diff options
Diffstat (limited to 'sha1_name.c')
-rw-r--r-- | sha1_name.c | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/sha1_name.c b/sha1_name.c index c50630a3ea..b3a90e6f05 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -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; } |