show-branch: fix description of --date-order
[gitweb.git] / sha1_name.c
index c50630a3ea793e0cfd2510b8813129a1685428f4..b3a90e6f051e8b75458055144829ea72bbe29970 100644 (file)
@@ -517,12 +517,21 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
                }
                if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
                                &co_time, &co_tz, &co_cnt)) {
+                       if (!len) {
+                               if (!prefixcmp(real_ref, "refs/heads/")) {
+                                       str = real_ref + 11;
+                                       len = strlen(real_ref + 11);
+                               } else {
+                                       /* detached HEAD */
+                                       str = "HEAD";
+                                       len = 4;
+                               }
+                       }
                        if (at_time)
                                warning("Log for '%.*s' only goes "
                                        "back to %s.", len, str,
                                        show_date(co_time, co_tz, DATE_RFC2822));
                        else {
-                               free(real_ref);
                                die("Log for '%.*s' only has %d entries.",
                                    len, str, co_cnt);
                        }
@@ -594,7 +603,7 @@ struct object *peel_to_type(const char *name, int namelen,
        while (1) {
                if (!o || (!o->parsed && !parse_object(o->sha1)))
                        return NULL;
-               if (o->type == expected_type)
+               if (expected_type == OBJ_ANY || o->type == expected_type)
                        return o;
                if (o->type == OBJ_TAG)
                        o = ((struct tag*) o)->tagged;
@@ -645,6 +654,8 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
                expected_type = OBJ_TREE;
        else if (!strncmp(blob_type, sp, 4) && sp[4] == '}')
                expected_type = OBJ_BLOB;
+       else if (!prefixcmp(sp, "object}"))
+               expected_type = OBJ_ANY;
        else if (sp[0] == '}')
                expected_type = OBJ_NONE;
        else if (sp[0] == '/')
@@ -654,6 +665,8 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
 
        if (expected_type == OBJ_COMMIT)
                lookup_flags = GET_SHA1_COMMITTISH;
+       else if (expected_type == OBJ_TREE)
+               lookup_flags = GET_SHA1_TREEISH;
 
        if (get_sha1_1(name, sp - name - 2, outer, lookup_flags))
                return -1;
@@ -856,8 +869,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1,
 }
 
 struct grab_nth_branch_switch_cbdata {
-       long cnt, alloc;
-       struct strbuf *buf;
+       int remaining;
+       struct strbuf buf;
 };
 
 static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
@@ -867,7 +880,6 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
        struct grab_nth_branch_switch_cbdata *cb = cb_data;
        const char *match = NULL, *target = NULL;
        size_t len;
-       int nth;
 
        if (!prefixcmp(message, "checkout: moving from ")) {
                match = message + strlen("checkout: moving from ");
@@ -876,11 +888,12 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
 
        if (!match || !target)
                return 0;
-
-       len = target - match;
-       nth = cb->cnt++ % cb->alloc;
-       strbuf_reset(&cb->buf[nth]);
-       strbuf_add(&cb->buf[nth], match, len);
+       if (--(cb->remaining) == 0) {
+               len = target - match;
+               strbuf_reset(&cb->buf);
+               strbuf_add(&cb->buf, match, len);
+               return 1; /* we are done */
+       }
        return 0;
 }
 
@@ -891,7 +904,7 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
 static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf)
 {
        long nth;
-       int i, retval;
+       int retval;
        struct grab_nth_branch_switch_cbdata cb;
        const char *brace;
        char *num_end;
@@ -901,34 +914,22 @@ static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf)
        brace = strchr(name, '}');
        if (!brace)
                return -1;
-       nth = strtol(name+3, &num_end, 10);
+       nth = strtol(name + 3, &num_end, 10);
        if (num_end != brace)
                return -1;
        if (nth <= 0)
                return -1;
-       cb.alloc = nth;
-       cb.buf = xmalloc(nth * sizeof(struct strbuf));
-       for (i = 0; i < nth; i++)
-               strbuf_init(&cb.buf[i], 20);
-       cb.cnt = 0;
+       cb.remaining = nth;
+       strbuf_init(&cb.buf, 20);
+
        retval = 0;
-       for_each_recent_reflog_ent("HEAD", grab_nth_branch_switch, 40960, &cb);
-       if (cb.cnt < nth) {
-               cb.cnt = 0;
-               for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
+       if (0 < for_each_reflog_ent_reverse("HEAD", grab_nth_branch_switch, &cb)) {
+               strbuf_reset(buf);
+               strbuf_add(buf, cb.buf.buf, cb.buf.len);
+               retval = brace - name + 1;
        }
-       if (cb.cnt < nth)
-               goto release_return;
-       i = cb.cnt % nth;
-       strbuf_reset(buf);
-       strbuf_add(buf, cb.buf[i].buf, cb.buf[i].len);
-       retval = brace-name+1;
-
-release_return:
-       for (i = 0; i < nth; i++)
-               strbuf_release(&cb.buf[i]);
-       free(cb.buf);
 
+       strbuf_release(&cb.buf);
        return retval;
 }
 
@@ -1041,14 +1042,15 @@ int interpret_branch_name(const char *name, struct strbuf *buf)
         * points to something different than a branch.
         */
        if (!upstream)
-               return error(_("HEAD does not point to a branch"));
+               die(_("HEAD does not point to a branch"));
        if (!upstream->merge || !upstream->merge[0]->dst) {
                if (!ref_exists(upstream->refname))
-                       return error(_("No such branch: '%s'"), cp);
-               if (!upstream->merge)
-                       return error(_("No upstream configured for branch '%s'"),
-                                    upstream->name);
-               return error(
+                       die(_("No such branch: '%s'"), cp);
+               if (!upstream->merge) {
+                       die(_("No upstream configured for branch '%s'"),
+                               upstream->name);
+               }
+               die(
                        _("Upstream branch '%s' not stored as a remote-tracking branch"),
                        upstream->merge[0]->src);
        }
@@ -1063,9 +1065,13 @@ int interpret_branch_name(const char *name, struct strbuf *buf)
 int strbuf_branchname(struct strbuf *sb, const char *name)
 {
        int len = strlen(name);
-       if (interpret_branch_name(name, sb) == len)
+       int used = interpret_branch_name(name, sb);
+
+       if (used == len)
                return 0;
-       strbuf_add(sb, name, len);
+       if (used < 0)
+               used = 0;
+       strbuf_add(sb, name + used, len - used);
        return len;
 }