X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=show-branch.c;h=24efb65e622d8dfe44db22e5bc23c9f8cc328109;hb=4ee6bc99133760531dd25013c7a7165b2feed9cd;hp=1935c448f4c50e8b9b4302162747a6a099dc718c;hpb=e99c2fbdda590b0d5fb5bd89001e6d9df8342564;p=git.git diff --git a/show-branch.c b/show-branch.c index 1935c448..24efb65e 100644 --- a/show-branch.c +++ b/show-branch.c @@ -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 ] [...]"; +"git-show-branch [--current] [--all] [--heads] [--tags] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [...]"; + +static int default_num = 0; +static int default_alloc = 0; +static char **default_arg = NULL; #define UNINTERESTING 01 @@ -254,8 +258,8 @@ static void show_one_commit(struct commit *commit, int no_name) char pretty[256], *cp; struct commit_name *name = commit->object.util; if (commit->object.parsed) - pretty_print_commit(CMIT_FMT_ONELINE, commit->buffer, ~0, - pretty, sizeof(pretty)); + pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, + pretty, sizeof(pretty), 0); else strcpy(pretty, "(unavailable)"); if (!strncmp(pretty, "[PATCH] ", 8)) @@ -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) || @@ -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; @@ -516,6 +535,7 @@ int main(int ac, char **av) int num_rev, i, extra = 0; int all_heads = 0, all_tags = 0; int all_mask, all_revs; + int lifo = 1; char head_path[128]; const char *head_path_p; int head_path_len; @@ -525,13 +545,26 @@ int main(int ac, char **av) int no_name = 0; int sha1_name = 0; int shown_merge_point = 0; - int topo_order = 0; + int with_current_branch = 0; + int head_at = -1; + int topics = 0; setup_git_directory(); + git_config(git_show_branch_config); + + /* 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 +576,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)) @@ -552,7 +587,11 @@ int main(int ac, char **av) else if (!strcmp(arg, "--independent")) independent = 1; else if (!strcmp(arg, "--topo-order")) - topo_order = 1; + lifo = 1; + else if (!strcmp(arg, "--topics")) + topics = 1; + else if (!strcmp(arg, "--date-order")) + lifo = 0; else usage(show_branch_usage); ac--; av++; @@ -574,6 +613,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 +676,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 +702,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++) @@ -656,8 +715,7 @@ int main(int ac, char **av) exit(0); /* Sort topologically */ - if (topo_order) - sort_in_topological_order(&seen); + sort_in_topological_order(&seen, lifo); /* Give names to commits */ if (!sha1_name && !no_name) @@ -669,13 +727,29 @@ int main(int ac, char **av) while (seen) { struct commit *commit = pop_one_commit(&seen); int this_flag = commit->object.flags; + int is_merge_point = ((this_flag & all_revs) == all_revs); - shown_merge_point |= ((this_flag & all_revs) == all_revs); + shown_merge_point |= is_merge_point; 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); + if (topics && + !is_merge_point && + (this_flag & (1u << REV_SHIFT))) + continue; + + 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);