Sync with 2.6.4
[gitweb.git] / builtin / show-branch.c
index f5168b4cceaad18ad37ef895a78c6282b2294906..e17744bc0dad37b75865b5da8c8c3037bcc02167 100644 (file)
@@ -52,17 +52,6 @@ static struct commit *interesting(struct commit_list *list)
        return NULL;
 }
 
-static struct commit *pop_one_commit(struct commit_list **list_p)
-{
-       struct commit *commit;
-       struct commit_list *list;
-       list = *list_p;
-       commit = list->item;
-       *list_p = list->next;
-       free(list);
-       return commit;
-}
-
 struct commit_name {
        const char *head_name; /* which head's ancestor? */
        int generation; /* how many parents away from head_name */
@@ -212,7 +201,7 @@ static void join_revs(struct commit_list **list_p,
        while (*list_p) {
                struct commit_list *parents;
                int still_interesting = !!interesting(*list_p);
-               struct commit *commit = pop_one_commit(list_p);
+               struct commit *commit = pop_commit(list_p);
                int flags = commit->object.flags & all_mask;
 
                if (!still_interesting && extra <= 0)
@@ -368,10 +357,10 @@ static void sort_ref_range(int bottom, int top)
              compare_ref_name);
 }
 
-static int append_ref(const char *refname, const unsigned char *sha1,
+static int append_ref(const char *refname, const struct object_id *oid,
                      int allow_dups)
 {
-       struct commit *commit = lookup_commit_reference_gently(sha1, 1);
+       struct commit *commit = lookup_commit_reference_gently(oid->hash, 1);
        int i;
 
        if (!commit)
@@ -393,39 +382,42 @@ static int append_ref(const char *refname, const unsigned char *sha1,
        return 0;
 }
 
-static int append_head_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+static int append_head_ref(const char *refname, const struct object_id *oid,
+                          int flag, void *cb_data)
 {
-       unsigned char tmp[20];
+       struct object_id tmp;
        int ofs = 11;
        if (!starts_with(refname, "refs/heads/"))
                return 0;
        /* If both heads/foo and tags/foo exists, get_sha1 would
         * get confused.
         */
-       if (get_sha1(refname + ofs, tmp) || hashcmp(tmp, sha1))
+       if (get_sha1(refname + ofs, tmp.hash) || oidcmp(&tmp, oid))
                ofs = 5;
-       return append_ref(refname + ofs, sha1, 0);
+       return append_ref(refname + ofs, oid, 0);
 }
 
-static int append_remote_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+static int append_remote_ref(const char *refname, const struct object_id *oid,
+                            int flag, void *cb_data)
 {
-       unsigned char tmp[20];
+       struct object_id tmp;
        int ofs = 13;
        if (!starts_with(refname, "refs/remotes/"))
                return 0;
        /* If both heads/foo and tags/foo exists, get_sha1 would
         * get confused.
         */
-       if (get_sha1(refname + ofs, tmp) || hashcmp(tmp, sha1))
+       if (get_sha1(refname + ofs, tmp.hash) || oidcmp(&tmp, oid))
                ofs = 5;
-       return append_ref(refname + ofs, sha1, 0);
+       return append_ref(refname + ofs, oid, 0);
 }
 
-static int append_tag_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+static int append_tag_ref(const char *refname, const struct object_id *oid,
+                         int flag, void *cb_data)
 {
        if (!starts_with(refname, "refs/tags/"))
                return 0;
-       return append_ref(refname + 5, sha1, 0);
+       return append_ref(refname + 5, oid, 0);
 }
 
 static const char *match_ref_pattern = NULL;
@@ -439,7 +431,8 @@ static int count_slash(const char *s)
        return cnt;
 }
 
-static int append_matching_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+static int append_matching_ref(const char *refname, const struct object_id *oid,
+                              int flag, void *cb_data)
 {
        /* we want to allow pattern hold/<asterisk> to show all
         * branches under refs/heads/hold/, and v0.99.9? to show
@@ -455,21 +448,23 @@ static int append_matching_ref(const char *refname, const unsigned char *sha1, i
        if (wildmatch(match_ref_pattern, tail, 0, NULL))
                return 0;
        if (starts_with(refname, "refs/heads/"))
-               return append_head_ref(refname, sha1, flag, cb_data);
+               return append_head_ref(refname, oid, flag, cb_data);
        if (starts_with(refname, "refs/tags/"))
-               return append_tag_ref(refname, sha1, flag, cb_data);
-       return append_ref(refname, sha1, 0);
+               return append_tag_ref(refname, oid, flag, cb_data);
+       return append_ref(refname, oid, 0);
 }
 
 static void snarf_refs(int head, int remotes)
 {
        if (head) {
                int orig_cnt = ref_name_cnt;
+
                for_each_ref(append_head_ref, NULL);
                sort_ref_range(orig_cnt, ref_name_cnt);
        }
        if (remotes) {
                int orig_cnt = ref_name_cnt;
+
                for_each_ref(append_remote_ref, NULL);
                sort_ref_range(orig_cnt, ref_name_cnt);
        }
@@ -497,7 +492,7 @@ static int show_merge_base(struct commit_list *seen, int num_rev)
        int exit_status = 1;
 
        while (seen) {
-               struct commit *commit = pop_one_commit(&seen);
+               struct commit *commit = pop_commit(&seen);
                int flags = commit->object.flags & all_mask;
                if (!(flags & UNINTERESTING) &&
                    ((flags & all_revs) == all_revs)) {
@@ -529,14 +524,15 @@ static int show_independent(struct commit **rev,
 
 static void append_one_rev(const char *av)
 {
-       unsigned char revkey[20];
-       if (!get_sha1(av, revkey)) {
-               append_ref(av, revkey, 0);
+       struct object_id revkey;
+       if (!get_sha1(av, revkey.hash)) {
+               append_ref(av, &revkey, 0);
                return;
        }
        if (strchr(av, '*') || strchr(av, '?') || strchr(av, '[')) {
                /* glob style match */
                int saved_matches = ref_name_cnt;
+
                match_ref_pattern = av;
                match_ref_slash = count_slash(av);
                for_each_ref(append_matching_ref, NULL);
@@ -628,7 +624,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
        char head[128];
        const char *head_p;
        int head_len;
-       unsigned char head_sha1[20];
+       struct object_id head_oid;
        int merge_base = 0;
        int independent = 0;
        int no_name = 0;
@@ -710,11 +706,11 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
        }
 
        /* If nothing is specified, show all branches by default */
-       if (ac + all_heads + all_remotes == 0)
+       if (ac <= topics && all_heads + all_remotes == 0)
                all_heads = 1;
 
        if (reflog) {
-               unsigned char sha1[20];
+               struct object_id oid;
                char *ref;
                int base = 0;
                unsigned int flags = 0;
@@ -724,10 +720,12 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 
                        fake_av[0] = resolve_refdup("HEAD",
                                                    RESOLVE_REF_READING,
-                                                   sha1, NULL);
+                                                   oid.hash, NULL);
                        fake_av[1] = NULL;
                        av = fake_av;
                        ac = 1;
+                       if (!*av)
+                               die("no branches given, and HEAD is not valid");
                }
                if (ac != 1)
                        die("--reflog option needs one branch name");
@@ -735,7 +733,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                if (MAX_REVS < reflog)
                        die("Only %d entries can be shown at one time.",
                            MAX_REVS);
-               if (!dwim_ref(*av, strlen(*av), sha1, &ref))
+               if (!dwim_ref(*av, strlen(*av), oid.hash, &ref))
                        die("No such ref %s", *av);
 
                /* Has the base been specified? */
@@ -746,7 +744,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                                /* Ah, that is a date spec... */
                                unsigned long at;
                                at = approxidate(reflog_base);
-                               read_ref_at(ref, flags, at, -1, sha1, NULL,
+                               read_ref_at(ref, flags, at, -1, oid.hash, NULL,
                                            NULL, NULL, &base);
                        }
                }
@@ -758,7 +756,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                        unsigned long timestamp;
                        int tz;
 
-                       if (read_ref_at(ref, flags, 0, base+i, sha1, &logmsg,
+                       if (read_ref_at(ref, flags, 0, base+i, oid.hash, &logmsg,
                                        &timestamp, &tz, NULL)) {
                                reflog = i;
                                break;
@@ -769,27 +767,28 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                        else
                                msg++;
                        reflog_msg[i] = xstrfmt("(%s) %s",
-                                               show_date(timestamp, tz, 1),
+                                               show_date(timestamp, tz,
+                                                         DATE_MODE(RELATIVE)),
                                                msg);
                        free(logmsg);
 
                        nth_desc = xstrfmt("%s@{%d}", *av, base+i);
-                       append_ref(nth_desc, sha1, 1);
+                       append_ref(nth_desc, &oid, 1);
                        free(nth_desc);
                }
                free(ref);
        }
-       else if (all_heads + all_remotes)
-               snarf_refs(all_heads, all_remotes);
        else {
                while (0 < ac) {
                        append_one_rev(*av);
                        ac--; av++;
                }
+               if (all_heads + all_remotes)
+                       snarf_refs(all_heads, all_remotes);
        }
 
        head_p = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
-                                   head_sha1, NULL);
+                                   head_oid.hash, NULL);
        if (head_p) {
                head_len = strlen(head_p);
                memcpy(head, head_p, head_len + 1);
@@ -808,7 +807,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                        if (rev_is_head(head,
                                        head_len,
                                        ref_name[i],
-                                       head_sha1, NULL))
+                                       head_oid.hash, NULL))
                                has_head++;
                }
                if (!has_head) {
@@ -823,17 +822,17 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
        }
 
        for (num_rev = 0; ref_name[num_rev]; num_rev++) {
-               unsigned char revkey[20];
+               struct object_id revkey;
                unsigned int flag = 1u << (num_rev + REV_SHIFT);
 
                if (MAX_REVS <= num_rev)
                        die("cannot handle more than %d revs.", MAX_REVS);
-               if (get_sha1(ref_name[num_rev], revkey))
+               if (get_sha1(ref_name[num_rev], revkey.hash))
                        die("'%s' is not a valid ref.", ref_name[num_rev]);
-               commit = lookup_commit_reference(revkey);
+               commit = lookup_commit_reference(revkey.hash);
                if (!commit)
                        die("cannot find commit %s (%s)",
-                           ref_name[num_rev], revkey);
+                           ref_name[num_rev], oid_to_hex(&revkey));
                parse_commit(commit);
                mark_seen(commit, &seen);
 
@@ -867,7 +866,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                        int is_head = rev_is_head(head,
                                                  head_len,
                                                  ref_name[i],
-                                                 head_sha1,
+                                                 head_oid.hash,
                                                  rev[i]->object.sha1);
                        if (extra < 0)
                                printf("%c [%s] ",
@@ -911,7 +910,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
        all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
 
        while (seen) {
-               struct commit *commit = pop_one_commit(&seen);
+               struct commit *commit = pop_commit(&seen);
                int this_flag = commit->object.flags;
                int is_merge_point = ((this_flag & all_revs) == all_revs);