summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar brian m. carlson <sandals@crustytoothpaste.net>2020-05-25 19:59:00 +0000
committerLibravatar Junio C Hamano <gitster@pobox.com>2020-05-27 10:07:06 -0700
commit7c601dc333b6cd86a84e77f41c968a3bb773ba36 (patch)
treeef321ba10247a91b05be0cfccbe2e87a8d845822
parentfetch-pack: detect when the server doesn't support our hash (diff)
downloadtgif-7c601dc333b6cd86a84e77f41c968a3bb773ba36.tar.xz
connect: detect algorithm when fetching refs
If we're fetching refs, detect the hash algorithm and parse the refs using that algorithm. As mentioned in the documentation, if multiple versions of the object-format capability are provided, we use the first. No known implementation supports multiple algorithms now, but they may in the future. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--connect.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/connect.c b/connect.c
index 397fad7e32..915f1736a0 100644
--- a/connect.c
+++ b/connect.c
@@ -220,12 +220,25 @@ static void annotate_refs_with_symref_info(struct ref *ref)
static void process_capabilities(struct packet_reader *reader, int *linelen)
{
+ const char *feat_val;
+ int feat_len;
const char *line = reader->line;
int nul_location = strlen(line);
if (nul_location == *linelen)
return;
server_capabilities_v1 = xstrdup(line + nul_location + 1);
*linelen = nul_location;
+
+ feat_val = server_feature_value("object-format", &feat_len);
+ if (feat_val) {
+ char *hash_name = xstrndup(feat_val, feat_len);
+ int hash_algo = hash_algo_by_name(hash_name);
+ if (hash_algo != GIT_HASH_UNKNOWN)
+ reader->hash_algo = &hash_algos[hash_algo];
+ free(hash_name);
+ } else {
+ reader->hash_algo = &hash_algos[GIT_HASH_SHA1];
+ }
}
static int process_dummy_ref(const struct packet_reader *reader)
@@ -234,7 +247,7 @@ static int process_dummy_ref(const struct packet_reader *reader)
struct object_id oid;
const char *name;
- if (parse_oid_hex(line, &oid, &name))
+ if (parse_oid_hex_algop(line, &oid, &name, reader->hash_algo))
return 0;
if (*name != ' ')
return 0;
@@ -258,7 +271,7 @@ static int process_ref(const struct packet_reader *reader, int len,
struct object_id old_oid;
const char *name;
- if (parse_oid_hex(line, &old_oid, &name))
+ if (parse_oid_hex_algop(line, &old_oid, &name, reader->hash_algo))
return 0;
if (*name != ' ')
return 0;
@@ -270,7 +283,7 @@ static int process_ref(const struct packet_reader *reader, int len,
die(_("protocol error: unexpected capabilities^{}"));
} else if (check_ref(name, flags)) {
struct ref *ref = alloc_ref(name);
- oidcpy(&ref->old_oid, &old_oid);
+ memcpy(ref->old_oid.hash, old_oid.hash, reader->hash_algo->rawsz);
**list = ref;
*list = &ref->next;
}
@@ -288,7 +301,7 @@ static int process_shallow(const struct packet_reader *reader, int len,
if (!skip_prefix(line, "shallow ", &arg))
return 0;
- if (get_oid_hex(arg, &old_oid))
+ if (get_oid_hex_algop(arg, &old_oid, reader->hash_algo))
die(_("protocol error: expected shallow sha-1, got '%s'"), arg);
if (!shallow_points)
die(_("repository on the other end cannot be shallow"));