From: Patrick Steinhardt Date: Thu, 16 Jul 2026 12:38:03 +0000 (+0200) Subject: refspec: let callers pass in hash algorithm when parsing items X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=bb71c3f19e6a693fc1d32e4448be8520132d946e;p=thirdparty%2Fgit.git refspec: let callers pass in hash algorithm when parsing items When parsing a refspec item we need to know about the hash algorithm used by the repository so that we can decide whether or not a given string is an exact object ID. We use `the_hash_algo` for this, which makes the code implicitly depend on `the_repository`. Refactor `refspec_item_init_fetch()`, `refspec_item_init_push()` and `valid_fetch_refspec()` so that callers have to pass in the hash algorithm explicitly and adapt callers accordingly. For now, all of the callers simply pass `the_hash_algo`, so there is no change in behaviour. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- diff --git a/builtin/fetch.c b/builtin/fetch.c index 8e676b79ba..1d4a129039 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -601,7 +601,8 @@ static struct ref *get_ref_map(struct remote *remote, struct refspec_item tag_refspec; /* also fetch all tags */ - refspec_item_init_push(&tag_refspec, TAG_REFSPEC); + refspec_item_init_push(&tag_refspec, TAG_REFSPEC, + the_hash_algo); get_fetch_map(remote_refs, &tag_refspec, &tail, 0); refspec_item_clear(&tag_refspec); } else if (tags == TAGS_DEFAULT && *autotags) { diff --git a/builtin/pull.c b/builtin/pull.c index d49b09114a..db3ee0aab3 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -612,7 +612,7 @@ static const char *get_tracking_branch(const char *remote, const char *refspec) const char *spec_src; const char *merge_branch; - if (!refspec_item_init_fetch(&spec, refspec)) + if (!refspec_item_init_fetch(&spec, refspec, the_hash_algo)) die(_("invalid refspec '%s'"), refspec); spec_src = spec.src; if (!*spec_src || !strcmp(spec_src, "HEAD")) diff --git a/refspec.c b/refspec.c index fb89bce1db..33a6fb8e45 100644 --- a/refspec.c +++ b/refspec.c @@ -16,7 +16,8 @@ * Parses the provided refspec 'refspec' and populates the refspec_item 'item'. * Returns 1 if successful and 0 if the refspec is invalid. */ -static int parse_refspec(struct refspec_item *item, const char *refspec, int fetch) +static int parse_refspec(struct refspec_item *item, const char *refspec, + const struct git_hash_algo *algo, int fetch) { size_t llen; int is_glob; @@ -84,7 +85,7 @@ static int parse_refspec(struct refspec_item *item, const char *refspec, int fet */ if (!*item->src) return 0; /* negative refspecs must not be empty */ - else if (llen == the_hash_algo->hexsz && !get_oid_hex(item->src, &unused)) + else if (llen == algo->hexsz && !get_oid_hex_algop(item->src, &unused, algo)) return 0; /* negative refspecs cannot be exact sha1 */ else if (!check_refname_format(item->src, flags)) ; /* valid looking ref is ok */ @@ -101,7 +102,7 @@ static int parse_refspec(struct refspec_item *item, const char *refspec, int fet /* LHS */ if (!*item->src) ; /* empty is ok; it means "HEAD" */ - else if (llen == the_hash_algo->hexsz && !get_oid_hex(item->src, &unused)) + else if (llen == algo->hexsz && !get_oid_hex_algop(item->src, &unused, algo)) item->exact_sha1 = 1; /* ok */ else if (!check_refname_format(item->src, flags)) ; /* valid looking ref is ok */ @@ -154,21 +155,23 @@ static int parse_refspec(struct refspec_item *item, const char *refspec, int fet } static int refspec_item_init(struct refspec_item *item, const char *refspec, - int fetch) + const struct git_hash_algo *algo, int fetch) { memset(item, 0, sizeof(*item)); item->raw = xstrdup(refspec); - return parse_refspec(item, refspec, fetch); + return parse_refspec(item, refspec, algo, fetch); } -int refspec_item_init_fetch(struct refspec_item *item, const char *refspec) +int refspec_item_init_fetch(struct refspec_item *item, const char *refspec, + const struct git_hash_algo *algo) { - return refspec_item_init(item, refspec, 1); + return refspec_item_init(item, refspec, algo, 1); } -int refspec_item_init_push(struct refspec_item *item, const char *refspec) +int refspec_item_init_push(struct refspec_item *item, const char *refspec, + const struct git_hash_algo *algo) { - return refspec_item_init(item, refspec, 0); + return refspec_item_init(item, refspec, algo, 0); } void refspec_item_clear(struct refspec_item *item) @@ -200,9 +203,9 @@ void refspec_append(struct refspec *rs, const char *refspec) int ret; if (rs->fetch) - ret = refspec_item_init_fetch(&item, refspec); + ret = refspec_item_init_fetch(&item, refspec, the_hash_algo); else - ret = refspec_item_init_push(&item, refspec); + ret = refspec_item_init_push(&item, refspec, the_hash_algo); if (!ret) die(_("invalid refspec '%s'"), refspec); @@ -246,10 +249,11 @@ void refspec_clear(struct refspec *rs) rs->fetch = 0; } -int valid_fetch_refspec(const char *fetch_refspec_str) +int valid_fetch_refspec(const char *fetch_refspec_str, + const struct git_hash_algo *algo) { struct refspec_item refspec; - int ret = refspec_item_init_fetch(&refspec, fetch_refspec_str); + int ret = refspec_item_init_fetch(&refspec, fetch_refspec_str, algo); refspec_item_clear(&refspec); return ret; } diff --git a/refspec.h b/refspec.h index 832d6f923c..e482b720a8 100644 --- a/refspec.h +++ b/refspec.h @@ -1,6 +1,7 @@ #ifndef REFSPEC_H #define REFSPEC_H +struct git_hash_algo; struct string_list; struct strvec; @@ -33,8 +34,10 @@ struct refspec_item { char *raw; }; -int refspec_item_init_fetch(struct refspec_item *item, const char *refspec); -int refspec_item_init_push(struct refspec_item *item, const char *refspec); +int refspec_item_init_fetch(struct refspec_item *item, const char *refspec, + const struct git_hash_algo *algo); +int refspec_item_init_push(struct refspec_item *item, const char *refspec, + const struct git_hash_algo *algo); void refspec_item_clear(struct refspec_item *item); /** @@ -61,7 +64,7 @@ __attribute__((format (printf,2,3))) void refspec_appendf(struct refspec *rs, const char *fmt, ...); void refspec_appendn(struct refspec *rs, const char **refspecs, int nr); -int valid_fetch_refspec(const char *refspec); +int valid_fetch_refspec(const char *refspec, const struct git_hash_algo *algo); /* * Determine what values to pass to the peer in ref-prefix lines diff --git a/remote.c b/remote.c index e6c52c850c..b4dff1e5f9 100644 --- a/remote.c +++ b/remote.c @@ -3039,7 +3039,7 @@ int valid_remote_name(const char *name) int result; struct strbuf refspec = STRBUF_INIT; strbuf_addf(&refspec, "refs/heads/test:refs/remotes/%s/test", name); - result = valid_fetch_refspec(refspec.buf); + result = valid_fetch_refspec(refspec.buf, the_hash_algo); strbuf_release(&refspec); return result; }