diff options
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 76 |
1 files changed, 40 insertions, 36 deletions
@@ -48,7 +48,7 @@ static const char *parse_ref_line(char *line, unsigned char *sha1) } static void add_ref(const char *name, const unsigned char *sha1, - int flag, struct ref_array *refs, + int flag, int check_name, struct ref_array *refs, struct ref_entry **new_entry) { int len; @@ -59,7 +59,8 @@ static void add_ref(const char *name, const unsigned char *sha1, entry = xmalloc(sizeof(struct ref_entry) + len); hashcpy(entry->sha1, sha1); hashclr(entry->peeled); - if (check_refname_format(name, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT)) + if (check_name && + check_refname_format(name, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT)) die("Reference has invalid format: '%s'", name); memcpy(entry->name, name, len); entry->flag = flag; @@ -234,7 +235,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array) name = parse_ref_line(refline, sha1); if (name) { - add_ref(name, sha1, flag, array, &last); + add_ref(name, sha1, flag, 1, array, &last); continue; } if (last && @@ -249,7 +250,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array) void add_extra_ref(const char *name, const unsigned char *sha1, int flag) { - add_ref(name, sha1, flag, &extra_refs, NULL); + add_ref(name, sha1, flag, 0, &extra_refs, NULL); } void clear_extra_refs(void) @@ -333,12 +334,11 @@ static void get_ref_dir(const char *submodule, const char *base, hashclr(sha1); flag |= REF_ISBROKEN; } - } else - if (!resolve_ref(ref, sha1, 1, &flag)) { - hashclr(sha1); - flag |= REF_ISBROKEN; - } - add_ref(ref, sha1, flag, array, NULL); + } else if (read_ref_full(ref, sha1, 1, &flag)) { + hashclr(sha1); + flag |= REF_ISBROKEN; + } + add_ref(ref, sha1, flag, 1, array, NULL); } free(ref); closedir(dir); @@ -361,7 +361,7 @@ static int warn_if_dangling_symref(const char *refname, const unsigned char *sha if (!(flags & REF_ISSYMREF)) return 0; - resolves_to = resolve_ref(refname, junk, 0, NULL); + resolves_to = resolve_ref_unsafe(refname, junk, 0, NULL); if (!resolves_to || strcmp(resolves_to, d->refname)) return 0; @@ -497,7 +497,7 @@ static int get_packed_ref(const char *ref, unsigned char *sha1) return -1; } -const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag) +const char *resolve_ref_unsafe(const char *ref, unsigned char *sha1, int reading, int *flag) { int depth = MAXDEPTH; ssize_t len; @@ -605,6 +605,12 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int * return ref; } +char *resolve_refdup(const char *ref, unsigned char *sha1, int reading, int *flag) +{ + const char *ret = resolve_ref_unsafe(ref, sha1, reading, flag); + return ret ? xstrdup(ret) : NULL; +} + /* The argument to filter_refs */ struct ref_filter { const char *pattern; @@ -612,13 +618,18 @@ struct ref_filter { void *cb_data; }; -int read_ref(const char *ref, unsigned char *sha1) +int read_ref_full(const char *ref, unsigned char *sha1, int reading, int *flags) { - if (resolve_ref(ref, sha1, 1, NULL)) + if (resolve_ref_unsafe(ref, sha1, reading, flags)) return 0; return -1; } +int read_ref(const char *ref, unsigned char *sha1) +{ + return read_ref_full(ref, sha1, 1, NULL); +} + #define DO_FOR_EACH_INCLUDE_BROKEN 01 static int do_one_ref(const char *base, each_ref_fn fn, int trim, int flags, void *cb_data, struct ref_entry *entry) @@ -663,7 +674,7 @@ int peel_ref(const char *ref, unsigned char *sha1) goto fallback; } - if (!resolve_ref(ref, base, 1, &flag)) + if (read_ref_full(ref, base, 1, &flag)) return -1; if ((flag & REF_ISPACKED)) { @@ -746,7 +757,7 @@ static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data) return 0; } - if (resolve_ref("HEAD", sha1, 1, &flag)) + if (!read_ref_full("HEAD", sha1, 1, &flag)) return fn("HEAD", sha1, flag, cb_data); return 0; @@ -826,7 +837,7 @@ int head_ref_namespaced(each_ref_fn fn, void *cb_data) int flag; strbuf_addf(&buf, "%sHEAD", get_git_namespace()); - if (resolve_ref(buf.buf, sha1, 1, &flag)) + if (!read_ref_full(buf.buf, sha1, 1, &flag)) ret = fn(buf.buf, sha1, flag, cb_data); strbuf_release(&buf); @@ -998,13 +1009,6 @@ const char *ref_rev_parse_rules[] = { NULL }; -const char *ref_fetch_rules[] = { - "%.*s", - "refs/%.*s", - "refs/heads/%.*s", - NULL -}; - int refname_match(const char *abbrev_name, const char *full_name, const char **rules) { const char **p; @@ -1022,7 +1026,7 @@ int refname_match(const char *abbrev_name, const char *full_name, const char **r static struct ref_lock *verify_lock(struct ref_lock *lock, const unsigned char *old_sha1, int mustexist) { - if (!resolve_ref(lock->ref_name, lock->old_sha1, mustexist, NULL)) { + if (read_ref_full(lock->ref_name, lock->old_sha1, mustexist, NULL)) { error("Can't verify ref %s", lock->ref_name); unlock_ref(lock); return NULL; @@ -1113,7 +1117,7 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) this_result = refs_found ? sha1_from_ref : sha1; mksnpath(fullref, sizeof(fullref), *p, len, str); - r = resolve_ref(fullref, this_result, 1, &flag); + r = resolve_ref_unsafe(fullref, this_result, 1, &flag); if (r) { if (!refs_found++) *ref = xstrdup(r); @@ -1143,7 +1147,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log) const char *ref, *it; mksnpath(path, sizeof(path), *p, len, str); - ref = resolve_ref(path, hash, 1, NULL); + ref = resolve_ref_unsafe(path, hash, 1, NULL); if (!ref) continue; if (!stat(git_path("logs/%s", path), &st) && @@ -1179,7 +1183,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char lock = xcalloc(1, sizeof(struct ref_lock)); lock->lock_fd = -1; - ref = resolve_ref(ref, lock->old_sha1, mustexist, &type); + ref = resolve_ref_unsafe(ref, lock->old_sha1, mustexist, &type); if (!ref && errno == EISDIR) { /* we are trying to lock foo but we used to * have foo/bar which now does not exist; @@ -1192,7 +1196,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char error("there are still refs under '%s'", orig_ref); goto error_return; } - ref = resolve_ref(orig_ref, lock->old_sha1, mustexist, &type); + ref = resolve_ref_unsafe(orig_ref, lock->old_sha1, mustexist, &type); } if (type_p) *type_p = type; @@ -1355,7 +1359,7 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg) if (log && S_ISLNK(loginfo.st_mode)) return error("reflog for %s is a symlink", oldref); - symref = resolve_ref(oldref, orig_sha1, 1, &flag); + symref = resolve_ref_unsafe(oldref, orig_sha1, 1, &flag); if (flag & REF_ISSYMREF) return error("refname %s is a symbolic ref, renaming it is not supported", oldref); @@ -1377,7 +1381,8 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg) goto rollback; } - if (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1, REF_NODEREF)) { + if (!read_ref_full(newref, sha1, 1, &flag) && + delete_ref(newref, sha1, REF_NODEREF)) { if (errno==EISDIR) { if (remove_empty_directories(git_path("%s", newref))) { error("Directory not empty: %s", newref); @@ -1643,7 +1648,7 @@ int write_ref_sha1(struct ref_lock *lock, unsigned char head_sha1[20]; int head_flag; const char *head_ref; - head_ref = resolve_ref("HEAD", head_sha1, 1, &head_flag); + head_ref = resolve_ref_unsafe("HEAD", head_sha1, 1, &head_flag); if (head_ref && (head_flag & REF_ISSYMREF) && !strcmp(head_ref, lock->ref_name)) log_ref_write("HEAD", lock->old_sha1, sha1, logmsg); @@ -1929,7 +1934,7 @@ static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data) retval = do_for_each_reflog(log, fn, cb_data); } else { unsigned char sha1[20]; - if (!resolve_ref(log, sha1, 0, NULL)) + if (read_ref_full(log, sha1, 0, NULL)) retval = error("bad ref for %s", log); else retval = fn(log, sha1, 0, cb_data); @@ -1980,7 +1985,7 @@ int update_ref(const char *action, const char *refname, int ref_exists(const char *refname) { unsigned char sha1[20]; - return !!resolve_ref(refname, sha1, 1, NULL); + return !!resolve_ref_unsafe(refname, sha1, 1, NULL); } struct ref *find_ref_by_name(const struct ref *list, const char *name) @@ -2072,7 +2077,6 @@ char *shorten_unambiguous_ref(const char *ref, int strict) */ for (j = 0; j < rules_to_fail; j++) { const char *rule = ref_rev_parse_rules[j]; - unsigned char short_objectname[20]; char refname[PATH_MAX]; /* skip matched rule */ @@ -2086,7 +2090,7 @@ char *shorten_unambiguous_ref(const char *ref, int strict) */ mksnpath(refname, sizeof(refname), rule, short_name_len, short_name); - if (!read_ref(refname, short_objectname)) + if (ref_exists(refname)) break; } |