Skip to content

Commit 665d70a

Browse files
derrickstoleegitster
authored andcommitted
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 <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Reviewed-by: brian m. carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f3d66ec commit 665d70a

File tree

5 files changed

+62
-8
lines changed

5 files changed

+62
-8
lines changed

Documentation/technical/commit-graph-format.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@ HEADER:
4242
1-byte version number:
4343
Currently, the only valid version is 1.
4444

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.
4752

4853
1-byte number (C) of "chunks"
4954

commit-graph.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,14 @@ static char *get_chain_filename(struct object_directory *odb)
179179

180180
static uint8_t oid_version(void)
181181
{
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+
}
183190
}
184191

185192
static struct commit_graph *alloc_commit_graph(void)

t/t4216-log-bloom.sh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,17 @@ test_expect_success 'setup test - repo, commits, commit graph, log outputs' '
3030
rm file_to_be_deleted &&
3131
git add . &&
3232
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
3439
'
3540
graph_read_expect () {
3641
NUM_CHUNKS=5
3742
cat >expect <<- EOF
38-
header: 43475048 1 1 $NUM_CHUNKS 0
43+
header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
3944
num_commits: $1
4045
chunks: oid_fanout oid_lookup commit_metadata bloom_indexes bloom_data
4146
EOF

t/t5318-commit-graph.sh

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ test_expect_success 'setup full repo' '
1010
cd "$TRASH_DIRECTORY/full" &&
1111
git init &&
1212
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
1419
'
1520

1621
test_expect_success POSIXPERM 'tweak umask for modebit tests' '
@@ -77,7 +82,7 @@ graph_read_expect() {
7782
NUM_CHUNKS=$((3 + $(echo "$2" | wc -w)))
7883
fi
7984
cat >expect <<- EOF
80-
header: 43475048 1 1 $NUM_CHUNKS 0
85+
header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
8186
num_commits: $1
8287
chunks: oid_fanout oid_lookup commit_metadata$OPTIONAL
8388
EOF
@@ -412,6 +417,35 @@ test_expect_success 'replace-objects invalidates commit-graph' '
412417
)
413418
'
414419

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+
415449
# the verify tests below expect the commit-graph to contain
416450
# exactly the commits reachable from the commits/8 branch.
417451
# If the file changes the set of commits in the list, then the

t/t5324-split-commit-graph.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ test_expect_success 'setup repo' '
1818
1919
base sha1:1376
2020
base sha256:1496
21+
22+
oid_version sha1:1
23+
oid_version sha256:2
2124
EOM
2225
'
2326

@@ -28,7 +31,7 @@ graph_read_expect() {
2831
NUM_BASE=$2
2932
fi
3033
cat >expect <<- EOF
31-
header: 43475048 1 1 3 $NUM_BASE
34+
header: 43475048 1 $(test_oid oid_version) 3 $NUM_BASE
3235
num_commits: $1
3336
chunks: oid_fanout oid_lookup commit_metadata
3437
EOF

0 commit comments

Comments
 (0)