DfsGarbageCollector: put only GC commits into the commit graph

GC puts all commits reachable from heads and tags into the GC pack,
and commits reachable only from other refs (e.g. refs/changes) into
GC_REST. The commit-graph contains all commits in GC and GC_REST. This
produces too big commit graphs in some repos, beating the purpose of
loading the index.

Limit the commit graph to commits reachable from heads and tags
(i.e. commits in the GC pack).

Change-Id: I4962faea5a726d2ea3e548af0aeae370a6cc8588
This commit is contained in:
Ivan Frade 2023-08-16 13:26:39 -07:00
parent b4b8f05eea
commit 6f73336939
2 changed files with 13 additions and 14 deletions

View File

@ -979,7 +979,7 @@ public void reftableWithTombstoneNotResurrected() throws Exception {
}
@Test
public void produceCommitGraphAllRefsIncludedFromDisk() throws Exception {
public void produceCommitGraphOnlyHeadsAndTags() throws Exception {
String tag = "refs/tags/tag1";
String head = "refs/heads/head1";
String nonHead = "refs/something/nonHead";
@ -1001,19 +1001,20 @@ public void produceCommitGraphAllRefsIncludedFromDisk() throws Exception {
CommitGraph cg = gcPack.getCommitGraph(reader);
assertNotNull(cg);
assertTrue("all commits in commit graph", cg.getCommitCnt() == 3);
assertTrue("Only heads and tags reachable commits in commit graph",
cg.getCommitCnt() == 2);
// GC packed
assertTrue("tag referenced commit is in graph",
cg.findGraphPosition(rootCommitTagged) != -1);
assertTrue("head referenced commit is in graph",
cg.findGraphPosition(headTip) != -1);
// GC_REST packed
assertTrue("nonHead referenced commit is in graph",
cg.findGraphPosition(nonHeadTip) != -1);
// GC_REST not in commit graph
assertEquals("nonHead referenced commit is NOT in graph",
-1, cg.findGraphPosition(nonHeadTip));
}
@Test
public void produceCommitGraphAllRefsIncludedFromCache() throws Exception {
public void produceCommitGraphOnlyHeadsAndTagsIncludedFromCache() throws Exception {
String tag = "refs/tags/tag1";
String head = "refs/heads/head1";
String nonHead = "refs/something/nonHead";
@ -1043,15 +1044,16 @@ public void produceCommitGraphAllRefsIncludedFromCache() throws Exception {
assertTrue("commit graph read time is recorded",
reader.stats.readCommitGraphMicros > 0);
assertTrue("all commits in commit graph", cachedCG.getCommitCnt() == 3);
assertTrue("Only heads and tags reachable commits in commit graph",
cachedCG.getCommitCnt() == 2);
// GC packed
assertTrue("tag referenced commit is in graph",
cachedCG.findGraphPosition(rootCommitTagged) != -1);
assertTrue("head referenced commit is in graph",
cachedCG.findGraphPosition(headTip) != -1);
// GC_REST packed
assertTrue("nonHead referenced commit is in graph",
cachedCG.findGraphPosition(nonHeadTip) != -1);
// GC_REST not in commit graph
assertEquals("nonHead referenced commit is not in graph",
-1, cachedCG.findGraphPosition(nonHeadTip));
}
@Test

View File

@ -783,12 +783,9 @@ private void writeCommitGraph(DfsPackDescription pack, ProgressMonitor pm)
return;
}
Set<ObjectId> allTips = refsBefore.stream().map(Ref::getObjectId)
.collect(Collectors.toUnmodifiableSet());
try (DfsOutputStream out = objdb.writeFile(pack, COMMIT_GRAPH);
RevWalk pool = new RevWalk(ctx)) {
GraphCommits gcs = GraphCommits.fromWalk(pm, allTips, pool);
GraphCommits gcs = GraphCommits.fromWalk(pm, allHeadsAndTags, pool);
CountingOutputStream cnt = new CountingOutputStream(out);
CommitGraphWriter writer = new CommitGraphWriter(gcs,
writeBloomFilter);