summaryrefslogtreecommitdiff
path: root/commit-graph.h
diff options
context:
space:
mode:
authorAbhishek Kumar <abhishekkumar8222@gmail.com>2021-01-16 18:11:16 (GMT)
committerJunio C Hamano <gitster@pobox.com>2021-01-19 00:21:18 (GMT)
commit1fdc383c5c87b6f2bcacddd07d5d45dd04c2d146 (patch)
treed365e9825f36d3197cc6f07405b7e086d9be1f66 /commit-graph.h
parente8b63005c48696a26f976f5f9b0ccaf1983e439d (diff)
downloadgit-1fdc383c5c87b6f2bcacddd07d5d45dd04c2d146.zip
git-1fdc383c5c87b6f2bcacddd07d5d45dd04c2d146.tar.gz
git-1fdc383c5c87b6f2bcacddd07d5d45dd04c2d146.tar.bz2
commit-graph: use generation v2 only if entire chain does
Since there are released versions of Git that understand generation numbers in the commit-graph's CDAT chunk but do not understand the GDAT chunk, the following scenario is possible: 1. "New" Git writes a commit-graph with the GDAT chunk. 2. "Old" Git writes a split commit-graph on top without a GDAT chunk. If each layer of split commit-graph is treated independently, as it was the case before this commit, with Git inspecting only the current layer for chunk_generation_data pointer, commits in the lower layer (one with GDAT) whould have corrected commit date as their generation number, while commits in the upper layer would have topological levels as their generation. Corrected commit dates usually have much larger values than topological levels. This means that if we take two commits, one from the upper layer, and one reachable from it in the lower layer, then the expectation that the generation of a parent is smaller than the generation of a child would be violated. It is difficult to expose this issue in a test. Since we _start_ with artificially low generation numbers, any commit walk that prioritizes generation numbers will walk all of the commits with high generation number before walking the commits with low generation number. In all the cases I tried, the commit-graph layers themselves "protect" any incorrect behavior since none of the commits in the lower layer can reach the commits in the upper layer. This issue would manifest itself as a performance problem in this case, especially with something like "git log --graph" since the low generation numbers would cause the in-degree queue to walk all of the commits in the lower layer before allowing the topo-order queue to write anything to output (depending on the size of the upper layer). Therefore, When writing the new layer in split commit-graph, we write a GDAT chunk only if the topmost layer has a GDAT chunk. This guarantees that if a layer has GDAT chunk, all lower layers must have a GDAT chunk as well. Rewriting layers follows similar approach: if the topmost layer below the set of layers being rewritten (in the split commit-graph chain) exists, and it does not contain GDAT chunk, then the result of rewrite does not have GDAT chunks either. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Abhishek Kumar <abhishekkumar8222@gmail.com> Reviewed-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'commit-graph.h')
-rw-r--r--commit-graph.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/commit-graph.h b/commit-graph.h
index 19a0200..ad52130 100644
--- a/commit-graph.h
+++ b/commit-graph.h
@@ -64,6 +64,7 @@ struct commit_graph {
struct object_directory *odb;
uint32_t num_commits_in_base;
+ unsigned int read_generation_data;
struct commit_graph *base_graph;
const uint32_t *chunk_oid_fanout;