diff options
author | David Turner <dturner@twopensource.com> | 2016-04-07 15:03:10 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-04-10 11:35:41 -0700 |
commit | 2d0663b21661f2677bce5742204ccdd73745a062 (patch) | |
tree | 53cee16fbbf082a26394a960a7b796fae8e8bfc3 | |
parent | 7fd12bfbef015bb63f2376f678d71bca54bbc64d (diff) | |
download | git-2d0663b21661f2677bce5742204ccdd73745a062.tar.gz |
refs: move resolve_ref_unsafe into common code
Now that resolve_ref_unsafe's only interaction with the backend is
through read_raw_ref, we can move it into the common code. Later,
we'll replace read_raw_ref with a backend function.
Signed-off-by: David Turner <dturner@twopensource.com>
Reviewed-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | refs.c | 74 | ||||
-rw-r--r-- | refs/files-backend.c | 82 | ||||
-rw-r--r-- | refs/refs-internal.h | 6 |
3 files changed, 83 insertions, 79 deletions
@@ -1155,3 +1155,77 @@ int for_each_rawref(each_ref_fn fn, void *cb_data) return do_for_each_ref(NULL, "", fn, 0, DO_FOR_EACH_INCLUDE_BROKEN, cb_data); } + +/* This function needs to return a meaningful errno on failure */ +const char *resolve_ref_unsafe(const char *refname, int resolve_flags, + unsigned char *sha1, int *flags) +{ + static struct strbuf sb_refname = STRBUF_INIT; + int unused_flags; + int symref_count; + + if (!flags) + flags = &unused_flags; + + *flags = 0; + + if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { + if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || + !refname_is_safe(refname)) { + errno = EINVAL; + return NULL; + } + + /* + * dwim_ref() uses REF_ISBROKEN to distinguish between + * missing refs and refs that were present but invalid, + * to complain about the latter to stderr. + * + * We don't know whether the ref exists, so don't set + * REF_ISBROKEN yet. + */ + *flags |= REF_BAD_NAME; + } + + for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) { + unsigned int read_flags = 0; + + if (read_raw_ref(refname, sha1, &sb_refname, &read_flags)) { + *flags |= read_flags; + if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING)) + return NULL; + hashclr(sha1); + if (*flags & REF_BAD_NAME) + *flags |= REF_ISBROKEN; + return refname; + } + + *flags |= read_flags; + + if (!(read_flags & REF_ISSYMREF)) { + if (*flags & REF_BAD_NAME) { + hashclr(sha1); + *flags |= REF_ISBROKEN; + } + return refname; + } + + refname = sb_refname.buf; + if (resolve_flags & RESOLVE_REF_NO_RECURSE) { + hashclr(sha1); + return refname; + } + if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { + if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || + !refname_is_safe(refname)) { + errno = EINVAL; + return NULL; + } + + *flags |= REF_ISBROKEN | REF_BAD_NAME; + } + } + + errno = ELOOP; + return NULL; +} diff --git a/refs/files-backend.c b/refs/files-backend.c index a15986ccc2..71848ab9d6 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1269,8 +1269,6 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs) return get_ref_dir(refs->loose); } -/* We allow "recursive" symbolic refs. Only within reason, though */ -#define MAXDEPTH 5 #define MAXREFLEN (1024) /* @@ -1300,7 +1298,7 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs, char buffer[128], *p; char *path; - if (recursion > MAXDEPTH || strlen(refname) > MAXREFLEN) + if (recursion > SYMREF_MAXDEPTH || strlen(refname) > MAXREFLEN) return -1; path = *refs->name ? git_pathdup_submodule(refs->name, "%s", refname) @@ -1420,8 +1418,8 @@ static int resolve_missing_loose_ref(const char *refname, * - in all other cases, symref will be untouched, and therefore * refname will still be valid and unchanged. */ -static int read_raw_ref(const char *refname, unsigned char *sha1, - struct strbuf *symref, unsigned int *flags) +int read_raw_ref(const char *refname, unsigned char *sha1, + struct strbuf *symref, unsigned int *flags) { struct strbuf sb_contents = STRBUF_INIT; struct strbuf sb_path = STRBUF_INIT; @@ -1538,80 +1536,6 @@ out: return ret; } -/* This function needs to return a meaningful errno on failure */ -const char *resolve_ref_unsafe(const char *refname, int resolve_flags, - unsigned char *sha1, int *flags) -{ - static struct strbuf sb_refname = STRBUF_INIT; - int unused_flags; - int symref_count; - - if (!flags) - flags = &unused_flags; - - *flags = 0; - - if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { - if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || - !refname_is_safe(refname)) { - errno = EINVAL; - return NULL; - } - - /* - * dwim_ref() uses REF_ISBROKEN to distinguish between - * missing refs and refs that were present but invalid, - * to complain about the latter to stderr. - * - * We don't know whether the ref exists, so don't set - * REF_ISBROKEN yet. - */ - *flags |= REF_BAD_NAME; - } - - for (symref_count = 0; symref_count < MAXDEPTH; symref_count++) { - unsigned int read_flags = 0; - - if (read_raw_ref(refname, sha1, &sb_refname, &read_flags)) { - *flags |= read_flags; - if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING)) - return NULL; - hashclr(sha1); - if (*flags & REF_BAD_NAME) - *flags |= REF_ISBROKEN; - return refname; - } - - *flags |= read_flags; - - if (!(read_flags & REF_ISSYMREF)) { - if (*flags & REF_BAD_NAME) { - hashclr(sha1); - *flags |= REF_ISBROKEN; - } - return refname; - } - - refname = sb_refname.buf; - if (resolve_flags & RESOLVE_REF_NO_RECURSE) { - hashclr(sha1); - return refname; - } - if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { - if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || - !refname_is_safe(refname)) { - errno = EINVAL; - return NULL; - } - - *flags |= REF_ISBROKEN | REF_BAD_NAME; - } - } - - errno = ELOOP; - return NULL; -} - /* * Peel the entry (if possible) and return its new peel_status. If * repeel is true, re-peel the entry even if there is an old peeled diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 92aae80c21..3a4f634cb4 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -197,6 +197,8 @@ const char *find_descendant_ref(const char *dirname, int rename_ref_available(const char *oldname, const char *newname); +/* We allow "recursive" symbolic refs. Only within reason, though */ +#define SYMREF_MAXDEPTH 5 /* Include broken references in a do_for_each_ref*() iteration: */ #define DO_FOR_EACH_INCLUDE_BROKEN 0x01 @@ -206,4 +208,8 @@ int rename_ref_available(const char *oldname, const char *newname); */ int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn, int trim, int flags, void *cb_data); + +int read_raw_ref(const char *refname, unsigned char *sha1, + struct strbuf *symref, unsigned int *flags); + #endif /* REFS_REFS_INTERNAL_H */ |