Merge git://git.kernel.org/pub/scm/gitk/gitk
[gitweb.git] / sha1_name.c
index 8b6c76f68ed1433caddfa8aab6132db667197433..b0b2167578a7baebeba676af0b33161fb688bae0 100644 (file)
@@ -351,8 +351,11 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
                }
                if (0 <= nth)
                        at_time = 0;
-               else
-                       at_time = approxidate(str + at + 2);
+               else {
+                       char *tmp = xstrndup(str + at + 2, reflog_len);
+                       at_time = approxidate(tmp);
+                       free(tmp);
+               }
                if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
                                &co_time, &co_tz, &co_cnt)) {
                        if (at_time)
@@ -407,18 +410,22 @@ static int get_nth_ancestor(const char *name, int len,
                            unsigned char *result, int generation)
 {
        unsigned char sha1[20];
-       int ret = get_sha1_1(name, len, sha1);
+       struct commit *commit;
+       int ret;
+
+       ret = get_sha1_1(name, len, sha1);
        if (ret)
                return ret;
+       commit = lookup_commit_reference(sha1);
+       if (!commit)
+               return -1;
 
        while (generation--) {
-               struct commit *commit = lookup_commit_reference(sha1);
-
-               if (!commit || parse_commit(commit) || !commit->parents)
+               if (parse_commit(commit) || !commit->parents)
                        return -1;
-               hashcpy(sha1, commit->parents->item->object.sha1);
+               commit = commit->parents->item;
        }
-       hashcpy(result, sha1);
+       hashcpy(result, commit->object.sha1);
        return 0;
 }
 
@@ -544,9 +551,8 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)
        int ret, has_suffix;
        const char *cp;
 
-       /* "name~3" is "name^^^",
-        * "name~" and "name~0" are name -- not "name^0"!
-        * "name^" is not "name^0"; it is "name^1".
+       /*
+        * "name~3" is "name^^^", "name~" is "name~1", and "name^" is "name^1".
         */
        has_suffix = 0;
        for (cp = name + len - 1; name <= cp; cp--) {
@@ -564,11 +570,10 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)
                cp++;
                while (cp < name + len)
                        num = num * 10 + *cp++ - '0';
-               if (has_suffix == '^') {
-                       if (!num && len1 == len - 1)
-                               num = 1;
+               if (!num && len1 == len - 1)
+                       num = 1;
+               if (has_suffix == '^')
                        return get_parent(name, len1, sha1, num);
-               }
                /* else if (has_suffix == '~') -- goes without saying */
                return get_nth_ancestor(name, len1, sha1, num);
        }