@matheusbsbs / matheus-bagliano / commits / 665d70ad03
Fork 0

commit-graph: use the "hash version" byte

The commit-graph format reserved a byte among the header of the file to store a "hash version". During the SHA-256 work, this was not modified because file formats are not necessarily intended to work across hash versions. If a repository has SHA-256 as its hash algorithm, it automatically up-shifts the lengths of object names in all necessary formats. However, since we have this byte available for adjusting the version, we can make the file formats more obviously incompatible instead of relying on other context from the repository. Update the oid_version() method in commit-graph.c to add a new value, 2, for sha-256. This automatically writes the new value in a SHA-256 repository _and_ verifies the value is correct. This is a breaking change relative to the current 'master' branch since 092b677 (Merge branch 'bc/sha-256-cvs-svn-updates', 2020-08-13) but it is not breaking relative to any released version of Git. The test impact is relatively minor: the output of 'test-tool read-graph' lists the header information, so those instances of '1' need to be replaced with a variable determined by GIT_TEST_DEFAULT_HASH. A more careful test is added that specifically creates a repository of each type then swaps the commit-graph files. The important value here is that the "git log" command succeeds while writing a message to stderr. Helped-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Aug 17, 2020 at 14:04 UTC 665d70ad033b115d8c14cdc2bcecf6c8b1947260
5 files changed +62 -8
Documentation/technical/commit-graph-format.txt
+7 -2
@@ -42,8 +42,13 @@ HEADER:
42 1-byte version number:
43 Currently, the only valid version is 1.
44
45 - 1-byte Hash Version (1 = SHA-1)
46 - We infer the hash length (H) from this value.
45 + 1-byte Hash Version
46 + We infer the hash length (H) from this value:
47 + 1 => SHA-1
48 + 2 => SHA-256
49 + If the hash type does not match the repository's hash algorithm, the
50 + commit-graph file should be ignored with a warning presented to the
51 + user.
52
53 1-byte number (C) of "chunks"
54
commit-graph.c
+8 -1
@@ -179,7 +179,14 @@ static char *get_chain_filename(struct object_directory *odb)
179
180 static uint8_t oid_version(void)
181 {
182 - return 1;
182 + switch (hash_algo_by_ptr(the_hash_algo)) {
183 + case GIT_HASH_SHA1:
184 + return 1;
185 + case GIT_HASH_SHA256:
186 + return 2;
187 + default:
188 + die(_("invalid hash version"));
189 + }
190 }
191
192 static struct commit_graph *alloc_commit_graph(void)
t/t4216-log-bloom.sh
+7 -2
@@ -30,12 +30,17 @@ test_expect_success 'setup test - repo, commits, commit graph, log outputs' '
30 rm file_to_be_deleted &&
31 git add . &&
32 git commit -m "file removed" &&
33 - git commit-graph write --reachable --changed-paths
33 + git commit-graph write --reachable --changed-paths &&
34 +
35 + test_oid_cache <<-EOF
36 + oid_version sha1:1
37 + oid_version sha256:2
38 + EOF
39 '
40 graph_read_expect () {
41 NUM_CHUNKS=5
42 cat >expect <<- EOF
38 - header: 43475048 1 1 $NUM_CHUNKS 0
43 + header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
44 num_commits: $1
45 chunks: oid_fanout oid_lookup commit_metadata bloom_indexes bloom_data
46 EOF
t/t5318-commit-graph.sh
+36 -2
@@ -10,7 +10,12 @@ test_expect_success 'setup full repo' '
10 cd "$TRASH_DIRECTORY/full" &&
11 git init &&
12 git config core.commitGraph true &&
13 - objdir=".git/objects"
13 + objdir=".git/objects" &&
14 +
15 + test_oid_cache <<-EOF
16 + oid_version sha1:1
17 + oid_version sha256:2
18 + EOF
19 '
20
21 test_expect_success POSIXPERM 'tweak umask for modebit tests' '
@@ -77,7 +82,7 @@ graph_read_expect() {
82 NUM_CHUNKS=$((3 + $(echo "$2" | wc -w)))
83 fi
84 cat >expect <<- EOF
80 - header: 43475048 1 1 $NUM_CHUNKS 0
85 + header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
86 num_commits: $1
87 chunks: oid_fanout oid_lookup commit_metadata$OPTIONAL
88 EOF
@@ -412,6 +417,35 @@ test_expect_success 'replace-objects invalidates commit-graph' '
417 )
418 '
419
420 +test_expect_success 'warn on improper hash version' '
421 + git init --object-format=sha1 sha1 &&
422 + (
423 + cd sha1 &&
424 + test_commit 1 &&
425 + git commit-graph write --reachable &&
426 + mv .git/objects/info/commit-graph ../cg-sha1
427 + ) &&
428 + git init --object-format=sha256 sha256 &&
429 + (
430 + cd sha256 &&
431 + test_commit 1 &&
432 + git commit-graph write --reachable &&
433 + mv .git/objects/info/commit-graph ../cg-sha256
434 + ) &&
435 + (
436 + cd sha1 &&
437 + mv ../cg-sha256 .git/objects/info/commit-graph &&
438 + git log -1 2>err &&
439 + test_i18ngrep "commit-graph hash version 2 does not match version 1" err
440 + ) &&
441 + (
442 + cd sha256 &&
443 + mv ../cg-sha1 .git/objects/info/commit-graph &&
444 + git log -1 2>err &&
445 + test_i18ngrep "commit-graph hash version 1 does not match version 2" err
446 + )
447 +'
448 +
449 # the verify tests below expect the commit-graph to contain
450 # exactly the commits reachable from the commits/8 branch.
451 # If the file changes the set of commits in the list, then the
t/t5324-split-commit-graph.sh
+4 -1
@@ -18,6 +18,9 @@ test_expect_success 'setup repo' '
18
19 base sha1:1376
20 base sha256:1496
21 +
22 + oid_version sha1:1
23 + oid_version sha256:2
24 EOM
25 '
26
@@ -28,7 +31,7 @@ graph_read_expect() {
31 NUM_BASE=$2
32 fi
33 cat >expect <<- EOF
31 - header: 43475048 1 1 3 $NUM_BASE
34 + header: 43475048 1 $(test_oid oid_version) 3 $NUM_BASE
35 num_commits: $1
36 chunks: oid_fanout oid_lookup commit_metadata
37 EOF