Add --ignore-unmatch option to exit with zero status when no files are removed.
[gitweb.git] / builtin-show-branch.c
index 452c15fd1b6164f9d33aeb6652c394054b280d7d..c892f1f7a643b3d7e5c298837424a72cbc2c4f78 100644 (file)
@@ -4,7 +4,9 @@
 #include "builtin.h"
 
 static const char show_branch_usage[] =
-"git-show-branch [--sparse] [--current] [--all] [--remotes] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...] | --reflog[=n] <branch>";
+"git-show-branch [--sparse] [--current] [--all] [--remotes] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...] | --reflog[=n[,b]] <branch>";
+static const char show_branch_usage_reflog[] =
+"--reflog is incompatible with --all, --remotes, --independent or --merge-base";
 
 static int default_num;
 static int default_alloc;
@@ -264,7 +266,7 @@ static void show_one_commit(struct commit *commit, int no_name)
                                    pretty, sizeof(pretty), 0, NULL, NULL, 0);
        else
                strcpy(pretty, "(unavailable)");
-       if (!strncmp(pretty, "[PATCH] ", 8))
+       if (!prefixcmp(pretty, "[PATCH] "))
                cp = pretty + 8;
        else
                cp = pretty;
@@ -376,7 +378,7 @@ static int append_head_ref(const char *refname, const unsigned char *sha1, int f
 {
        unsigned char tmp[20];
        int ofs = 11;
-       if (strncmp(refname, "refs/heads/", ofs))
+       if (prefixcmp(refname, "refs/heads/"))
                return 0;
        /* If both heads/foo and tags/foo exists, get_sha1 would
         * get confused.
@@ -390,7 +392,7 @@ static int append_remote_ref(const char *refname, const unsigned char *sha1, int
 {
        unsigned char tmp[20];
        int ofs = 13;
-       if (strncmp(refname, "refs/remotes/", ofs))
+       if (prefixcmp(refname, "refs/remotes/"))
                return 0;
        /* If both heads/foo and tags/foo exists, get_sha1 would
         * get confused.
@@ -402,7 +404,7 @@ static int append_remote_ref(const char *refname, const unsigned char *sha1, int
 
 static int append_tag_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
 {
-       if (strncmp(refname, "refs/tags/", 10))
+       if (prefixcmp(refname, "refs/tags/"))
                return 0;
        return append_ref(refname + 5, sha1, 0);
 }
@@ -433,9 +435,9 @@ static int append_matching_ref(const char *refname, const unsigned char *sha1, i
                return 0;
        if (fnmatch(match_ref_pattern, tail, 0))
                return 0;
-       if (!strncmp("refs/heads/", refname, 11))
+       if (!prefixcmp(refname, "refs/heads/"))
                return append_head_ref(refname, sha1, flag, cb_data);
-       if (!strncmp("refs/tags/", refname, 10))
+       if (!prefixcmp(refname, "refs/tags/"))
                return append_tag_ref(refname, sha1, flag, cb_data);
        return append_ref(refname, sha1, 0);
 }
@@ -460,11 +462,11 @@ static int rev_is_head(char *head, int headlen, char *name,
        if ((!head[0]) ||
            (head_sha1 && sha1 && hashcmp(head_sha1, sha1)))
                return 0;
-       if (!strncmp(head, "refs/heads/", 11))
+       if (!prefixcmp(head, "refs/heads/"))
                head += 11;
-       if (!strncmp(name, "refs/heads/", 11))
+       if (!prefixcmp(name, "refs/heads/"))
                name += 11;
-       else if (!strncmp(name, "heads/", 6))
+       else if (!prefixcmp(name, "heads/"))
                name += 6;
        return !strcmp(head, name);
 }
@@ -633,7 +635,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                        with_current_branch = 1;
                else if (!strcmp(arg, "--sha1-name"))
                        sha1_name = 1;
-               else if (!strncmp(arg, "--more=", 7))
+               else if (!prefixcmp(arg, "--more="))
                        extra = atoi(arg + 7);
                else if (!strcmp(arg, "--merge-base"))
                        merge_base = 1;
@@ -647,44 +649,61 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                        dense = 0;
                else if (!strcmp(arg, "--date-order"))
                        lifo = 0;
-               else if (!strcmp(arg, "--reflog")) {
+               else if (!strcmp(arg, "--reflog") || !strcmp(arg, "-g")) {
                        reflog = DEFAULT_REFLOG;
                }
-               else if (!strncmp(arg, "--reflog=", 9))
+               else if (!prefixcmp(arg, "--reflog="))
                        parse_reflog_param(arg + 9, &reflog, &reflog_base);
+               else if (!prefixcmp(arg, "-g="))
+                       parse_reflog_param(arg + 3, &reflog, &reflog_base);
                else
                        usage(show_branch_usage);
                ac--; av++;
        }
        ac--; av++;
 
-       if (!!extra || !!reflog) {
+       if (extra || reflog) {
                /* "listing" mode is incompatible with
                 * independent nor merge-base modes.
                 */
                if (independent || merge_base)
                        usage(show_branch_usage);
-               if (!!reflog && (0 < extra))
+               if (reflog && ((0 < extra) || all_heads || all_remotes))
                        /*
                         * Asking for --more in reflog mode does not
-                        * make sense.
+                        * make sense.  --list is Ok.
+                        *
+                        * Also --all and --remotes do not make sense either.
                         */
-                       usage(show_branch_usage);
+                       usage(show_branch_usage_reflog);
        }
 
        /* If nothing is specified, show all branches by default */
        if (ac + all_heads + all_remotes == 0)
                all_heads = 1;
 
-       if (all_heads + all_remotes)
-               snarf_refs(all_heads, all_remotes);
        if (reflog) {
                unsigned char sha1[20];
                char nth_desc[256];
                char *ref;
                int base = 0;
+
+               if (ac == 0) {
+                       static const char *fake_av[2];
+                       const char *refname;
+
+                       refname = resolve_ref("HEAD", sha1, 1, NULL);
+                       fake_av[0] = xstrdup(refname);
+                       fake_av[1] = NULL;
+                       av = fake_av;
+                       ac = 1;
+               }
                if (ac != 1)
                        die("--reflog option needs one branch name");
+
+               if (MAX_REVS < reflog)
+                       die("Only %d entries can be shown at one time.",
+                           MAX_REVS);
                if (!dwim_ref(*av, strlen(*av), sha1, &ref))
                        die("No such ref %s", *av);
 
@@ -702,7 +721,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                }
 
                for (i = 0; i < reflog; i++) {
-                       char *logmsg, *msg, *m;
+                       char *logmsg, *m;
+                       const char *msg;
                        unsigned long timestamp;
                        int tz;
 
@@ -718,7 +738,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                                msg++;
                        m = xmalloc(strlen(msg) + 200);
                        sprintf(m, "(%s) %s",
-                               show_date(timestamp, 0, 1),
+                               show_date(timestamp, tz, 1),
                                msg);
                        reflog_msg[i] = m;
                        free(logmsg);
@@ -726,6 +746,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                        append_ref(nth_desc, sha1, 1);
                }
        }
+       else if (all_heads + all_remotes)
+               snarf_refs(all_heads, all_remotes);
        else {
                while (0 < ac) {
                        append_one_rev(*av);