Skip to content

Commit 1221085

Browse files
committed
Merge branch 'bc/sha-256-part-2'
SHA-256 migration work continues. * bc/sha-256-part-2: (44 commits) remote-testgit: adapt for object-format bundle: detect hash algorithm when reading refs t5300: pass --object-format to git index-pack t5704: send object-format capability with SHA-256 t5703: use object-format serve option t5702: offer an object-format capability in the test t/helper: initialize the repository for test-sha1-array remote-curl: avoid truncating refs with ls-remote t1050: pass algorithm to index-pack when outside repo builtin/index-pack: add option to specify hash algorithm remote-curl: detect algorithm for dumb HTTP by size builtin/ls-remote: initialize repository based on fetch t5500: make hash independent serve: advertise object-format capability for protocol v2 connect: parse v2 refs with correct hash algorithm connect: pass full packet reader when parsing v2 refs Documentation/technical: document object-format for protocol v2 t1302: expect repo format version 1 for SHA-256 builtin/show-index: provide options to determine hash algo t5302: modernize test formatting ...
2 parents a08a83d + 3716d50 commit 1221085

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+694
-246
lines changed

Documentation/git-index-pack.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ OPTIONS
9393
--max-input-size=<size>::
9494
Die, if the pack is larger than <size>.
9595

96+
--object-format=<hash-algorithm>::
97+
Specify the given object format (hash algorithm) for the pack. The valid
98+
values are 'sha1' and (if enabled) 'sha256'. The default is the algorithm for
99+
the current repository (set by `extensions.objectFormat`), or 'sha1' if no
100+
value is set or outside a repository.
101+
+
102+
This option cannot be used with --stdin.
103+
96104
NOTES
97105
-----
98106

Documentation/git-show-index.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ git-show-index - Show packed archive index
99
SYNOPSIS
1010
--------
1111
[verse]
12-
'git show-index'
12+
'git show-index' [--object-format=<hash-algorithm>]
1313

1414

1515
DESCRIPTION
@@ -36,6 +36,15 @@ Note that you can get more information on a packfile by calling
3636
linkgit:git-verify-pack[1]. However, as this command considers only the
3737
index file itself, it's both faster and more flexible.
3838

39+
OPTIONS
40+
-------
41+
42+
--object-format=<hash-algorithm>::
43+
Specify the given object format (hash algorithm) for the index file. The
44+
valid values are 'sha1' and (if enabled) 'sha256'. The default is the
45+
algorithm for the current repository (set by `extensions.objectFormat`), or
46+
'sha1' if no value is set or outside a repository..
47+
3948
GIT
4049
---
4150
Part of the linkgit:git[1] suite

Documentation/gitremote-helpers.txt

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ the remote repository.
238238
`--signed-tags=verbatim` to linkgit:git-fast-export[1]. In the
239239
absence of this capability, Git will use `--signed-tags=warn-strip`.
240240

241+
'object-format'::
242+
This indicates that the helper is able to interact with the remote
243+
side using an explicit hash algorithm extension.
241244

242245

243246
COMMANDS
@@ -257,12 +260,14 @@ Support for this command is mandatory.
257260
'list'::
258261
Lists the refs, one per line, in the format "<value> <name>
259262
[<attr> ...]". The value may be a hex sha1 hash, "@<dest>" for
260-
a symref, or "?" to indicate that the helper could not get the
261-
value of the ref. A space-separated list of attributes follows
262-
the name; unrecognized attributes are ignored. The list ends
263-
with a blank line.
263+
a symref, ":<keyword> <value>" for a key-value pair, or
264+
"?" to indicate that the helper could not get the value of the
265+
ref. A space-separated list of attributes follows the name;
266+
unrecognized attributes are ignored. The list ends with a
267+
blank line.
264268
+
265269
See REF LIST ATTRIBUTES for a list of currently defined attributes.
270+
See REF LIST KEYWORDS for a list of currently defined keywords.
266271
+
267272
Supported if the helper has the "fetch" or "import" capability.
268273

@@ -432,6 +437,18 @@ attributes are defined.
432437
This ref is unchanged since the last import or fetch, although
433438
the helper cannot necessarily determine what value that produced.
434439

440+
REF LIST KEYWORDS
441+
-----------------
442+
443+
The 'list' command may produce a list of key-value pairs.
444+
The following keys are defined.
445+
446+
'object-format'::
447+
The refs are using the given hash algorithm. This keyword is only
448+
used if the server and client both support the object-format
449+
extension.
450+
451+
435452
OPTIONS
436453
-------
437454

@@ -516,6 +533,14 @@ set by Git if the remote helper has the 'option' capability.
516533
transaction. If successful, all refs will be updated, or none will. If the
517534
remote side does not support this capability, the push will fail.
518535

536+
'option object-format' {'true'|algorithm}::
537+
If 'true', indicate that the caller wants hash algorithm information
538+
to be passed back from the remote. This mode is used when fetching
539+
refs.
540+
+
541+
If set to an algorithm, indicate that the caller wants to interact with
542+
the remote side using that algorithm.
543+
519544
SEE ALSO
520545
--------
521546
linkgit:git-remote[1]

Documentation/technical/protocol-capabilities.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,21 @@ agent strings are purely informative for statistics and debugging
176176
purposes, and MUST NOT be used to programmatically assume the presence
177177
or absence of particular features.
178178

179+
object-format
180+
-------------
181+
182+
This capability, which takes a hash algorithm as an argument, indicates
183+
that the server supports the given hash algorithms. It may be sent
184+
multiple times; if so, the first one given is the one used in the ref
185+
advertisement.
186+
187+
When provided by the client, this indicates that it intends to use the
188+
given hash algorithm to communicate. The algorithm provided must be one
189+
that the server supports.
190+
191+
If this capability is not provided, it is assumed that the only
192+
supported algorithm is SHA-1.
193+
179194
symref
180195
------
181196

Documentation/technical/protocol-v2.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,3 +483,12 @@ included in a request. This is done by sending each option as a
483483
a request.
484484

485485
The provided options must not contain a NUL or LF character.
486+
487+
object-format
488+
~~~~~~~~~~~~~~~
489+
490+
The server can advertise the `object-format` capability with a value `X` (in the
491+
form `object-format=X`) to notify the client that the server is able to deal
492+
with objects using hash algorithm X. If not specified, the server is assumed to
493+
only handle SHA-1. If the client would like to use a hash algorithm other than
494+
SHA-1, it should specify its object-format string.

builtin/clone.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
12201220
refs = transport_get_remote_refs(transport, &ref_prefixes);
12211221

12221222
if (refs) {
1223+
int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
1224+
1225+
/*
1226+
* Now that we know what algorithm the remote side is using,
1227+
* let's set ours to the same thing.
1228+
*/
1229+
initialize_repository_version(hash_algo);
1230+
repo_set_hash_algo(the_repository, hash_algo);
1231+
12231232
mapped_refs = wanted_peer_refs(refs, &remote->fetch);
12241233
/*
12251234
* transport_get_remote_refs() may return refs with null sha-1

builtin/index-pack.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,13 +1555,9 @@ static void read_v2_anomalous_offsets(struct packed_git *p,
15551555
{
15561556
const uint32_t *idx1, *idx2;
15571557
uint32_t i;
1558-
const uint32_t hashwords = the_hash_algo->rawsz / sizeof(uint32_t);
15591558

15601559
/* The address of the 4-byte offset table */
1561-
idx1 = (((const uint32_t *)p->index_data)
1562-
+ 2 /* 8-byte header */
1563-
+ 256 /* fan out */
1564-
+ hashwords * p->num_objects /* object ID table */
1560+
idx1 = (((const uint32_t *)((const uint8_t *)p->index_data + p->crc_offset))
15651561
+ p->num_objects /* CRC32 table */
15661562
);
15671563

@@ -1671,6 +1667,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
16711667
unsigned char pack_hash[GIT_MAX_RAWSZ];
16721668
unsigned foreign_nr = 1; /* zero is a "good" value, assume bad */
16731669
int report_end_of_input = 0;
1670+
int hash_algo = 0;
16741671

16751672
/*
16761673
* index-pack never needs to fetch missing objects except when
@@ -1764,6 +1761,11 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
17641761
die(_("bad %s"), arg);
17651762
} else if (skip_prefix(arg, "--max-input-size=", &arg)) {
17661763
max_input_size = strtoumax(arg, NULL, 10);
1764+
} else if (skip_prefix(arg, "--object-format=", &arg)) {
1765+
hash_algo = hash_algo_by_name(arg);
1766+
if (hash_algo == GIT_HASH_UNKNOWN)
1767+
die(_("unknown hash algorithm '%s'"), arg);
1768+
repo_set_hash_algo(the_repository, hash_algo);
17671769
} else
17681770
usage(index_pack_usage);
17691771
continue;
@@ -1780,6 +1782,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
17801782
die(_("--fix-thin cannot be used without --stdin"));
17811783
if (from_stdin && !startup_info->have_repository)
17821784
die(_("--stdin requires a git repository"));
1785+
if (from_stdin && hash_algo)
1786+
die(_("--object-format cannot be used with --stdin"));
17831787
if (!index_name && pack_name)
17841788
index_name = derive_filename(pack_name, "idx", &index_name_buf);
17851789

builtin/ls-remote.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
118118
transport->server_options = &server_options;
119119

120120
ref = transport_get_remote_refs(transport, &ref_prefixes);
121+
if (ref) {
122+
int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
123+
repo_set_hash_algo(the_repository, hash_algo);
124+
}
121125
if (transport_disconnect(transport)) {
122126
UNLEAK(sorting);
123127
return 1;

builtin/receive-pack.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ static void show_ref(const char *path, const struct object_id *oid)
249249
strbuf_addf(&cap, " push-cert=%s", push_cert_nonce);
250250
if (advertise_push_options)
251251
strbuf_addstr(&cap, " push-options");
252+
strbuf_addf(&cap, " object-format=%s", the_hash_algo->name);
252253
strbuf_addf(&cap, " agent=%s", git_user_agent_sanitized());
253254
packet_write_fmt(1, "%s %s%c%s\n",
254255
oid_to_hex(oid), path, 0, cap.buf);
@@ -1624,6 +1625,8 @@ static struct command *read_head_info(struct packet_reader *reader,
16241625
linelen = strlen(reader->line);
16251626
if (linelen < reader->pktlen) {
16261627
const char *feature_list = reader->line + linelen + 1;
1628+
const char *hash = NULL;
1629+
int len = 0;
16271630
if (parse_feature_request(feature_list, "report-status"))
16281631
report_status = 1;
16291632
if (parse_feature_request(feature_list, "side-band-64k"))
@@ -1636,6 +1639,13 @@ static struct command *read_head_info(struct packet_reader *reader,
16361639
if (advertise_push_options
16371640
&& parse_feature_request(feature_list, "push-options"))
16381641
use_push_options = 1;
1642+
hash = parse_feature_value(feature_list, "object-format", &len, NULL);
1643+
if (!hash) {
1644+
hash = hash_algos[GIT_HASH_SHA1].name;
1645+
len = strlen(hash);
1646+
}
1647+
if (xstrncmpz(the_hash_algo->name, hash, len))
1648+
die("error: unsupported object format '%s'", hash);
16391649
}
16401650

16411651
if (!strcmp(reader->line, "push-cert")) {

builtin/show-index.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
#include "builtin.h"
22
#include "cache.h"
33
#include "pack.h"
4+
#include "parse-options.h"
45

5-
static const char show_index_usage[] =
6-
"git show-index";
6+
static const char *const show_index_usage[] = {
7+
"git show-index [--object-format=<hash-algorithm>]",
8+
NULL
9+
};
710

811
int cmd_show_index(int argc, const char **argv, const char *prefix)
912
{
1013
int i;
1114
unsigned nr;
1215
unsigned int version;
1316
static unsigned int top_index[256];
14-
const unsigned hashsz = the_hash_algo->rawsz;
17+
unsigned hashsz;
18+
const char *hash_name = NULL;
19+
int hash_algo;
20+
const struct option show_index_options[] = {
21+
OPT_STRING(0, "object-format", &hash_name, N_("hash-algorithm"),
22+
N_("specify the hash algorithm to use")),
23+
OPT_END()
24+
};
25+
26+
argc = parse_options(argc, argv, prefix, show_index_options, show_index_usage, 0);
27+
28+
if (hash_name) {
29+
hash_algo = hash_algo_by_name(hash_name);
30+
if (hash_algo == GIT_HASH_UNKNOWN)
31+
die(_("Unknown hash algorithm"));
32+
repo_set_hash_algo(the_repository, hash_algo);
33+
}
34+
35+
hashsz = the_hash_algo->rawsz;
1536

16-
if (argc != 1)
17-
usage(show_index_usage);
1837
if (fread(top_index, 2 * 4, 1, stdin) != 1)
1938
die("unable to read header");
2039
if (top_index[0] == htonl(PACK_IDX_SIGNATURE)) {

0 commit comments

Comments
 (0)