From: Arnaud Lacombe Date: Sun, 04 Jan 2009 08:21:47 GMT Subject: Re: git-branch --print-current Message-ID: <1a69a9d80901040021i1dae2c6j7337cf57eed6476a@mail.gmail.com> In-Reply-To: Hi, On Thu, Jan 1, 2009 at 10:28 PM, Karl Chen wrote: > > How about an option to git-branch that just prints the name of the > current branch for scripts' sake? To replace: > > git branch --no-color 2>/dev/null | perl -ne '/^[*] (.*)/ && print $1' FWIW, I had this in a stalled modification in a tree, it just add the '-c' (as "current") option to git branch. Patch is mostly for the record :/ The main trouble I have with pipe stuff is that it forks a process for something that can be done natively. Previously, I was using awk(1) to extract the current branch: $ git branch | awk '/^\*/ {print $2}' - Arnaud diff --git a/builtin-branch.c b/builtin-branch.c index 494cbac..2846768 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -17,7 +17,7 @@ #include "revision.h" static const char * const builtin_branch_usage[] = { - "git branch [options] [-r | -a] [--merged | --no-merged]", + "git branch [options] [-r | -a | -c] [--merged | --no-merged]", "git branch [options] [-l] [-f] []", "git branch [options] [-r] (-d | -D) ", "git branch [options] (-m | -M) [] ", @@ -312,9 +312,6 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, int color; struct commit *commit = item->commit; - if (!matches_merge_filter(commit)) - return; - switch (item->kind) { case REF_LOCAL_BRANCH: color = COLOR_BRANCH_LOCAL; @@ -373,18 +370,58 @@ static int calc_maxwidth(struct ref_list *refs) return w; } -static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit) +static inline int is_current(struct ref_item *item, int detached) +{ + + if (detached || + item->kind != REF_LOCAL_BRANCH || + strcmp(item->name, head) != 0) + return 0; + + return 1; +} + +static void print_ref_list(struct ref_list *ref_list, int kinds, int detached, + int verbose, int abbrev, struct commit_list *with_commit) { + struct commit *head_commit; int i; + + head_commit = lookup_commit_reference_gently(head_sha1, 1); + + detached = (detached && (kinds & REF_LOCAL_BRANCH)); + if (detached && head_commit && has_commit(head_commit, with_commit)) { + struct ref_item item; + item.name = xstrdup("(no branch)"); + item.kind = REF_LOCAL_BRANCH; + item.commit = head_commit; + if (strlen(item.name) > ref_list->maxwidth) + ref_list->maxwidth = strlen(item.name); + print_ref_item(&item, ref_list->maxwidth, verbose, abbrev, 1); + free(item.name); + } + for (i = 0; i < ref_list->index; i++) { + int current = is_current(&ref_list->list[i], detached); + print_ref_item(&ref_list->list[i], ref_list->maxwidth, verbose, + abbrev, current); + } + +} + +static void print_branch(int kinds, int detached, int verbose, int abbrev, + int only_current, struct commit_list *with_commit) +{ struct ref_list ref_list; - struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1); + int i; memset(&ref_list, 0, sizeof(ref_list)); ref_list.kinds = kinds; ref_list.with_commit = with_commit; if (merge_filter != NO_FILTER) init_revisions(&ref_list.revs, NULL); + for_each_ref(append_ref, &ref_list); + if (merge_filter != NO_FILTER) { struct commit *filter; filter = lookup_commit_reference_gently(merge_filter_ref, 0); @@ -399,29 +436,24 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); - detached = (detached && (kinds & REF_LOCAL_BRANCH)); - if (detached && head_commit && has_commit(head_commit, with_commit)) { - struct ref_item item; - item.name = xstrdup("(no branch)"); - item.kind = REF_LOCAL_BRANCH; - item.commit = head_commit; - if (strlen(item.name) > ref_list.maxwidth) - ref_list.maxwidth = strlen(item.name); - print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1); - free(item.name); - } + if (only_current) { + for (i = 0; i < ref_list.index; i++) { + if (!is_current(&ref_list.list[i], detached)) + continue; + if (!matches_merge_filter(ref_list.list[i].commit)) + continue; - for (i = 0; i < ref_list.index; i++) { - int current = !detached && - (ref_list.list[i].kind == REF_LOCAL_BRANCH) && - !strcmp(ref_list.list[i].name, head); - print_ref_item(&ref_list.list[i], ref_list.maxwidth, verbose, - abbrev, current); + printf("%s\n", ref_list.list[i].name); + } + goto free_it; } + print_ref_list(&ref_list, kinds, detached, verbose, + abbrev, with_commit); + +free_it: free_ref_list(&ref_list); } - static void rename_branch(const char *oldname, const char *newname, int force) { struct strbuf oldref = STRBUF_INIT, newref = STRBUF_INIT, logmsg = STRBUF_INIT; @@ -499,7 +531,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) { int delete = 0, rename = 0, force_create = 0; int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0; - int reflog = 0; + int only_current = 0, reflog = 0; enum branch_track track; int kinds = REF_LOCAL_BRANCH; struct commit_list *with_commit = NULL; @@ -524,6 +556,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) PARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT, opt_parse_with_commit, (intptr_t) "HEAD", }, + OPT_SET_INT('c', NULL, &only_current, "show only current branch", 1), OPT__ABBREV(&abbrev), OPT_GROUP("Specific git-branch actions:"), @@ -576,9 +609,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (delete) return delete_branches(argc, argv, delete > 1, kinds); - else if (argc == 0) - print_ref_list(kinds, detached, verbose, abbrev, with_commit); - else if (rename && (argc == 1)) + else if (argc == 0) { + print_branch(kinds, detached, verbose, abbrev, only_current, + with_commit); + }else if (rename && (argc == 1)) rename_branch(head, argv[0], rename > 1); else if (rename && (argc == 2)) rename_branch(argv[0], argv[1], rename > 1);