commit-graph: merge commit-graph chains
commit1771be90c8e4797c2466296d1d570dbfa39d9743
authorDerrick Stolee <dstolee@microsoft.com>
Tue, 18 Jun 2019 18:14:29 +0000 (18 11:14 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 20 Jun 2019 03:46:26 +0000 (19 20:46 -0700)
tree38e4ee534e905bd5a31cf7607eedbe48c5c6255c
parent135a7123755bfdde05da18012bebd2776f82b26c
commit-graph: merge commit-graph chains

When searching for a commit in a commit-graph chain of G graphs with N
commits, the search takes O(G log N) time. If we always add a new tip
graph with every write, the linear G term will start to dominate and
slow the lookup process.

To keep lookups fast, but also keep most incremental writes fast, create
a strategy for merging levels of the commit-graph chain. The strategy is
detailed in the commit-graph design document, but is summarized by these
two conditions:

  1. If the number of commits we are adding is more than half the number
     of commits in the graph below, then merge with that graph.

  2. If we are writing more than 64,000 commits into a single graph,
     then merge with all lower graphs.

The numeric values in the conditions above are currently constant, but
can become config options in a future update.

As we merge levels of the commit-graph chain, check that the commits
still exist in the repository. A garbage-collection operation may have
removed those commits from the object store and we do not want to
persist them in the commit-graph chain. This is a non-issue if the
'git gc' process wrote a new, single-level commit-graph file.

After we merge levels, the old graph-{hash}.graph files are no longer
referenced by the commit-graph-chain file. We will expire these files in
a future change.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/technical/commit-graph.txt
commit-graph.c
t/t5324-split-commit-graph.sh