diff options
author | Junio C Hamano <gitster@pobox.com> | 2011-10-12 10:35:38 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2011-10-12 10:35:38 -0700 |
commit | ff74f7f1187cbf1b46e85ed1bde1f194991f919c (patch) | |
tree | e5b5dde1d991fc1202ff8dbec8d63fa7ff3a4b93 /refs.c | |
parent | dce4bab6567de7c458b334e029e3dedcab5f2648 (diff) | |
download | git-ff74f7f1187cbf1b46e85ed1bde1f194991f919c.tar.gz |
refs.c: move dwim_ref()/dwim_log() from sha1_name.c
Both dwim_ref()/dwim_log() functions are intimately related to the ref
parsing rules defined in refs.c and better fits there. Move them together
with substitute_branch_name(), a file scope static helper function.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 85 |
1 files changed, 85 insertions, 0 deletions
@@ -1067,6 +1067,91 @@ static int is_refname_available(const char *ref, const char *oldref, return 1; } +/* + * *string and *len will only be substituted, and *string returned (for + * later free()ing) if the string passed in is a magic short-hand form + * to name a branch. + */ +static char *substitute_branch_name(const char **string, int *len) +{ + struct strbuf buf = STRBUF_INIT; + int ret = interpret_branch_name(*string, &buf); + + if (ret == *len) { + size_t size; + *string = strbuf_detach(&buf, &size); + *len = size; + return (char *)*string; + } + + return NULL; +} + +int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) +{ + char *last_branch = substitute_branch_name(&str, &len); + const char **p, *r; + int refs_found = 0; + + *ref = NULL; + for (p = ref_rev_parse_rules; *p; p++) { + char fullref[PATH_MAX]; + unsigned char sha1_from_ref[20]; + unsigned char *this_result; + int flag; + + this_result = refs_found ? sha1_from_ref : sha1; + mksnpath(fullref, sizeof(fullref), *p, len, str); + r = resolve_ref(fullref, this_result, 1, &flag); + if (r) { + if (!refs_found++) + *ref = xstrdup(r); + if (!warn_ambiguous_refs) + break; + } else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) + warning("ignoring dangling symref %s.", fullref); + } + free(last_branch); + return refs_found; +} + +int dwim_log(const char *str, int len, unsigned char *sha1, char **log) +{ + char *last_branch = substitute_branch_name(&str, &len); + const char **p; + int logs_found = 0; + + *log = NULL; + for (p = ref_rev_parse_rules; *p; p++) { + struct stat st; + unsigned char hash[20]; + char path[PATH_MAX]; + const char *ref, *it; + + mksnpath(path, sizeof(path), *p, len, str); + ref = resolve_ref(path, hash, 1, NULL); + if (!ref) + continue; + if (!stat(git_path("logs/%s", path), &st) && + S_ISREG(st.st_mode)) + it = path; + else if (strcmp(ref, path) && + !stat(git_path("logs/%s", ref), &st) && + S_ISREG(st.st_mode)) + it = ref; + else + continue; + if (!logs_found++) { + *log = xstrdup(it); + hashcpy(sha1, hash); + } + if (!warn_ambiguous_refs) + break; + } + free(last_branch); + return logs_found; +} + static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char *old_sha1, int flags, int *type_p) { char *ref_file; |