git: properly load empty repositories (#851)

Summary:
Fixes #850.

Test Plan:
Regression test added; it fails before the change and passes after it.
Also, running `node ./bin/sourcecred.js load wchargin/mt` (which is a
GitHub repository with no commits) now successfully loads the
repository. (The cred explorer fails to process it, because it tries to
normalize across GitHub users, of which there are none, but this is a
known limitation and is unrelated.)

wchargin-branch: fix-empty-git-repository
This commit is contained in:
William Chargin 2018-09-17 16:36:22 -07:00 committed by GitHub
parent 7259233f82
commit fa81c4eaa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 0 deletions

View File

@ -25,6 +25,16 @@ export function loadRepository(
mode: "FULL" | "COMMITS_ONLY" = "FULL"
): Repository {
const git = localGit(repositoryPath);
try {
// If the repository is empty, HEAD will not exist. We check HEAD
// rather than the provided `rootRef` because, in the case where the
// repository is non-empty but the provided `rootRef` does not
// exist, we still want to fail.
git(["rev-parse", "--verify", "HEAD"]);
} catch (e) {
// No data in the repository.
return {commits: {}, trees: {}};
}
const commits = findCommits(git, rootRef);
const trees = (() => {
switch (mode) {

View File

@ -3,6 +3,7 @@
import tmp from "tmp";
import {createExampleRepo} from "./example/exampleRepo";
import {localGit} from "./gitUtils";
import {loadRepository} from "./loadRepository";
const cleanups: (() => void)[] = [];
@ -58,4 +59,22 @@ describe("plugins/git/loadRepository", () => {
trees: new Set(Object.keys(part.trees)),
}).toMatchSnapshot();
});
it("fails when given a non-existent root ref", () => {
const repository = createExampleRepo(mkdtemp());
const invalidHash = "0".repeat(40);
expect(() => {
loadRepository(repository.path, invalidHash);
}).toThrow("fatal: bad object 0000000000000000000000000000000000000000");
});
it("handles an empty repository properly", () => {
const repositoryPath = mkdtemp();
const git = localGit(repositoryPath);
git(["init"]);
expect(loadRepository(repositoryPath, "HEAD")).toEqual({
commits: {},
trees: {},
});
});
});