diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2022-07-05 09:06:24 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2022-07-08 15:46:53 +0300 |
commit | a8f996a321e73597a0c726576bc9b8c1d03d9a07 (patch) | |
tree | f27cac11882a26f836005b7f7f2b8ab3b9716672 | |
parent | e48e575179544159732c490280f4f40b8dbf43a5 (diff) |
git: Fix commit-graph corruption caused by corrected committer dates
In staging systems we have observed corruption in commit-graphs with the
following error message:
fatal: commit-graph requires overflow generation data but has none
This bug is caused by the rollout of Git v2.36.0, which has fixed a set
of bugs with reading corrected committer dates in commit-graphs [1].
Unfortunately, these fixes surface a corruption in commit-graphs that
can happen when upgrading a commit-graph written by Git v2.35.0 with a
Git version of v2.36.0 or later with `--changed-paths` enabled [2].
Disable use of corrected committer dates for now. Due to the bug that
existed in Git v2.35.0 and earlier we haven't ever read them anyway, so
this is not a performance regression for us. Instead, we'll continue to
use topological generation numbers to still speed up certain queries.
We should reenable them when the bug has been fixed upstream.
[1]: http://public-inbox.org/git/pull.1163.git.1645735117.gitgitgadget@gmail.com/
[2]: https://public-inbox.org/git/DD88D523-0ECA-4474-9AA5-1D4A431E532A@wfchandler.org/
Changelog: fixed
-rw-r--r-- | internal/git/command_factory.go | 28 | ||||
-rw-r--r-- | internal/git/command_factory_test.go | 2 |
2 files changed, 30 insertions, 0 deletions
diff --git a/internal/git/command_factory.go b/internal/git/command_factory.go index 86918985f..8a2d83e45 100644 --- a/internal/git/command_factory.go +++ b/internal/git/command_factory.go @@ -514,6 +514,34 @@ func (cf *ExecCommandFactory) globalConfiguration(ctx context.Context) ([]Global // mechanism to replace malicious commits with seemingly benign ones. We thus globally // disable this mechanism. ConfigPair{Key: "core.useReplaceRefs", Value: "false"}, + + // Commit-graphs are used as an optimization to speed up reading commits and to be + // able to perform certain commit-related queries faster. One property that these + // graphs are storing is the generation number of a commit, where there are two + // different types of generation numbers: + // + // - Topological level: a commit with no parents has a level of 1. A commit with + // at least one parent has a level one more than the largest topological level + // of its parents. + // + // - Corrected committer date: a commit with no parents has a corrected commit + // date equal to its committer date. A commit with at least one parent has a + // corrected committer date equal to the maximum between either its own + // committer date or the largest corrected committer date across its parents + // plus 1. + // + // By default, newer Git versions store both generation numbers for commits, where + // the corrected committer date allows for some more optimizations. But due to a bug + // in Git v2.35.0 and earlier, the corrected committer date wasn't ever read. + // + // This bug was fixed in Git v2.36.0, together with a few other bugs in this area. + // But unfortunately, a new bug was introduced: when upgrading a commit-graph + // written by Git v2.35.0 or newer with Git v2.36.0 and later with `--changed-paths` + // enabled then the resulting commit-graph may be corrupt. + // + // Let's disable reading and writing corrected committer dates for now until the fix + // to this issue is upstream. + ConfigPair{Key: "commitGraph.generationVersion", Value: "1"}, } // Git v2.36.0 introduced new fine-grained configuration for what data should be fsynced and diff --git a/internal/git/command_factory_test.go b/internal/git/command_factory_test.go index d709dd130..91672db47 100644 --- a/internal/git/command_factory_test.go +++ b/internal/git/command_factory_test.go @@ -483,6 +483,7 @@ func TestExecCommandFactory_config(t *testing.T) { "gc.auto=0", "core.autocrlf=input", "core.usereplacerefs=false", + "commitgraph.generationversion=1", } for _, tc := range []struct { @@ -543,6 +544,7 @@ func TestExecCommandFactory_SidecarGitConfiguration(t *testing.T) { {Key: "gc.auto", Value: "0"}, {Key: "core.autocrlf", Value: "input"}, {Key: "core.useReplaceRefs", Value: "false"}, + {Key: "commitGraph.generationVersion", Value: "1"}, } commonTail := []git.ConfigPair{ |