Skip to content

Commit 6f8a213

Browse files
committed
Merge branch 'ds/sha256-leftover-bits'
midx and commit-graph files now use the byte defined in their file format specification for identifying the hash function used for object names. * ds/sha256-leftover-bits: multi-pack-index: use hash version byte commit-graph: use the "hash version" byte t/README: document GIT_TEST_DEFAULT_HASH
2 parents 74a395c + d960754 commit 6f8a213

File tree

10 files changed

+146
-21
lines changed

10 files changed

+146
-21
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

Documentation/technical/pack-format.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,12 @@ HEADER:
279279
Git only writes or recognizes version 1.
280280

281281
1-byte Object Id Version
282-
Git only writes or recognizes version 1 (SHA1).
282+
We infer the length of object IDs (OIDs) from this value:
283+
1 => SHA-1
284+
2 => SHA-256
285+
If the hash type does not match the repository's hash algorithm,
286+
the multi-pack-index file should be ignored with a warning
287+
presented to the user.
283288

284289
1-byte number of "chunks"
285290

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)

midx.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#define MIDX_BYTE_HASH_VERSION 5
1818
#define MIDX_BYTE_NUM_CHUNKS 6
1919
#define MIDX_BYTE_NUM_PACKS 8
20-
#define MIDX_HASH_VERSION 1
2120
#define MIDX_HEADER_SIZE 12
2221
#define MIDX_MIN_SIZE (MIDX_HEADER_SIZE + the_hash_algo->rawsz)
2322

@@ -36,6 +35,18 @@
3635

3736
#define PACK_EXPIRED UINT_MAX
3837

38+
static uint8_t oid_version(void)
39+
{
40+
switch (hash_algo_by_ptr(the_hash_algo)) {
41+
case GIT_HASH_SHA1:
42+
return 1;
43+
case GIT_HASH_SHA256:
44+
return 2;
45+
default:
46+
die(_("invalid hash version"));
47+
}
48+
}
49+
3950
static char *get_midx_filename(const char *object_dir)
4051
{
4152
return xstrfmt("%s/pack/multi-pack-index", object_dir);
@@ -90,8 +101,11 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
90101
m->version);
91102

92103
hash_version = m->data[MIDX_BYTE_HASH_VERSION];
93-
if (hash_version != MIDX_HASH_VERSION)
94-
die(_("hash version %u does not match"), hash_version);
104+
if (hash_version != oid_version()) {
105+
error(_("multi-pack-index hash version %u does not match version %u"),
106+
hash_version, oid_version());
107+
goto cleanup_fail;
108+
}
95109
m->hash_len = the_hash_algo->rawsz;
96110

97111
m->num_chunks = m->data[MIDX_BYTE_NUM_CHUNKS];
@@ -418,7 +432,7 @@ static size_t write_midx_header(struct hashfile *f,
418432

419433
hashwrite_be32(f, MIDX_SIGNATURE);
420434
byte_values[0] = MIDX_VERSION;
421-
byte_values[1] = MIDX_HASH_VERSION;
435+
byte_values[1] = oid_version();
422436
byte_values[2] = num_chunks;
423437
byte_values[3] = 0; /* unused */
424438
hashwrite(f, byte_values, sizeof(byte_values));
@@ -1105,8 +1119,17 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
11051119
struct multi_pack_index *m = load_multi_pack_index(object_dir, 1);
11061120
verify_midx_error = 0;
11071121

1108-
if (!m)
1109-
return 0;
1122+
if (!m) {
1123+
int result = 0;
1124+
struct stat sb;
1125+
char *filename = get_midx_filename(object_dir);
1126+
if (!stat(filename, &sb)) {
1127+
error(_("multi-pack-index file exists, but failed to parse"));
1128+
result = 1;
1129+
}
1130+
free(filename);
1131+
return result;
1132+
}
11101133

11111134
if (flags & MIDX_PROGRESS)
11121135
progress = start_progress(_("Looking for referenced packfiles"),

t/README

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,10 @@ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is
421421
the default when running tests), errors out when an abbreviated option
422422
is used.
423423

424+
GIT_TEST_DEFAULT_HASH=<hash-algo> specifies which hash algorithm to
425+
use in the test scripts. Recognized values for <hash-algo> are "sha1"
426+
and "sha256".
427+
424428
Naming Tests
425429
------------
426430

t/helper/test-read-midx.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@
77
static int read_midx_file(const char *object_dir)
88
{
99
uint32_t i;
10-
struct multi_pack_index *m = load_multi_pack_index(object_dir, 1);
10+
struct multi_pack_index *m;
11+
12+
setup_git_directory();
13+
m = load_multi_pack_index(object_dir, 1);
1114

1215
if (!m)
1316
return 1;
1417

15-
printf("header: %08x %d %d %d\n",
18+
printf("header: %08x %d %d %d %d\n",
1619
m->signature,
1720
m->version,
21+
m->hash_len,
1822
m->num_chunks,
1923
m->num_packs);
2024

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/t5319-multi-pack-index.sh

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ test_description='multi-pack-indexes'
55

66
objdir=.git/objects
77

8+
HASH_LEN=$(test_oid rawsz)
9+
810
midx_read_expect () {
911
NUM_PACKS=$1
1012
NUM_OBJECTS=$2
@@ -13,7 +15,7 @@ midx_read_expect () {
1315
EXTRA_CHUNKS="$5"
1416
{
1517
cat <<-EOF &&
16-
header: 4d494458 1 $NUM_CHUNKS $NUM_PACKS
18+
header: 4d494458 1 $HASH_LEN $NUM_CHUNKS $NUM_PACKS
1719
chunks: pack-names oid-fanout oid-lookup object-offsets$EXTRA_CHUNKS
1820
num_objects: $NUM_OBJECTS
1921
packs:
@@ -46,7 +48,7 @@ test_expect_success "don't write midx with no packs" '
4648
test_path_is_missing pack/multi-pack-index
4749
'
4850

49-
test_expect_success "Warn if a midx contains no oid" '
51+
test_expect_success SHA1 'warn if a midx contains no oid' '
5052
cp "$TEST_DIRECTORY"/t5319/no-objects.midx $objdir/pack/multi-pack-index &&
5153
test_must_fail git multi-pack-index verify &&
5254
rm $objdir/pack/multi-pack-index
@@ -198,6 +200,40 @@ test_expect_success 'write midx with twelve packs' '
198200

199201
compare_results_with_midx "twelve packs"
200202

203+
test_expect_success 'warn on improper hash version' '
204+
git init --object-format=sha1 sha1 &&
205+
(
206+
cd sha1 &&
207+
git config core.multiPackIndex true &&
208+
test_commit 1 &&
209+
git repack -a &&
210+
git multi-pack-index write &&
211+
mv .git/objects/pack/multi-pack-index ../mpi-sha1
212+
) &&
213+
git init --object-format=sha256 sha256 &&
214+
(
215+
cd sha256 &&
216+
git config core.multiPackIndex true &&
217+
test_commit 1 &&
218+
git repack -a &&
219+
git multi-pack-index write &&
220+
mv .git/objects/pack/multi-pack-index ../mpi-sha256
221+
) &&
222+
(
223+
cd sha1 &&
224+
mv ../mpi-sha256 .git/objects/pack/multi-pack-index &&
225+
git log -1 2>err &&
226+
test_i18ngrep "multi-pack-index hash version 2 does not match version 1" err
227+
) &&
228+
(
229+
cd sha256 &&
230+
mv ../mpi-sha1 .git/objects/pack/multi-pack-index &&
231+
git log -1 2>err &&
232+
test_i18ngrep "multi-pack-index hash version 1 does not match version 2" err
233+
)
234+
'
235+
236+
201237
test_expect_success 'verify multi-pack-index success' '
202238
git multi-pack-index verify --object-dir=$objdir
203239
'
@@ -243,7 +279,6 @@ test_expect_success 'verify bad signature' '
243279
"multi-pack-index signature"
244280
'
245281

246-
HASH_LEN=$(test_oid rawsz)
247282
NUM_OBJECTS=74
248283
MIDX_BYTE_VERSION=4
249284
MIDX_BYTE_OID_VERSION=5
@@ -272,7 +307,7 @@ test_expect_success 'verify bad version' '
272307
'
273308

274309
test_expect_success 'verify bad OID version' '
275-
corrupt_midx_and_verify $MIDX_BYTE_OID_VERSION "\02" $objdir \
310+
corrupt_midx_and_verify $MIDX_BYTE_OID_VERSION "\03" $objdir \
276311
"hash version"
277312
'
278313

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)