Skip to content

Commit 6161ce7

Browse files
bk2204gitster
authored andcommitted
bundle: detect hash algorithm when reading refs
Much like with the dumb HTTP transport, there isn't a way to explicitly specify the hash algorithm when dealing with a bundle, so detect the algorithm based on the length of the object IDs in the prerequisites and ref advertisements. Signed-off-by: brian m. carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 371c407 commit 6161ce7

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

bundle.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ static void add_to_ref_list(const struct object_id *oid, const char *name,
2323
list->nr++;
2424
}
2525

26+
static const struct git_hash_algo *detect_hash_algo(struct strbuf *buf)
27+
{
28+
size_t len = strcspn(buf->buf, " \n");
29+
int algo;
30+
31+
algo = hash_algo_by_length(len / 2);
32+
if (algo == GIT_HASH_UNKNOWN)
33+
return NULL;
34+
return &hash_algos[algo];
35+
}
36+
2637
static int parse_bundle_header(int fd, struct bundle_header *header,
2738
const char *report_path)
2839
{
@@ -52,12 +63,21 @@ static int parse_bundle_header(int fd, struct bundle_header *header,
5263
}
5364
strbuf_rtrim(&buf);
5465

66+
if (!header->hash_algo) {
67+
header->hash_algo = detect_hash_algo(&buf);
68+
if (!header->hash_algo) {
69+
error(_("unknown hash algorithm length"));
70+
status = -1;
71+
break;
72+
}
73+
}
74+
5575
/*
5676
* Tip lines have object name, SP, and refname.
5777
* Prerequisites have object name that is optionally
5878
* followed by SP and subject line.
5979
*/
60-
if (parse_oid_hex(buf.buf, &oid, &p) ||
80+
if (parse_oid_hex_algop(buf.buf, &oid, &p, header->hash_algo) ||
6181
(*p && !isspace(*p)) ||
6282
(!is_prereq && !*p)) {
6383
if (report_path)

bundle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct ref_list {
1515
struct bundle_header {
1616
struct ref_list prerequisites;
1717
struct ref_list references;
18+
const struct git_hash_algo *hash_algo;
1819
};
1920

2021
int is_bundle(const char *path, int quiet);

transport.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ static struct ref *get_refs_from_bundle(struct transport *transport,
143143
data->fd = read_bundle_header(transport->url, &data->header);
144144
if (data->fd < 0)
145145
die(_("could not read bundle '%s'"), transport->url);
146+
147+
transport->hash_algo = data->header.hash_algo;
148+
146149
for (i = 0; i < data->header.references.nr; i++) {
147150
struct ref_list_entry *e = data->header.references.list + i;
148151
struct ref *ref = alloc_ref(e->name);
@@ -157,11 +160,14 @@ static int fetch_refs_from_bundle(struct transport *transport,
157160
int nr_heads, struct ref **to_fetch)
158161
{
159162
struct bundle_transport_data *data = transport->data;
163+
int ret;
160164

161165
if (!data->get_refs_from_bundle_called)
162166
get_refs_from_bundle(transport, 0, NULL);
163-
return unbundle(the_repository, &data->header, data->fd,
164-
transport->progress ? BUNDLE_VERBOSE : 0);
167+
ret = unbundle(the_repository, &data->header, data->fd,
168+
transport->progress ? BUNDLE_VERBOSE : 0);
169+
transport->hash_algo = data->header.hash_algo;
170+
return ret;
165171
}
166172

167173
static int close_bundle(struct transport *transport)

0 commit comments

Comments
 (0)