diff options
author | Junio C Hamano <junkio@cox.net> | 2007-02-08 23:24:51 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2007-02-08 23:24:51 -0800 |
commit | 40facde06e3f9d5231c257e1a7f5b545b563d45f (patch) | |
tree | cd72b3530897ca20d96047df6e4501ab8ece1cc9 | |
parent | eb3a48221fd4a0b38c31976028dbab7df51be6d4 (diff) | |
download | git-40facde06e3f9d5231c257e1a7f5b545b563d45f.tar.gz |
reflog: handle $name => remotes/%s/HEAD mapping consistently for logs
When refs/remotes/gfi/master and refs/remotes/gfi/HEAD exist,
and the latter is a symref that points at the former, dwim_ref()
resolves string "gfi" to "refs/remotes/gfi/master" as expected,
but dwim_log() does not understand "gfi@{1.day}" and needs to be
told "gfi/master@{1.day}". This is confusing.
Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r-- | sha1_name.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/sha1_name.c b/sha1_name.c index f79a7c9fb8..a7efa96f35 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -275,16 +275,29 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log) *log = NULL; for (p = ref_fmt; *p; p++) { struct stat st; - char *path = mkpath(*p, len, str); + unsigned char hash[20]; + char path[PATH_MAX]; + const char *ref, *it; + + strcpy(path, mkpath(*p, len, str)); + ref = resolve_ref(path, hash, 0, NULL); + if (!ref) + continue; if (!stat(git_path("logs/%s", path), &st) && - S_ISREG(st.st_mode)) { - if (!logs_found++) { - *log = xstrdup(path); - resolve_ref(path, sha1, 0, NULL); - } - if (!warn_ambiguous_refs) - break; + 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; } return logs_found; } |