rev-parse: make "whatchanged -- git-fetch-script" work again.
[gitweb.git] / show-branch.c
index 15b1968781178c8aa939a79ed5a7f8fb363d181e..7a0dcc649edaf6a823e15f60d04c6ce67348dc42 100644 (file)
@@ -5,7 +5,11 @@
 #include "refs.h"
 
 static const char show_branch_usage[] =
-"git-show-branch [--all] [--heads] [--tags] [--topo-order] [--more=count | --list | --independent | --merge-base ] [<refs>...]";
+"git-show-branch [--current] [--all] [--heads] [--tags] [--topo-order] [--more=count | --list | --independent | --merge-base ] [<refs>...]";
+
+static int default_num = 0;
+static int default_alloc = 0;
+static char **default_arg = NULL;
 
 #define UNINTERESTING  01
 
@@ -431,12 +435,12 @@ static void snarf_refs(int head, int tag)
        }
 }
 
-static int rev_is_head(char *head_path, int headlen,
-                      char *name,
+static int rev_is_head(char *head_path, int headlen, char *name,
                       unsigned char *head_sha1, unsigned char *sha1)
 {
        int namelen;
-       if ((!head_path[0]) || memcmp(head_sha1, sha1, 20))
+       if ((!head_path[0]) ||
+           (head_sha1 && sha1 && memcmp(head_sha1, sha1, 20)))
                return 0;
        namelen = strlen(name);
        if ((headlen < namelen) ||
@@ -492,7 +496,7 @@ static void append_one_rev(const char *av)
                append_ref(av, revkey);
                return;
        }
-       if (strchr(av, '*') || strchr(av, '?')) {
+       if (strchr(av, '*') || strchr(av, '?') || strchr(av, '[')) {
                /* glob style match */
                int saved_matches = ref_name_cnt;
                match_ref_pattern = av;
@@ -508,6 +512,21 @@ static void append_one_rev(const char *av)
        die("bad sha1 reference %s", av);
 }
 
+static int git_show_branch_config(const char *var, const char *value)
+{
+       if (!strcmp(var, "showbranch.default")) {
+               if (default_alloc <= default_num + 1) {
+                       default_alloc = default_alloc * 3 / 2 + 20;
+                       default_arg = xrealloc(default_arg, sizeof *default_arg * default_alloc);
+               }
+               default_arg[default_num++] = strdup(value);
+               default_arg[default_num] = NULL;
+               return 0;
+       }
+
+       return git_default_config(var, value);
+}
+
 int main(int ac, char **av)
 {
        struct commit *rev[MAX_REVS], *commit;
@@ -526,12 +545,25 @@ int main(int ac, char **av)
        int sha1_name = 0;
        int shown_merge_point = 0;
        int topo_order = 0;
+       int with_current_branch = 0;
+       int head_at = -1;
 
+       git_config(git_show_branch_config);
        setup_git_directory();
 
+       /* If nothing is specified, try the default first */
+       if (ac == 1 && default_num) {
+               ac = default_num + 1;
+               av = default_arg - 1; /* ick; we would not address av[0] */
+       }
+
        while (1 < ac && av[1][0] == '-') {
                char *arg = av[1];
-               if (!strcmp(arg, "--all"))
+               if (!strcmp(arg, "--")) {
+                       ac--; av++;
+                       break;
+               }
+               else if (!strcmp(arg, "--all"))
                        all_heads = all_tags = 1;
                else if (!strcmp(arg, "--heads"))
                        all_heads = 1;
@@ -543,6 +575,8 @@ int main(int ac, char **av)
                        extra = -1;
                else if (!strcmp(arg, "--no-name"))
                        no_name = 1;
+               else if (!strcmp(arg, "--current"))
+                       with_current_branch = 1;
                else if (!strcmp(arg, "--sha1-name"))
                        sha1_name = 1;
                else if (!strncmp(arg, "--more=", 7))
@@ -574,6 +608,34 @@ int main(int ac, char **av)
                ac--; av++;
        }
 
+       head_path_p = resolve_ref(git_path("HEAD"), head_sha1, 1);
+       if (head_path_p) {
+               head_path_len = strlen(head_path_p);
+               memcpy(head_path, head_path_p, head_path_len + 1);
+       }
+       else {
+               head_path_len = 0;
+               head_path[0] = 0;
+       }
+
+       if (with_current_branch && head_path_p) {
+               int has_head = 0;
+               for (i = 0; !has_head && i < ref_name_cnt; i++) {
+                       /* We are only interested in adding the branch
+                        * HEAD points at.
+                        */
+                       if (rev_is_head(head_path,
+                                       head_path_len,
+                                       ref_name[i],
+                                       head_sha1, NULL))
+                               has_head++;
+               }
+               if (!has_head) {
+                       int pfxlen = strlen(git_path("refs/heads/"));
+                       append_one_rev(head_path + pfxlen);
+               }
+       }
+
        if (!ref_name_cnt) {
                fprintf(stderr, "No revs to be shown.\n");
                exit(0);
@@ -609,16 +671,6 @@ int main(int ac, char **av)
        if (0 <= extra)
                join_revs(&list, &seen, num_rev, extra);
 
-       head_path_p = resolve_ref(git_path("HEAD"), head_sha1, 1);
-       if (head_path_p) {
-               head_path_len = strlen(head_path_p);
-               memcpy(head_path, head_path_p, head_path_len + 1);
-       }
-       else {
-               head_path_len = 0;
-               head_path[0] = 0;
-       }
-
        if (merge_base)
                return show_merge_base(seen, num_rev);
 
@@ -645,6 +697,8 @@ int main(int ac, char **av)
                        }
                        /* header lines never need name */
                        show_one_commit(rev[i], 1);
+                       if (is_head)
+                               head_at = i;
                }
                if (0 <= extra) {
                        for (i = 0; i < num_rev; i++)
@@ -673,9 +727,19 @@ int main(int ac, char **av)
                shown_merge_point |= ((this_flag & all_revs) == all_revs);
 
                if (1 < num_rev) {
-                       for (i = 0; i < num_rev; i++)
-                               putchar((this_flag & (1u << (i + REV_SHIFT)))
-                                       ? '+' : ' ');
+                       int is_merge = !!(commit->parents && commit->parents->next);
+                       for (i = 0; i < num_rev; i++) {
+                               int mark;
+                               if (!(this_flag & (1u << (i + REV_SHIFT))))
+                                       mark = ' ';
+                               else if (is_merge)
+                                       mark = '-';
+                               else if (i == head_at)
+                                       mark = '*';
+                               else
+                                       mark = '+';
+                               putchar(mark);
+                       }
                        putchar(' ');
                }
                show_one_commit(commit, no_name);