{"thread":{"id":"27997","subject":"[RFC] branch: list branches by single remote","startedAt":"2011-08-02T17:17:38Z","lastAt":"2011-09-13T17:16:12Z","messageCount":77,"participants":["Michael Schubert","Jeff King","Michael J Gruber","Junio C Hamano","Thiago Farina","Sverre Rabbelier"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"172674","messageId":"4E383132.3040907@elegosoft.com","threadId":"27997","inReplyTo":null,"subject":"[RFC] branch: list branches by single remote","fromName":"Michael Schubert","fromEmail":"mschub@elegosoft.com","sentAt":"2011-08-02T17:17:38Z","receivedAt":"2011-08-02T17:17:38Z","isPatch":false,"sender":{"key":"mschub@elegosoft.com","avatar":null},"body":"I've always missed some option for \"git branch\" to limit the output to a single\nremote. What's the right place to filter the output? The code below doesn't\nlook very smart..\n\n---\n builtin/branch.c |   16 +++++++++++++---\n 1 files changed, 13 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 3142daa..22e6be2 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -17,7 +17,7 @@\n #include \"revision.h\"\n \n static const char * const builtin_branch_usage[] = {\n-\t\"git branch [options] [-r | -a] [--merged | --no-merged]\",\n+\t\"git branch [options] [-r | -a] [-R <remote>] [--merged | --no-merged]\",\n \t\"git branch [options] [-l] [-f] <branchname> [<start-point>]\",\n \t\"git branch [options] [-r] (-d | -D) <branchname>...\",\n \t\"git branch [options] (-m | -M) [<oldbranch>] <newbranch>\",\n@@ -260,6 +260,7 @@ static char *resolve_symref(const char *src, const char *prefix)\n \n struct append_ref_cb {\n \tstruct ref_list *ref_list;\n+\tconst char *remote;\n \tint ret;\n };\n \n@@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n \tif ((kind & ref_list->kinds) == 0)\n \t\treturn 0;\n \n+\tif (cb->remote && strncmp(cb->remote, refname, strlen(cb->remote)))\n+\t\treturn 0;\n+\n \tcommit = NULL;\n \tif (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {\n \t\tcommit = lookup_commit_reference_gently(sha1, 1);\n@@ -492,7 +496,7 @@ static void show_detached(struct ref_list *ref_list)\n \t}\n }\n \n-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)\n+static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char *only)\n {\n \tint i;\n \tstruct append_ref_cb cb;\n@@ -506,6 +510,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tif (merge_filter != NO_FILTER)\n \t\tinit_revisions(&ref_list.revs, NULL);\n \tcb.ref_list = &ref_list;\n+\tcb.remote = only;\n \tcb.ret = 0;\n \tfor_each_rawref(append_ref, &cb);\n \tif (merge_filter != NO_FILTER) {\n@@ -618,6 +623,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tenum branch_track track;\n \tint kinds = REF_LOCAL_BRANCH;\n \tstruct commit_list *with_commit = NULL;\n+\tchar *single_remote = NULL;\n \n \tstruct option options[] = {\n \t\tOPT_GROUP(\"Generic options\"),\n@@ -647,6 +653,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_GROUP(\"Specific git-branch actions:\"),\n \t\tOPT_SET_INT('a', NULL, &kinds, \"list both remote-tracking and local branches\",\n \t\t\tREF_REMOTE_BRANCH | REF_LOCAL_BRANCH),\n+\t\tOPT_STRING('R', NULL, &single_remote, \"remote\", \"list only branches by remote\"),\n \t\tOPT_BIT('d', NULL, &delete, \"delete fully merged branch\", 1),\n \t\tOPT_BIT('D', NULL, &delete, \"delete branch (even if not merged)\", 2),\n \t\tOPT_BIT('m', NULL, &rename, \"move/rename a branch and its reflog\", 1),\n@@ -696,10 +703,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tif (!!delete + !!rename + !!force_create > 1)\n \t\tusage_with_options(builtin_branch_usage, options);\n \n+\tif (single_remote)\n+\t\tkinds = REF_REMOTE_BRANCH;\n+\n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n \telse if (argc == 0)\n-\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n+\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit, single_remote);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n \telse if (rename && (argc == 2))\n-- \n1.7.6.396.ge0613.dirty\n"},{"id":"172853","messageId":"20110804040646.GA5104@sigill.intra.peff.net","threadId":"27997","inReplyTo":"4E383132.3040907@elegosoft.com","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-08-04T04:06:46Z","receivedAt":"2011-08-04T04:06:46Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Aug 02, 2011 at 07:17:38PM +0200, Michael Schubert wrote:\n\n> @@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n>  \tif ((kind & ref_list->kinds) == 0)\n>  \t\treturn 0;\n>  \n> +\tif (cb->remote && strncmp(cb->remote, refname, strlen(cb->remote)))\n> +\t\treturn 0;\n> +\n\nThis isn't right. You are assuming that a remote called \"foo\" will have\nall of its branches in refs/remotes/foo. That's true under the default\nconfiguration, but technically speaking, the remote tracking branches of\n\"foo\" are defined by the right-hand side of foo's fetch refspecs.\n\nSo I think you want something more like this:\n\n  int i;\n  struct remote *remote = remote_get(\"foo\");\n\n  for (i = 0; i < remote->fetch_refspec_nr; i++) {\n          struct refspec *rs = remote->fetch + i;\n\n          /* if it's not a wildcard, then take the rhs verbatim */\n          if (!rs->pattern)\n                  append_ref(rs->dst);\n          else {\n                  /* it's a wildcard like refs/remotes/foo/*; glob in\n                   * the ref list appropriately. Or we can cheat, noting\n                   * that git's only allowed wildcard is \"/*\" at the\n                   * end, and do this: */\n                  char *prefix = xstrndup(rs->dst, strlen(rs->dst) - 1);\n                  for_each_ref_in(prefix, append_ref, NULL);\n          }\n  }\n\ninstead of the call to \"for_each_rawref(append_ref, ...)\" that would\nnormally be used. You could even pretty easily allow selecting branches\nfrom multiple remotes, too, though I don't know if that is actually\nuseful.\n\n-Peff\n"},{"id":"173608","messageId":"4E4A729D.9030906@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110804040646.GA5104@sigill.intra.peff.net","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-16T13:37:33Z","receivedAt":"2011-08-16T13:37:33Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 04.08.2011 06:06:\n> On Tue, Aug 02, 2011 at 07:17:38PM +0200, Michael Schubert wrote:\n> \n>> @@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n>>  \tif ((kind & ref_list->kinds) == 0)\n>>  \t\treturn 0;\n>>  \n>> +\tif (cb->remote && strncmp(cb->remote, refname, strlen(cb->remote)))\n>> +\t\treturn 0;\n>> +\n> \n> This isn't right. You are assuming that a remote called \"foo\" will have\n> all of its branches in refs/remotes/foo. That's true under the default\n> configuration, but technically speaking, the remote tracking branches of\n> \"foo\" are defined by the right-hand side of foo's fetch refspecs.\n\nYou are 100% right here, but...\n\n> So I think you want something more like this:\n\n...the op still might want to filter simply by the remote name.\n\nReminds me that I have to resurrect my patterns-with-branches series....\n\nMichael\n"},{"id":"173613","messageId":"4E4A7C64.2090607@elegosoft.com","threadId":"27997","inReplyTo":"4E4A729D.9030906@drmicha.warpmail.net","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Michael Schubert","fromEmail":"mschub@elegosoft.com","sentAt":"2011-08-16T14:19:16Z","receivedAt":"2011-08-16T14:19:16Z","isPatch":false,"sender":{"key":"mschub@elegosoft.com","avatar":null},"body":"On 08/16/2011 03:37 PM, Michael J Gruber wrote:\n> Jeff King venit, vidit, dixit 04.08.2011 06:06:\n>> On Tue, Aug 02, 2011 at 07:17:38PM +0200, Michael Schubert wrote:\n>>\n>>> @@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n>>>  \tif ((kind & ref_list->kinds) == 0)\n>>>  \t\treturn 0;\n>>>  \n>>> +\tif (cb->remote && strncmp(cb->remote, refname, strlen(cb->remote)))\n>>> +\t\treturn 0;\n>>> +\n>>\n>> This isn't right. You are assuming that a remote called \"foo\" will have\n>> all of its branches in refs/remotes/foo. That's true under the default\n>> configuration, but technically speaking, the remote tracking branches of\n>> \"foo\" are defined by the right-hand side of foo's fetch refspecs.\n> \n> You are 100% right here, but...\n> \n>> So I think you want something more like this:\n> \n> ...the op still might want to filter simply by the remote name.\n\nThere's an interesting discussion related to the subject:\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/178960\n"},{"id":"173616","messageId":"20110816151448.GA5152@sigill.intra.peff.net","threadId":"27997","inReplyTo":"4E4A729D.9030906@drmicha.warpmail.net","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-08-16T15:14:50Z","receivedAt":"2011-08-16T15:14:50Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Aug 16, 2011 at 03:37:33PM +0200, Michael J Gruber wrote:\n\n> > This isn't right. You are assuming that a remote called \"foo\" will have\n> > all of its branches in refs/remotes/foo. That's true under the default\n> > configuration, but technically speaking, the remote tracking branches of\n> > \"foo\" are defined by the right-hand side of foo's fetch refspecs.\n> \n> You are 100% right here, but...\n> \n> > So I think you want something more like this:\n> \n> ...the op still might want to filter simply by the remote name.\n\nThat is a perfectly reasonable approach. It just should be called\n\"--glob\" or something, and not \"remote\".  git-tag allows patterns to an\nexplicit \"tag -l\", but \"-l\" is already taken for git-branch.\n\n> Reminds me that I have to resurrect my patterns-with-branches series....\n\nPlease do. I think it's a much simpler and more versatile solution to\nthe same problem.\n\n-Peff\n"},{"id":"174157","messageId":"4E551548.9090807@elegosoft.com","threadId":"27997","inReplyTo":"20110816151448.GA5152@sigill.intra.peff.net","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Michael Schubert","fromEmail":"mschub@elegosoft.com","sentAt":"2011-08-24T15:14:16Z","receivedAt":"2011-08-24T15:14:16Z","isPatch":false,"sender":{"key":"mschub@elegosoft.com","avatar":null},"body":"On 08/16/2011 05:14 PM, Jeff King wrote:\n> On Tue, Aug 16, 2011 at 03:37:33PM +0200, Michael J Gruber wrote:\n> \n>>> This isn't right. You are assuming that a remote called \"foo\" will have\n>>> all of its branches in refs/remotes/foo. That's true under the default\n>>> configuration, but technically speaking, the remote tracking branches of\n>>> \"foo\" are defined by the right-hand side of foo's fetch refspecs.\n>>\n>> You are 100% right here, but...\n>>\n>>> So I think you want something more like this:\n>>\n>> ...the op still might want to filter simply by the remote name.\n> \n> That is a perfectly reasonable approach. It just should be called\n> \"--glob\" or something, and not \"remote\".  git-tag allows patterns to an\n> explicit \"tag -l\", but \"-l\" is already taken for git-branch.\n\nAs suggested, I've just called it \"--glob\" for now.\n\n--- 8< ---\n\nSubject: [PATCH] branch: add option \"glob\" to filter listed branches\n\nWhen calling \"git branch\" with either \"-r\" or \"-a\", there is no way to\nfurther limit the output. Add an option \"--glob=<pattern>\" to allow\nlimiting the output to matching branch names.\n\nSigned-off-by: Michael Schubert <mschub@elegosoft.com>\n---\n Documentation/git-branch.txt |    8 ++++++--\n builtin/branch.c             |   13 ++++++++++---\n 2 files changed, 16 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex c50f189..5de3c79 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -8,7 +8,7 @@ git-branch - List, create, or delete branches\n SYNOPSIS\n --------\n [verse]\n-'git branch' [--color[=<when>] | --no-color] [-r | -a]\n+'git branch' [--color[=<when>] | --no-color] [(-r | -a) [--glob=<pattern>]]\n \t[-v [--abbrev=<length> | --no-abbrev]]\n \t[(--merged | --no-merged | --contains) [<commit>]]\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n@@ -20,7 +20,8 @@ DESCRIPTION\n \n With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n-branches to be listed, and option `-a` shows both.\n+branches to be listed, option `-a` shows both and `--glob` limits the\n+output to branches matching <pattern>.\n \n With `--contains`, shows only the branches that contain the named commit\n (in other words, the branches whose tip commits are descendants of the\n@@ -105,6 +106,9 @@ OPTIONS\n -a::\n \tList both remote-tracking branches and local branches.\n \n+--glob=<pattern>::\n+\tList only branches matching pattern.\n+\n -v::\n --verbose::\n \tShow sha1 and commit subject line for each head, along with\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 3142daa..74730ad 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -17,7 +17,7 @@\n #include \"revision.h\"\n \n static const char * const builtin_branch_usage[] = {\n-\t\"git branch [options] [-r | -a] [--merged | --no-merged]\",\n+\t\"git branch [options] [(-r | -a) [--glob=<pattern>]] [--merged | --no-merged]\",\n \t\"git branch [options] [-l] [-f] <branchname> [<start-point>]\",\n \t\"git branch [options] [-r] (-d | -D) <branchname>...\",\n \t\"git branch [options] (-m | -M) [<oldbranch>] <newbranch>\",\n@@ -260,6 +260,7 @@ static char *resolve_symref(const char *src, const char *prefix)\n \n struct append_ref_cb {\n \tstruct ref_list *ref_list;\n+\tconst char *glob;\n \tint ret;\n };\n \n@@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n \tif ((kind & ref_list->kinds) == 0)\n \t\treturn 0;\n \n+\tif (cb->glob && fnmatch(cb->glob, refname, 0))\n+\t\treturn 0;\n+\n \tcommit = NULL;\n \tif (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {\n \t\tcommit = lookup_commit_reference_gently(sha1, 1);\n@@ -492,7 +496,7 @@ static void show_detached(struct ref_list *ref_list)\n \t}\n }\n \n-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)\n+static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char *glob)\n {\n \tint i;\n \tstruct append_ref_cb cb;\n@@ -506,6 +510,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tif (merge_filter != NO_FILTER)\n \t\tinit_revisions(&ref_list.revs, NULL);\n \tcb.ref_list = &ref_list;\n+\tcb.glob = glob;\n \tcb.ret = 0;\n \tfor_each_rawref(append_ref, &cb);\n \tif (merge_filter != NO_FILTER) {\n@@ -618,6 +623,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tenum branch_track track;\n \tint kinds = REF_LOCAL_BRANCH;\n \tstruct commit_list *with_commit = NULL;\n+\tchar *glob = NULL;\n \n \tstruct option options[] = {\n \t\tOPT_GROUP(\"Generic options\"),\n@@ -647,6 +653,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_GROUP(\"Specific git-branch actions:\"),\n \t\tOPT_SET_INT('a', NULL, &kinds, \"list both remote-tracking and local branches\",\n \t\t\tREF_REMOTE_BRANCH | REF_LOCAL_BRANCH),\n+\t\tOPT_STRING(0, \"glob\", &glob, \"pattern\", \"list only branches matching the pattern\"),\n \t\tOPT_BIT('d', NULL, &delete, \"delete fully merged branch\", 1),\n \t\tOPT_BIT('D', NULL, &delete, \"delete branch (even if not merged)\", 2),\n \t\tOPT_BIT('m', NULL, &rename, \"move/rename a branch and its reflog\", 1),\n@@ -699,7 +706,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n \telse if (argc == 0)\n-\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n+\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit, glob);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n \telse if (rename && (argc == 2))\n-- \n1.7.6.577.g8d918.dirty\n"},{"id":"174160","messageId":"4E551AD0.7050702@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E551548.9090807@elegosoft.com","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-24T15:37:52Z","receivedAt":"2011-08-24T15:37:52Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Michael Schubert venit, vidit, dixit 24.08.2011 17:14:\n> On 08/16/2011 05:14 PM, Jeff King wrote:\n>> On Tue, Aug 16, 2011 at 03:37:33PM +0200, Michael J Gruber wrote:\n>>\n>>>> This isn't right. You are assuming that a remote called \"foo\" will have\n>>>> all of its branches in refs/remotes/foo. That's true under the default\n>>>> configuration, but technically speaking, the remote tracking branches of\n>>>> \"foo\" are defined by the right-hand side of foo's fetch refspecs.\n>>>\n>>> You are 100% right here, but...\n>>>\n>>>> So I think you want something more like this:\n>>>\n>>> ...the op still might want to filter simply by the remote name.\n>>\n>> That is a perfectly reasonable approach. It just should be called\n>> \"--glob\" or something, and not \"remote\".  git-tag allows patterns to an\n>> explicit \"tag -l\", but \"-l\" is already taken for git-branch.\n> \n> As suggested, I've just called it \"--glob\" for now.\n\nWell, again, what's the point in replicating\n\nhttp://permalink.gmane.org/gmane.comp.version-control.git/172228\n\nand how is it different?\n\nAs I've mentioned, I've been in the middle of polishing that up. You can\nfollow it if you like:\n\nhttp://repo.or.cz/w/git/mjg.git/shortlog/refs/heads/branch-list-pattern\n\nAlso, again: git branch is much more like git tag than it is like git\nlog, so I think the pattern matching options should be, too.\n\nMichael\n"},{"id":"174164","messageId":"4E5520AC.7050407@elegosoft.com","threadId":"27997","inReplyTo":"4E551AD0.7050702@drmicha.warpmail.net","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Michael Schubert","fromEmail":"mschub@elegosoft.com","sentAt":"2011-08-24T16:02:52Z","receivedAt":"2011-08-24T16:02:52Z","isPatch":false,"sender":{"key":"mschub@elegosoft.com","avatar":null},"body":"On 08/24/2011 05:37 PM, Michael J Gruber wrote:\n> Michael Schubert venit, vidit, dixit 24.08.2011 17:14:\n>> On 08/16/2011 05:14 PM, Jeff King wrote:\n>>> On Tue, Aug 16, 2011 at 03:37:33PM +0200, Michael J Gruber wrote:\n>>>\n>>>>> This isn't right. You are assuming that a remote called \"foo\" will have\n>>>>> all of its branches in refs/remotes/foo. That's true under the default\n>>>>> configuration, but technically speaking, the remote tracking branches of\n>>>>> \"foo\" are defined by the right-hand side of foo's fetch refspecs.\n>>>>\n>>>> You are 100% right here, but...\n>>>>\n>>>>> So I think you want something more like this:\n>>>>\n>>>> ...the op still might want to filter simply by the remote name.\n>>>\n>>> That is a perfectly reasonable approach. It just should be called\n>>> \"--glob\" or something, and not \"remote\".  git-tag allows patterns to an\n>>> explicit \"tag -l\", but \"-l\" is already taken for git-branch.\n>>\n>> As suggested, I've just called it \"--glob\" for now.\n> \n> Well, again, what's the point in replicating\n> \n> http://permalink.gmane.org/gmane.comp.version-control.git/172228\n> \n> and how is it different?\n\nWhile I just haven't seen this,\n\n> As I've mentioned, I've been in the middle of polishing that up. You can\n> follow it if you like:\n> \n> http://repo.or.cz/w/git/mjg.git/shortlog/refs/heads/branch-list-pattern\n\nI thought I just send it out not knowing you're actually into resurrecting\nthe \"patterns-with-branches series\".\n\nThanks.\n"},{"id":"174173","messageId":"7vei0apsj9.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"4E551AD0.7050702@drmicha.warpmail.net","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-24T18:34:50Z","receivedAt":"2011-08-24T18:34:50Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n>> As suggested, I've just called it \"--glob\" for now.\n>\n> Well, again, what's the point in replicating\n>\n> http://permalink.gmane.org/gmane.comp.version-control.git/172228\n>\n> and how is it different?\n> As I've mentioned, I've been in the middle of polishing that up.\n\nIt is not unusual for a similar itch to happen to different people\nindependently.\n\nIf this were something you reposted even a WIP re-polish within the past\ntwo weeks, I would understand and even sympathise with your irritation,\nbut please don't expect everybody to dig back FOUR MONTHS worth of mail\nbacklog to find an topic that may or may not be abandoned by the original\nauthor.  Perhaps we would need a weekly posting of topics people have\nposted, found to be not quite ready yet, and are still being polished and\nnot abandoned [*1*]?\n\nHaving said that, I still appreciate that you posted a link to the\nprevious topic:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/172226\n\nso that the discussions in this thread to scratch the same \"itch\" can\nbenefit from the points raised in the previous thread that need to be\nconsidered.\n\nThe old thread talks about renaming existing options and transition plans\nto make the \"listing\" mode of \"branch\" and \"tag\" more similar, which may\nbe a good plan in the longer term.\n\nI however can see that teaching \"--glob\" to both \"branch\" and \"tag\" (in\nother words, \"tag -l\" would become a synonym for \"tag --glob\") an equally\ngood longer term plan.\n\n\n[Footnote]\n\n*1* It does not have to be a weekly _posting_ on the list but can be a\nwell-known Wiki page or even a bug tracker. Whatever medium is used for\nthis purpose, there _must_ be a built-in mechanism to expire entries away\nthat are inactive for more than some reasonable limit (say two to three\nweeks).\n"},{"id":"174206","messageId":"CACnwZYd=pM+fRNy0pqv+jR9bb0AWC89nkgHq3m1nMw9cUfHOQw@mail.gmail.com","threadId":"27997","inReplyTo":"7vei0apsj9.fsf@alter.siamese.dyndns.org","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Thiago Farina","fromEmail":"tfransosi@gmail.com","sentAt":"2011-08-25T02:31:57Z","receivedAt":"2011-08-25T02:31:57Z","isPatch":false,"sender":{"key":"tfransosi@gmail.com","avatar":"https://avatars.githubusercontent.com/u/970071?v=4"},"body":"On Wed, Aug 24, 2011 at 3:34 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> [Footnote]\n>\n> *1* It does not have to be a weekly _posting_ on the list but can be a\n> well-known Wiki page or even a bug tracker. Whatever medium is used for\n> this purpose, there _must_ be a built-in mechanism to expire entries away\n> that are inactive for more than some reasonable limit (say two to three\n> weeks).\n\nHost the project on Google Code for bug tracking? Use rietveld for\ncode reviews (ike codereview.chromium.org and codereview.appspot.com)?\n"},{"id":"174216","messageId":"4E5607E0.1050300@drmicha.warpmail.net","threadId":"27997","inReplyTo":"7vei0apsj9.fsf@alter.siamese.dyndns.org","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-25T08:29:20Z","receivedAt":"2011-08-25T08:29:20Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 24.08.2011 20:34:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n> \n>>> As suggested, I've just called it \"--glob\" for now.\n>>\n>> Well, again, what's the point in replicating\n>>\n>> http://permalink.gmane.org/gmane.comp.version-control.git/172228\n>>\n>> and how is it different?\n>> As I've mentioned, I've been in the middle of polishing that up.\n> \n> It is not unusual for a similar itch to happen to different people\n> independently.\n> \n> If this were something you reposted even a WIP re-polish within the past\n> two weeks, I would understand and even sympathise with your irritation,\n> but please don't expect everybody to dig back FOUR MONTHS worth of mail\n> backlog to find an topic that may or may not be abandoned by the original\n> author.  Perhaps we would need a weekly posting of topics people have\n\nWell, I've mentioned it earlier in this thread, though without a link.\nIt's the time when several of us are off-line for a couple weeks. I've\nalso mentioned it in the thread about filtering by remote.\n\nOn a side note, the list here usually does require people to search\nback, and much longer than this, on frequently requested issues. But how\ndoes a newcomer discover \"frequently\"? Right, by searching back years,\nnot months.\n\n> posted, found to be not quite ready yet, and are still being polished and\n> not abandoned [*1*]?\n> \n> Having said that, I still appreciate that you posted a link to the\n> previous topic:\n> \n>   http://thread.gmane.org/gmane.comp.version-control.git/172226\n> \n> so that the discussions in this thread to scratch the same \"itch\" can\n> benefit from the points raised in the previous thread that need to be\n> considered.\n> \n> The old thread talks about renaming existing options and transition plans\n> to make the \"listing\" mode of \"branch\" and \"tag\" more similar, which may\n> be a good plan in the longer term.\n> \n> I however can see that teaching \"--glob\" to both \"branch\" and \"tag\" (in\n> other words, \"tag -l\" would become a synonym for \"tag --glob\") an equally\n> good longer term plan.\n\nI don't care about the names, but I'd hate to introduce more\ninconsistencies. The implementation is a non-brainer, it's really\nsomething only Apple could get a patent on. The other Michael and I came\nup with basically the same patch because it follows \"automatically\". But\nthe ui is important.\n\nSo I'll take the opportunity and discuss this further in the cover\nletter for the upcoming series.\n\nMichael\n"},{"id":"174217","messageId":"cover.1314259226.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E5607E0.1050300@drmicha.warpmail.net","subject":"[PATCH 0/5] RFC: patterns for branch list","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-25T08:30:16Z","receivedAt":"2011-08-25T08:30:16Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"This mini series is about introducing patterns to the list mode of\n'git branch' much like the pattern for 'git tag -l'. There are several\nrelated things which are to be considered for the ui design:\n\ngit log\n=======\n\nFor \"log\" and friends, \"--glob\" is a means to specify revision arguments by\nmatching refs. Note that we have\n\n--branches[=<pattern>] matching in refs/heads\n--tags[=<pattern>] matching in refs/tags\n--glob=<glob-pattern> matching in refs/\n\ngit tag\n=======\n\nFor \"tag\", we have a pattern matching in refs/tags, but only in the list mode\nof \"tag\", which is invoked by \"-l\", or automatically when there are no\narguments. There is no pattern related option, it's \"always on\" in list mode.\nI.e., in list mode it behaves much like\n\ngit log --no-walk --oneline --tags=\n\nwith a different format string, and an optional argument stuck at the end of\nthe line. (git for-each-ref is another related interface, but plumbing, so I'll\nskip it here.)\n\ngit branch\n==========\n\nAnalogous to \"git tag\", \"branch\" has several modes, one of which is list mode.\nIt is currently activated (and possibly modified) by \"-v\" and \"-vv\", and when\nthere are no arguments. So, at the least,\n\ngit branch -v[v] <pattern>\n\nshould match just like \"git tag -l <pattern>\" does. And that is what the first\npatch in my series does.\n\nThen we need an option to invoke list mode. The natural candidate \"-l\" is taken\nby the badly named reflog option, which is why I suggested \"--list\" and moving\nthe reflog option to \"-g\" over time.\n\nI'm open to other suggestions as long as they keep and improve the consistency\nbetween \"git tag\" and \"git branch\". I never liked their different implicit\nmodes/subcommands but have been around long enough to know that they are there\nto stay.\n\n\"git tag\" should probably learn the same long option and others. And why not\nverify tags given by a pattern?\n\nBoth \"tag\" and \"branch\" could activate list mode automatically on an invalid\ntag name rather than dieing:\n\ngit tag v1.7.6\\*\nWarning: tag 'v1.7.6*' not found.\nv1.7.6\nv1.7.6-rc0\nv1.7.6-rc1\nv1.7.6-rc2\nv1.7.6-rc3\nv1.7.6.1\n\nOn the other hand, one might think about implementing both list modes (tag and\nbranch) using the revision machinery and custom format strings, or\nfor-each-ref; rather than both differently as it is now.\n\n'-l' is the natural short option name for '--list'. This is taken for the\nrarely used or needed 'create reflog' option. I'd change the latter to\n'-g,--create-reflog' (cmp. log) and take '-l,--list' but know the reaction\nalready.\n\n-v[v] sanity\n============\n\n'-v' and '-vv' both take considerable time (because they need to walk).\nIt makes more sense to have '-v' display cheap output (upstream name)\nand '-vv' add expensive output (ahead/behind info). '-vvv' could add super\nexpensive info (ahead/equivalent/behind a la cherry-mark).\n\nThese are changes to current porcelain ui behaviour, so I deem this to be OK\n(too late for 1.7.7, of course). The option renaming needs a transition\n(not done in this series).\n\nMichael J Gruber (5):\n  branch: allow pattern arguments\n  branch: introduce --list argument\n  t6040; test branch -vv [independent, can go in as is testing current behaviour]\n  branch: restructure -v vs. -vv\n  branch: give patchsame count with -vvv\n\n Documentation/git-branch.txt |   20 +++++++++---\n builtin/branch.c             |   65 +++++++++++++++++++++++++----------------\n remote.c                     |   12 ++++++--\n remote.h                     |    2 +-\n t/t3203-branch-output.sh     |   24 +++++++++++++++\n t/t6040-tracking-info.sh     |   41 ++++++++++++++++++++++++--\n wt-status.c                  |    2 +-\n 7 files changed, 127 insertions(+), 39 deletions(-)\n\n-- \n1.7.6.845.gc3c05\n"},{"id":"174220","messageId":"00847b8ee77129433a5d908ad25c9ebaf7fa7130.1314259226.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E5607E0.1050300@drmicha.warpmail.net","subject":"[PATCH 1/5] branch: allow pattern arguments","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-25T08:30:17Z","receivedAt":"2011-08-25T08:30:17Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Allow pattern arguments for the list mode just like for git tag -l.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |    7 +++++--\n builtin/branch.c             |   13 +++++++++----\n t/t3203-branch-output.sh     |   10 ++++++++++\n 3 files changed, 24 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex c50f189..2152d48 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n [verse]\n 'git branch' [--color[=<when>] | --no-color] [-r | -a]\n \t[-v [--abbrev=<length> | --no-abbrev]]\n-\t[(--merged | --no-merged | --contains) [<commit>]]\n+\t[(--merged | --no-merged | --contains) [<commit>]] [<pattern>]\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n 'git branch' (-d | -D) [-r] <branchname>...\n@@ -20,7 +20,10 @@ DESCRIPTION\n \n With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n-branches to be listed, and option `-a` shows both.\n+branches to be listed, and option `-a` shows both. This list mode is also\n+activated by the `-v` option (see below).\n+<pattern> restricts the output to matching branches, the pattern is a shell\n+wildcard (i.e., matched using fnmatch(3))\n \n With `--contains`, shows only the branches that contain the named commit\n (in other words, the branches whose tip commits are descendants of the\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 73d4170..6b40815 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -260,6 +260,7 @@ static char *resolve_symref(const char *src, const char *prefix)\n \n struct append_ref_cb {\n \tstruct ref_list *ref_list;\n+\tconst char *pattern;\n \tint ret;\n };\n \n@@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n \tif ((kind & ref_list->kinds) == 0)\n \t\treturn 0;\n \n+\tif (cb->pattern && fnmatch(cb->pattern, refname, 0))\n+\t\treturn 0;\n+\n \tcommit = NULL;\n \tif (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {\n \t\tcommit = lookup_commit_reference_gently(sha1, 1);\n@@ -492,7 +496,7 @@ static void show_detached(struct ref_list *ref_list)\n \t}\n }\n \n-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)\n+static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char *pattern)\n {\n \tint i;\n \tstruct append_ref_cb cb;\n@@ -506,6 +510,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tif (merge_filter != NO_FILTER)\n \t\tinit_revisions(&ref_list.revs, NULL);\n \tcb.ref_list = &ref_list;\n+\tcb.pattern = pattern;\n \tcb.ret = 0;\n \tfor_each_rawref(append_ref, &cb);\n \tif (merge_filter != NO_FILTER) {\n@@ -523,7 +528,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tqsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);\n \n \tdetached = (detached && (kinds & REF_LOCAL_BRANCH));\n-\tif (detached)\n+\tif (detached && (!pattern || !fnmatch(pattern, \"HEAD\", 0)))\n \t\tshow_detached(&ref_list);\n \n \tfor (i = 0; i < ref_list.index; i++) {\n@@ -695,8 +700,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n-\telse if (argc == 0)\n-\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n+\telse if (argc == 0 || (verbose && argc == 1))\n+\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit, argc ? argv[0] : NULL);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n \telse if (rename && (argc == 2))\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex 6b7c118..2df1d3d 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -67,6 +67,16 @@ test_expect_success 'git branch -v shows branch summaries' '\n '\n \n cat >expect <<'EOF'\n+two\n+one\n+EOF\n+test_expect_success 'git branch -v pattern shows branch summaries' '\n+\tgit branch -v branch* >tmp &&\n+\tawk \"{print \\$NF}\" <tmp >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n * (no branch)\n   branch-one\n   branch-two\n-- \n1.7.6.845.gc3c05\n"},{"id":"174222","messageId":"32d0954697da9ac96cc11af0d8cc1390d93fd037.1314259226.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E5607E0.1050300@drmicha.warpmail.net","subject":"[PATCH 2/5] branch: introduce --list argument","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-25T08:30:19Z","receivedAt":"2011-08-25T08:30:19Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Currently, there is no way to invoke the list mode with a pattern\nbecause this is interpreted as branch creation.\n\nIntroduce a --list argument which invokes the list mode.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |    9 +++++++--\n builtin/branch.c             |   10 +++++++---\n t/t3203-branch-output.sh     |   14 ++++++++++++++\n 3 files changed, 28 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 2152d48..789ff02 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git branch' [--color[=<when>] | --no-color] [-r | -a]\n-\t[-v [--abbrev=<length> | --no-abbrev]]\n+\t[--list] [-v [--abbrev=<length> | --no-abbrev]]\n \t[(--merged | --no-merged | --contains) [<commit>]] [<pattern>]\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n@@ -21,7 +21,7 @@ DESCRIPTION\n With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n branches to be listed, and option `-a` shows both. This list mode is also\n-activated by the `-v` option (see below).\n+activated by the `--list` and `-v` options (see below).\n <pattern> restricts the output to matching branches, the pattern is a shell\n wildcard (i.e., matched using fnmatch(3))\n \n@@ -108,11 +108,16 @@ OPTIONS\n -a::\n \tList both remote-tracking branches and local branches.\n \n+--list::\n+\tActivate the list mode. `git branch <pattern>` would try to create a branch,\n+\tuse `git branch --list <pattern>` to list matching branches.\n+\n -v::\n --verbose::\n \tShow sha1 and commit subject line for each head, along with\n \trelationship to upstream branch (if any). If given twice, print\n \tthe name of the upstream branch, as well.\n+\t`--list` is implied by all verbosity options.\n \n --abbrev=<length>::\n \tAlter the sha1's minimum display length in the output listing.\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 6b40815..aed0aca 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -617,7 +617,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int\n \n int cmd_branch(int argc, const char **argv, const char *prefix)\n {\n-\tint delete = 0, rename = 0, force_create = 0;\n+\tint delete = 0, rename = 0, force_create = 0, list = 0;\n \tint verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;\n \tint reflog = 0;\n \tenum branch_track track;\n@@ -656,6 +656,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT('D', NULL, &delete, \"delete branch (even if not merged)\", 2),\n \t\tOPT_BIT('m', NULL, &rename, \"move/rename a branch and its reflog\", 1),\n \t\tOPT_BIT('M', NULL, &rename, \"move/rename a branch, even if target exists\", 2),\n+\t\tOPT_BOOLEAN(0, \"list\", &list, \"list branch names\"),\n \t\tOPT_BOOLEAN('l', NULL, &reflog, \"create the branch's reflog\"),\n \t\tOPT__FORCE(&force_create, \"force creation (when already exists)\"),\n \t\t{\n@@ -695,12 +696,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, prefix, options, builtin_branch_usage,\n \t\t\t     0);\n-\tif (!!delete + !!rename + !!force_create > 1)\n+\tif (!!delete + !!rename + !!force_create + !!list > 1)\n \t\tusage_with_options(builtin_branch_usage, options);\n \n+\tif (argc == 0 || (verbose && argc == 1))\n+\t\tlist = 1;\n+\n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n-\telse if (argc == 0 || (verbose && argc == 1))\n+\telse if (list)\n \t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit, argc ? argv[0] : NULL);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex 2df1d3d..f2b294b 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git branch --list shows local branches' '\n+\tgit branch --list >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+  branch-one\n+  branch-two\n+EOF\n+test_expect_success 'git branch --list pattern shows matching local branches' '\n+\tgit branch --list branch* >actual &&\n+\ttest_cmp expect actual\n+'\n+\n cat >expect <<'EOF'\n   origin/HEAD -> origin/branch-one\n   origin/branch-one\n-- \n1.7.6.845.gc3c05\n"},{"id":"174218","messageId":"d55c61a6c667a8ef08c8ead8e3672050375253f9.1314259226.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E5607E0.1050300@drmicha.warpmail.net","subject":"[PATCH 3/5] t6040; test branch -vv","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-25T08:30:20Z","receivedAt":"2011-08-25T08:30:20Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"t6040 has a test for 'git branch -v' but not for 'git branch -vv'.\nAdd one.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n t/t6040-tracking-info.sh |   16 ++++++++++++++++\n 1 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh\nindex 19de5b1..19272bc 100755\n--- a/t/t6040-tracking-info.sh\n+++ b/t/t6040-tracking-info.sh\n@@ -51,6 +51,22 @@ test_expect_success 'branch -v' '\n \ttest_i18ncmp expect actual\n '\n \n+cat >expect <<\\EOF\n+b1 origin/master: ahead 1, behind 1\n+b2 origin/master: ahead 1, behind 1\n+b3 origin/master: behind 1\n+b4 origin/master: ahead 2\n+EOF\n+\n+test_expect_success 'branch -vv' '\n+\t(\n+\t\tcd test &&\n+\t\tgit branch -vv\n+\t) |\n+\tsed -n -e \"$script\" >actual &&\n+\ttest_i18ncmp expect actual\n+'\n+\n test_expect_success 'checkout' '\n \t(\n \t\tcd test && git checkout b1\n-- \n1.7.6.845.gc3c05\n"},{"id":"174221","messageId":"f471a616e4f08e729384138d8cb8afff4e9dbcbf.1314259226.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E5607E0.1050300@drmicha.warpmail.net","subject":"[PATCH 4/5] branch: restructure -v vs. -vv","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-25T08:30:21Z","receivedAt":"2011-08-25T08:30:21Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"ahead/behind info is expensive, upstream name info cheap. Therefore,\nmake -v output the upstream branch name and -vv add the ahead/behind\ninfo.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |    4 ++--\n builtin/branch.c             |   34 ++++++++++++++++------------------\n t/t6040-tracking-info.sh     |    8 ++++----\n 3 files changed, 22 insertions(+), 24 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 789ff02..59d729a 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -115,8 +115,8 @@ OPTIONS\n -v::\n --verbose::\n \tShow sha1 and commit subject line for each head, along with\n-\trelationship to upstream branch (if any). If given twice, print\n-\tthe name of the upstream branch, as well.\n+\tthe name of the upstream branch (if any). If given twice, print\n+\tthe relationship to the upstream branch (ahead/behind), as well.\n \t`--list` is implied by all verbosity options.\n \n --abbrev=<length>::\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex aed0aca..21ef5fc 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -359,29 +359,27 @@ static int ref_cmp(const void *r1, const void *r2)\n }\n \n static void fill_tracking_info(struct strbuf *stat, const char *branch_name,\n-\t\tint show_upstream_ref)\n+\t\tint verbose)\n {\n \tint ours, theirs;\n \tstruct branch *branch = branch_get(branch_name);\n \n-\tif (!stat_tracking_info(branch, &ours, &theirs)) {\n-\t\tif (branch && branch->merge && branch->merge[0]->dst &&\n-\t\t    show_upstream_ref)\n-\t\t\tstrbuf_addf(stat, \"[%s] \",\n-\t\t\t    shorten_unambiguous_ref(branch->merge[0]->dst, 0));\n+\t/* verbose >= 1 */\n+\tif (!(branch && branch->merge && branch->merge[0]->dst))\n \t\treturn;\n-\t}\n-\n \tstrbuf_addch(stat, '[');\n-\tif (show_upstream_ref)\n-\t\tstrbuf_addf(stat, \"%s: \",\n-\t\t\tshorten_unambiguous_ref(branch->merge[0]->dst, 0));\n-\tif (!ours)\n-\t\tstrbuf_addf(stat, _(\"behind %d] \"), theirs);\n-\telse if (!theirs)\n-\t\tstrbuf_addf(stat, _(\"ahead %d] \"), ours);\n-\telse\n-\t\tstrbuf_addf(stat, _(\"ahead %d, behind %d] \"), ours, theirs);\n+\tstrbuf_addstr(stat, shorten_unambiguous_ref(branch->merge[0]->dst, 0));\n+\n+\tif (verbose >= 2 && stat_tracking_info(branch, &ours, &theirs)) {\n+\t\tstrbuf_addstr(stat, \": \");\n+\t\tif (!ours)\n+\t\t\tstrbuf_addf(stat, _(\"behind %d\"), theirs);\n+\t\telse if (!theirs)\n+\t\t\tstrbuf_addf(stat, _(\"ahead %d\"), ours);\n+\t\telse\n+\t\t\tstrbuf_addf(stat, _(\"ahead %d, behind %d\"), ours, theirs);\n+\t}\n+\tstrbuf_addstr(stat, \"] \");\n }\n \n static int matches_merge_filter(struct commit *commit)\n@@ -408,7 +406,7 @@ static void add_verbose_info(struct strbuf *out, struct ref_item *item,\n \t}\n \n \tif (item->kind == REF_LOCAL_BRANCH)\n-\t\tfill_tracking_info(&stat, item->name, verbose > 1);\n+\t\tfill_tracking_info(&stat, item->name, verbose);\n \n \tstrbuf_addf(out, \" %s %s%s\",\n \t\tfind_unique_abbrev(item->commit->object.sha1, abbrev),\ndiff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh\nindex 19272bc..9539882 100755\n--- a/t/t6040-tracking-info.sh\n+++ b/t/t6040-tracking-info.sh\n@@ -36,10 +36,10 @@ test_expect_success setup '\n \n script='s/^..\\(b.\\)[\t 0-9a-f]*\\[\\([^]]*\\)\\].*/\\1 \\2/p'\n cat >expect <<\\EOF\n-b1 ahead 1, behind 1\n-b2 ahead 1, behind 1\n-b3 behind 1\n-b4 ahead 2\n+b1 origin/master\n+b2 origin/master\n+b3 origin/master\n+b4 origin/master\n EOF\n \n test_expect_success 'branch -v' '\n-- \n1.7.6.845.gc3c05\n"},{"id":"174219","messageId":"1b532b894c26c6b31c94760222715b5eb5cc45bb.1314259226.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E5607E0.1050300@drmicha.warpmail.net","subject":"[PATCH 5/5] branch: give patchsame count with -vvv","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-25T08:30:22Z","receivedAt":"2011-08-25T08:30:22Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"This results in output like such as\n\n  mjg/attr-filetype                    9d2536e [origin/next: ahead 35,\nbehind 1430, same 46] attr: make attributes depend on file type\n\nall on one line.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |    2 ++\n builtin/branch.c             |   24 ++++++++++++++++--------\n remote.c                     |   12 +++++++++---\n remote.h                     |    2 +-\n t/t6040-tracking-info.sh     |   19 ++++++++++++++++++-\n wt-status.c                  |    2 +-\n 6 files changed, 47 insertions(+), 14 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 59d729a..770b2e4 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -117,6 +117,8 @@ OPTIONS\n \tShow sha1 and commit subject line for each head, along with\n \tthe name of the upstream branch (if any). If given twice, print\n \tthe relationship to the upstream branch (ahead/behind), as well.\n+\tIf given three times, show ahead/behind/same information like\n+\t`git rev-list --count --cherry-mark`.\n \t`--list` is implied by all verbosity options.\n \n --abbrev=<length>::\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 21ef5fc..0984bb7 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -361,7 +361,7 @@ static int ref_cmp(const void *r1, const void *r2)\n static void fill_tracking_info(struct strbuf *stat, const char *branch_name,\n \t\tint verbose)\n {\n-\tint ours, theirs;\n+\tint ours, theirs, patchsame = 0;\n \tstruct branch *branch = branch_get(branch_name);\n \n \t/* verbose >= 1 */\n@@ -370,14 +370,22 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,\n \tstrbuf_addch(stat, '[');\n \tstrbuf_addstr(stat, shorten_unambiguous_ref(branch->merge[0]->dst, 0));\n \n-\tif (verbose >= 2 && stat_tracking_info(branch, &ours, &theirs)) {\n-\t\tstrbuf_addstr(stat, \": \");\n-\t\tif (!ours)\n-\t\t\tstrbuf_addf(stat, _(\"behind %d\"), theirs);\n-\t\telse if (!theirs)\n+\tif (verbose >= 2 && stat_tracking_info(branch, &ours, &theirs, (verbose >=3) ? &patchsame : NULL)) {\n+\t\tstrbuf_addstr(stat, _(\": \"));\n+\t\tconst char *sep = \"\";\n+\t\tif (ours) {\n \t\t\tstrbuf_addf(stat, _(\"ahead %d\"), ours);\n-\t\telse\n-\t\t\tstrbuf_addf(stat, _(\"ahead %d, behind %d\"), ours, theirs);\n+\t\t\tsep = _(\", \");\n+\t\t}\n+\t\tif (theirs) {\n+\t\t\tstrbuf_addstr(stat, sep);\n+\t\t\tstrbuf_addf(stat, _(\"behind %d\"), theirs);\n+\t\t\tsep = _(\", \");\n+\t\t}\n+\t\tif (patchsame) {\n+\t\t\tstrbuf_addstr(stat, sep);\n+\t\t\tstrbuf_addf(stat, _(\"same %d\"), patchsame);\n+\t\t}\n \t}\n \tstrbuf_addstr(stat, \"] \");\n }\ndiff --git a/remote.c b/remote.c\nindex b8ecfa5..40cebef 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1510,7 +1510,7 @@ int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1)\n /*\n  * Return true if there is anything to report, otherwise false.\n  */\n-int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)\n+int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs, int *num_patchsame)\n {\n \tunsigned char sha1[20];\n \tstruct commit *ours, *theirs;\n@@ -1553,6 +1553,8 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)\n \trev_argv[rev_argc++] = NULL;\n \trev_argv[rev_argc++] = \"--left-right\";\n \trev_argv[rev_argc++] = symmetric;\n+\tif (num_patchsame)\n+\t\trev_argv[rev_argc++] = \"--cherry-mark\";\n \trev_argv[rev_argc++] = \"--\";\n \trev_argv[rev_argc] = NULL;\n \n@@ -1567,11 +1569,15 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)\n \t/* ... and count the commits on each side. */\n \t*num_ours = 0;\n \t*num_theirs = 0;\n+\tif (num_patchsame)\n+\t\t*num_patchsame = 0;\n \twhile (1) {\n \t\tstruct commit *c = get_revision(&revs);\n \t\tif (!c)\n \t\t\tbreak;\n-\t\tif (c->object.flags & SYMMETRIC_LEFT)\n+\t\tif (c->object.flags & PATCHSAME)\n+\t\t\t(*num_patchsame)++;\n+\t\telse if (c->object.flags & SYMMETRIC_LEFT)\n \t\t\t(*num_ours)++;\n \t\telse\n \t\t\t(*num_theirs)++;\n@@ -1591,7 +1597,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb)\n \tint num_ours, num_theirs;\n \tconst char *base;\n \n-\tif (!stat_tracking_info(branch, &num_ours, &num_theirs))\n+\tif (!stat_tracking_info(branch, &num_ours, &num_theirs, NULL))\n \t\treturn 0;\n \n \tbase = branch->merge[0]->dst;\ndiff --git a/remote.h b/remote.h\nindex 9a30a9d..31c1f28 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -149,7 +149,7 @@ enum match_refs_flags {\n };\n \n /* Reporting of tracking info */\n-int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs);\n+int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs, int *num_patchsame);\n int format_tracking_info(struct branch *branch, struct strbuf *sb);\n \n struct ref *get_local_heads(void);\ndiff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh\nindex 9539882..f8bff61 100755\n--- a/t/t6040-tracking-info.sh\n+++ b/t/t6040-tracking-info.sh\n@@ -24,6 +24,7 @@ test_expect_success setup '\n \t\tadvance d &&\n \t\tgit checkout -b b2 origin &&\n \t\tgit reset --hard b1 &&\n+\t\tgit cherry-pick origin &&\n \t\tgit checkout -b b3 origin &&\n \t\tgit reset --hard HEAD^ &&\n \t\tgit checkout -b b4 origin &&\n@@ -53,7 +54,7 @@ test_expect_success 'branch -v' '\n \n cat >expect <<\\EOF\n b1 origin/master: ahead 1, behind 1\n-b2 origin/master: ahead 1, behind 1\n+b2 origin/master: ahead 2, behind 1\n b3 origin/master: behind 1\n b4 origin/master: ahead 2\n EOF\n@@ -67,6 +68,22 @@ test_expect_success 'branch -vv' '\n \ttest_i18ncmp expect actual\n '\n \n+cat >expect <<\\EOF\n+b1 origin/master: ahead 1, behind 1\n+b2 origin/master: ahead 1, same 2\n+b3 origin/master: behind 1\n+b4 origin/master: ahead 2\n+EOF\n+\n+test_expect_success 'branch -vvv' '\n+\t(\n+\t\tcd test &&\n+\t\tgit branch -vvv\n+\t) |\n+\tsed -n -e \"$script\" >actual &&\n+\ttest_i18ncmp expect actual\n+'\n+\n test_expect_success 'checkout' '\n \t(\n \t\tcd test && git checkout b1\ndiff --git a/wt-status.c b/wt-status.c\nindex 8836a52..522318a 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -890,7 +890,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)\n \tbranch = branch_get(s->branch + 11);\n \tif (s->is_initial)\n \t\tcolor_fprintf(s->fp, header_color, _(\"Initial commit on \"));\n-\tif (!stat_tracking_info(branch, &num_ours, &num_theirs)) {\n+\tif (!stat_tracking_info(branch, &num_ours, &num_theirs, NULL)) {\n \t\tcolor_fprintf_ln(s->fp, branch_color_local,\n \t\t\t\"%s\", branch_name);\n \t\treturn;\n-- \n1.7.6.845.gc3c05\n"},{"id":"174241","messageId":"20110825175301.GC519@sigill.intra.peff.net","threadId":"27997","inReplyTo":"cover.1314259226.git.git@drmicha.warpmail.net","subject":"Re: [PATCH 0/5] RFC: patterns for branch list","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-08-25T17:53:01Z","receivedAt":"2011-08-25T17:53:01Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Aug 25, 2011 at 10:30:16AM +0200, Michael J Gruber wrote:\n\n> This mini series is about introducing patterns to the list mode of\n> 'git branch' much like the pattern for 'git tag -l'. There are several\n> related things which are to be considered for the ui design:\n\n> [log vs tag vs branch]\n\nI agree that the ideal UI change would be to move git-branch's \"-l\" to\n\"-g\", and make \"-l|--list\" work the same as it does for git-tag.\n\nEven though branch is generally considered a porcelain, I worry a little\nabout making that change. A script that wants to create a branch has no\nreal choice other than to use \"git branch\" (OK, they can use\n\"update-ref\" themselves, but I seriously doubt that most scripts do so).\nHowever, I kind of doubt anyone actually uses \"-l\"; it is mostly\npointless in the default config, so maybe it is safe.\n\nSearching google code for \"git.branch.*-l\" turns up only one hit, and it\nis somebody who apparently thought that \"-l\" meant \"list\".\n\n> Analogous to \"git tag\", \"branch\" has several modes, one of which is list mode.\n> It is currently activated (and possibly modified) by \"-v\" and \"-vv\", and when\n> there are no arguments. So, at the least,\n> \n> git branch -v[v] <pattern>\n> \n> should match just like \"git tag -l <pattern>\" does. And that is what the first\n> patch in my series does.\n\nThe order of your patches seems backwards to me. You add\npattern-matching for \"-v\", but there is no way to get pattern-matching\nfor the non-verbose case. Shouldn't \"--list\" come first?\n\nMaybe I am just nitpicking, as I think the end result after the series\nis the same. I just found the first patch very confusing.\n\n> \"git tag\" should probably learn the same long option and others. And why not\n> verify tags given by a pattern?\n\nYeah, having them both do --list makes sense. Whether it is appropriate\nto glob for other operations, I don't know. I think you'd have to\nlook at each operation individually.\n\n> Both \"tag\" and \"branch\" could activate list mode automatically on an invalid\n> tag name rather than dieing:\n> \n> git tag v1.7.6\\*\n> Warning: tag 'v1.7.6*' not found.\n> v1.7.6\n> v1.7.6-rc0\n> v1.7.6-rc1\n> v1.7.6-rc2\n> v1.7.6-rc3\n> v1.7.6.1\n\nThat just seems confusing to me. What is the exit status? Shouldn't the\nwarning be \"error: tag 'v1.7.6*' is not a valid tag name\"?\n\n> -v[v] sanity\n> ============\n> \n> '-v' and '-vv' both take considerable time (because they need to walk).\n> It makes more sense to have '-v' display cheap output (upstream name)\n> and '-vv' add expensive output (ahead/behind info). '-vvv' could add super\n> expensive info (ahead/equivalent/behind a la cherry-mark).\n\nI think the original rationale was not so much \"how much time does it\ntake\", but rather \"how much space do you want each line to take on your\nterminal\". For many people, the upstream name in \"-vv\" is just\ncluttering noise.\n\nTag and branch listing are really just specialized versions of\nfor-each-ref. I wonder if it makes sense to do:\n\n  1. Teach for-each-ref formats replacement tokens for ahead/behind\n     counts.\n\n  2. Let the user specify a for-each-ref format for tag and branch\n     listing output. Then the various levels of \"-v\" just become some\n     special format strings, and the user is free to ask for whatever\n     they want (or even have \"branch.defaultListFormat\" to get it\n     without typing over and over).\n\n-Peff\n"},{"id":"174242","messageId":"20110825175405.GD519@sigill.intra.peff.net","threadId":"27997","inReplyTo":"00847b8ee77129433a5d908ad25c9ebaf7fa7130.1314259226.git.git@drmicha.warpmail.net","subject":"Re: [PATCH 1/5] branch: allow pattern arguments","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-08-25T17:54:05Z","receivedAt":"2011-08-25T17:54:05Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Aug 25, 2011 at 10:30:17AM +0200, Michael J Gruber wrote:\n\n> -\telse if (argc == 0)\n> -\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n> +\telse if (argc == 0 || (verbose && argc == 1))\n> +\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit, argc ? argv[0] : NULL);\n\nNote that \"git tag -l\" takes multiple patterns these days (it used to\nsilently ignore everything after the first one!). \"git branch\" should\nprobably do the same.\n\n-Peff\n"},{"id":"174243","messageId":"7v7h61mks8.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"CACnwZYd=pM+fRNy0pqv+jR9bb0AWC89nkgHq3m1nMw9cUfHOQw@mail.gmail.com","subject":"Re: [RFC] branch: list branches by single remote","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-25T18:02:47Z","receivedAt":"2011-08-25T18:02:47Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thiago Farina <tfransosi@gmail.com> writes:\n\n> On Wed, Aug 24, 2011 at 3:34 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> [Footnote]\n>>\n>> *1* It does not have to be a weekly _posting_ on the list but can be a\n>> well-known Wiki page or even a bug tracker. Whatever medium is used for\n>> this purpose, there _must_ be a built-in mechanism to expire entries away\n>> that are inactive for more than some reasonable limit (say two to three\n>> weeks).\n>\n> Host the project on Google Code for bug tracking? Use rietveld for\n> code reviews (ike codereview.chromium.org and codereview.appspot.com)?\n\nIf any of the above expires entries by default unless explicit actions\nare taken, I am personally fine to go with it.\n"},{"id":"174246","messageId":"7vliuhl4us.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"20110825175405.GD519@sigill.intra.peff.net","subject":"Re: [PATCH 1/5] branch: allow pattern arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-25T18:32:11Z","receivedAt":"2011-08-25T18:32:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Thu, Aug 25, 2011 at 10:30:17AM +0200, Michael J Gruber wrote:\n>\n>> -\telse if (argc == 0)\n>> -\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n>> +\telse if (argc == 0 || (verbose && argc == 1))\n>> +\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit, argc ? argv[0] : NULL);\n>\n> Note that \"git tag -l\" takes multiple patterns these days (it used to\n> silently ignore everything after the first one!). \"git branch\" should\n> probably do the same.\n\nAgreed.\n"},{"id":"174247","messageId":"7vhb55l4qw.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"32d0954697da9ac96cc11af0d8cc1390d93fd037.1314259226.git.git@drmicha.warpmail.net","subject":"Re: [PATCH 2/5] branch: introduce --list argument","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-25T18:34:31Z","receivedAt":"2011-08-25T18:34:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Currently, there is no way to invoke the list mode with a pattern\n> because this is interpreted as branch creation.\n>\n> Introduce a --list argument which invokes the list mode.\n\nProbably this is --list \"option\", but I think this is a good idea to allow\n\"we are in list mode\" without having to invoke \"verbose\" output.\n"},{"id":"174250","messageId":"7v8vqhl3go.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"f471a616e4f08e729384138d8cb8afff4e9dbcbf.1314259226.git.git@drmicha.warpmail.net","subject":"Re: [PATCH 4/5] branch: restructure -v vs. -vv","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-25T19:02:15Z","receivedAt":"2011-08-25T19:02:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> ahead/behind info is expensive, upstream name info cheap. Therefore,\n> make -v output the upstream branch name and -vv add the ahead/behind\n> info.\n\nWhile I do not care too much about the end result, and I even suspect that\nswapping the meaning might be better at the semantic level, I do not agree\nwith the above line of reasoning. It is not based on what the end user\nwants at all, but is based on how easily you can produce results.\n\nIf a relatively expensive information is what is more often wanted and the\nusers are willing to pay the price to compute it, it is very reasonable to\nuse short-and-sweet -v for showing only that information, and have them\ntype -vv to ask for a less common information.\n\nI also suspect that \"ahead/behind\" and \"who-is-upstream\" may be orthogonal\nand we may not tie these to degree of verbosity. Jeff's suggestion to\nteach these to for-each-ref may be along a similar thought.\n\nYou however may be able to argue \"When the user wants A/B, s/he always\nwants who-is-upstream, and asking for A/B and not wanting who-is-upstream\nis insane\". If \"A/B\" does not make sense without seeing \"who-is-upstream\",\nbut if seeing \"who-is-upstream\" alone makes sense without seeing \"A/B\",\nthen you can argue that these two are indeed degrees of verbosity, and it\nmay be justifiable to make -v give \"who-is-upstream\", and make -vv give\n\"A/B and who-is-upstream\".\n\nBut I suspect that much more people have more than one topics cooking on\ntop of upstream (i.e. need for A/B) than people who work with these topics\nbased on different upstreams (i.e. need for \"who-is-upstream\"). People who\nbase their topics on only one upstream do not need \"who-is-upstream\" to\nunderstand A/B.\n\nI am wondering if \"branch -v=<comma separated tokens>\", where currently\navailable tokens are \"sha1\", \"upstream\", \"ahead/behind\", is the right way\nto keep these orthogonal and extensible (of course you would want a\nshorter mnemonic). Then existing -v and -vv can be understood as aliases\nto:\n\n\t-v   ===  -v=sha1,ahead/behind\n        -vv  ===  -v=sha1,upstream,ahead/behind\n\nand you can naturally extend the vocabulary with \"patchsame\" to define\nyour -vvv introduced in [5/5].\n"},{"id":"174254","messageId":"7vwre1jnmj.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"7vliuhl4us.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/5] branch: allow pattern arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-25T19:29:40Z","receivedAt":"2011-08-25T19:29:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Jeff King <peff@peff.net> writes:\n>\n>> On Thu, Aug 25, 2011 at 10:30:17AM +0200, Michael J Gruber wrote:\n>>\n>>> -\telse if (argc == 0)\n>>> -\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n>>> +\telse if (argc == 0 || (verbose && argc == 1))\n>>> +\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit, argc ? argv[0] : NULL);\n>>\n>> Note that \"git tag -l\" takes multiple patterns these days (it used to\n>> silently ignore everything after the first one!). \"git branch\" should\n>> probably do the same.\n>\n> Agreed.\n\n... and can be done without too much additional code.\n\nAn offtopic side note about naming:\n\nI called it \"const char **pattern\" not \"patterns\" and that is\ndeliberate. I find it natural to be able to call the 2nd pattern, counting\nfrom 0 as any CS person would, by spelling \"pattern[2]\". \"patterns[2]\"\nsounds as if I am have multiple sets of patterns and refering to the\nsecond set of patterns.\n\n builtin/branch.c |   25 +++++++++++++++++++------\n 1 files changed, 19 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 495bf2e..0fa62bd 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -260,10 +260,22 @@ static char *resolve_symref(const char *src, const char *prefix)\n \n struct append_ref_cb {\n \tstruct ref_list *ref_list;\n-\tconst char *pattern;\n+\tconst char **pattern;\n \tint ret;\n };\n \n+static int match_patterns(const char **pattern, const char *refname)\n+{\n+\tif (!*pattern)\n+\t\treturn 1; /* no pattern always matches */\n+\twhile (*pattern) {\n+\t\tif (!fnmatch(*pattern, refname, 0))\n+\t\t\treturn 1;\n+\t\tpattern++;\n+\t}\n+\treturn 0;\n+}\n+\n static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)\n {\n \tstruct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);\n@@ -298,7 +310,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n \tif ((kind & ref_list->kinds) == 0)\n \t\treturn 0;\n \n-\tif (cb->pattern && fnmatch(cb->pattern, refname, 0))\n+\tif (!match_patterns(cb->pattern, refname))\n \t\treturn 0;\n \n \tcommit = NULL;\n@@ -496,7 +508,7 @@ static void show_detached(struct ref_list *ref_list)\n \t}\n }\n \n-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char *pattern)\n+static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)\n {\n \tint i;\n \tstruct append_ref_cb cb;\n@@ -528,7 +540,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tqsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);\n \n \tdetached = (detached && (kinds & REF_LOCAL_BRANCH));\n-\tif (detached && (!pattern || !fnmatch(pattern, \"HEAD\", 0)))\n+\tif (detached && match_patterns(pattern, \"HEAD\"))\n \t\tshow_detached(&ref_list);\n \n \tfor (i = 0; i < ref_list.index; i++) {\n@@ -703,8 +715,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n-\telse if (argc == 0 || (verbose && argc == 1))\n-\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit, argc ? argv[0] : NULL);\n+\telse if (argc == 0 || (verbose && argc))\n+\t\treturn print_ref_list(kinds, detached, verbose, abbrev,\n+\t\t\t\t      with_commit, argv);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n \telse if (rename && (argc == 2))\n"},{"id":"174255","messageId":"7vmxexjmk6.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"32d0954697da9ac96cc11af0d8cc1390d93fd037.1314259226.git.git@drmicha.warpmail.net","subject":"Re: [PATCH 2/5] branch: introduce --list argument","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-25T19:52:41Z","receivedAt":"2011-08-25T19:52:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> @@ -695,12 +696,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n>  \n>  \targc = parse_options(argc, argv, prefix, options, builtin_branch_usage,\n>  \t\t\t     0);\n> -\tif (!!delete + !!rename + !!force_create > 1)\n> +\tif (!!delete + !!rename + !!force_create + !!list > 1)\n>  \t\tusage_with_options(builtin_branch_usage, options);\n>  \n> +\tif (argc == 0 || (verbose && argc == 1))\n> +\t\tlist = 1;\n> +\n\nI am afraid this is not quite right.\n\nWhat happens if one of delete/rename/force-create can take a single\nargument, or more importantly, if we someday gain another option that can\ntake zero or one argument and is incompatible with other operating mode?\n\nFor example, what happens to this command line with your \"git branch\":\n\n\t$ git branch -v -m boo\n\nThe first test passes (no explicit --list), and then you violate the \"only\none of these operating mode can be set\" assertion you made yourself by\nflipping list on, no?\n\nIt is a good practice to always run the defaulting tweak *before* checking\noptions that are mutually incompatible, to catch your own mistake in the\ntweaking code.\n\nOn top of my previous \"multiple patterns allowed\" tweak, a replacement\npatch to this file may look like this.  I suspect there should be a better\nway to represent the mode in a single variable and enforce that there is\nonly one chosen, but that is left for another day.\n\n builtin/branch.c |   12 +++++++++---\n 1 files changed, 9 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 0fa62bd..4243e7c 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -629,7 +629,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int\n \n int cmd_branch(int argc, const char **argv, const char *prefix)\n {\n-\tint delete = 0, rename = 0, force_create = 0;\n+\tint delete = 0, rename = 0, force_create = 0, list = 0;\n \tint verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;\n \tint reflog = 0;\n \tenum branch_track track;\n@@ -668,6 +668,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT('D', NULL, &delete, \"delete branch (even if not merged)\", 2),\n \t\tOPT_BIT('m', NULL, &rename, \"move/rename a branch and its reflog\", 1),\n \t\tOPT_BIT('M', NULL, &rename, \"move/rename a branch, even if target exists\", 2),\n+\t\tOPT_BOOLEAN(0, \"list\", &list, \"list branch names\"),\n \t\tOPT_BOOLEAN('l', NULL, &reflog, \"create the branch's reflog\"),\n \t\tOPT__FORCE(&force_create, \"force creation (when already exists)\"),\n \t\t{\n@@ -710,12 +711,17 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, prefix, options, builtin_branch_usage,\n \t\t\t     0);\n-\tif (!!delete + !!rename + !!force_create > 1)\n+\n+\tif (!delete && !rename && !force_create &&\n+\t    (argc == 0 || (verbose && argc)))\n+\t\tlist = 1;\n+\n+\tif (!!delete + !!rename + !!force_create + !!list > 1)\n \t\tusage_with_options(builtin_branch_usage, options);\n \n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n-\telse if (argc == 0 || (verbose && argc))\n+\telse if (list)\n \t\treturn print_ref_list(kinds, detached, verbose, abbrev,\n \t\t\t\t      with_commit, argv);\n \telse if (rename && (argc == 1))\n"},{"id":"174306","messageId":"4E5759B1.50705@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110825175301.GC519@sigill.intra.peff.net","subject":"Re: [PATCH 0/5] RFC: patterns for branch list","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-26T08:30:41Z","receivedAt":"2011-08-26T08:30:41Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 25.08.2011 19:53:\n> On Thu, Aug 25, 2011 at 10:30:16AM +0200, Michael J Gruber wrote:\n> \n>> This mini series is about introducing patterns to the list mode of\n>> 'git branch' much like the pattern for 'git tag -l'. There are several\n>> related things which are to be considered for the ui design:\n> \n>> [log vs tag vs branch]\n> \n> I agree that the ideal UI change would be to move git-branch's \"-l\" to\n> \"-g\", and make \"-l|--list\" work the same as it does for git-tag.\n> \n> Even though branch is generally considered a porcelain, I worry a little\n> about making that change. A script that wants to create a branch has no\n> real choice other than to use \"git branch\" (OK, they can use\n> \"update-ref\" themselves, but I seriously doubt that most scripts do so).\n> However, I kind of doubt anyone actually uses \"-l\"; it is mostly\n> pointless in the default config, so maybe it is safe.\n> \n> Searching google code for \"git.branch.*-l\" turns up only one hit, and it\n> is somebody who apparently thought that \"-l\" meant \"list\".\n\n;)\n\nThanks for doing the search.\n\n>> Analogous to \"git tag\", \"branch\" has several modes, one of which is list mode.\n>> It is currently activated (and possibly modified) by \"-v\" and \"-vv\", and when\n>> there are no arguments. So, at the least,\n>>\n>> git branch -v[v] <pattern>\n>>\n>> should match just like \"git tag -l <pattern>\" does. And that is what the first\n>> patch in my series does.\n> \n> The order of your patches seems backwards to me. You add\n> pattern-matching for \"-v\", but there is no way to get pattern-matching\n> for the non-verbose case. Shouldn't \"--list\" come first?\n> \n> Maybe I am just nitpicking, as I think the end result after the series\n> is the same. I just found the first patch very confusing.\n\nIt's an RFC series to revive the discussion about what to aim for.\nAgreement about \"--list\" seems to be growing, so a natural first patch\nwould introduce that.\n\n>> \"git tag\" should probably learn the same long option and others. And why not\n>> verify tags given by a pattern?\n> \n> Yeah, having them both do --list makes sense. Whether it is appropriate\n> to glob for other operations, I don't know. I think you'd have to\n> look at each operation individually.\n> \n>> Both \"tag\" and \"branch\" could activate list mode automatically on an invalid\n>> tag name rather than dieing:\n>>\n>> git tag v1.7.6\\*\n>> Warning: tag 'v1.7.6*' not found.\n>> v1.7.6\n>> v1.7.6-rc0\n>> v1.7.6-rc1\n>> v1.7.6-rc2\n>> v1.7.6-rc3\n>> v1.7.6.1\n> \n> That just seems confusing to me. What is the exit status? Shouldn't the\n> warning be \"error: tag 'v1.7.6*' is not a valid tag name\"?\n\nSure, and sorry, copied the wrong one. I'd just like to have the simple\nway to say \"git branch peff/\\*\" at least as long as we don't have \"-l\"\nfor \"--list\".\n\n>> -v[v] sanity\n>> ============\n>>\n>> '-v' and '-vv' both take considerable time (because they need to walk).\n>> It makes more sense to have '-v' display cheap output (upstream name)\n>> and '-vv' add expensive output (ahead/behind info). '-vvv' could add super\n>> expensive info (ahead/equivalent/behind a la cherry-mark).\n> \n> I think the original rationale was not so much \"how much time does it\n> take\", but rather \"how much space do you want each line to take on your\n> terminal\". For many people, the upstream name in \"-vv\" is just\n> cluttering noise.\n\nAccording to my experience, the ahead/behind computations take so much\ntime (in a git.git clone with my devel branches) that they render all\n\"-v\" versions unusable, unless I use a restrictive pattern.\n\nOn the other hand, I have branches based on all of origin/{master,next}\nand others, so having the upstream name is valuable.\n\nSeems that I'm an outlier, though.\n\n> Tag and branch listing are really just specialized versions of\n> for-each-ref. I wonder if it makes sense to do:\n> \n>   1. Teach for-each-ref formats replacement tokens for ahead/behind\n>      counts.\n> \n>   2. Let the user specify a for-each-ref format for tag and branch\n>      listing output. Then the various levels of \"-v\" just become some\n>      special format strings, and the user is free to ask for whatever\n>      they want (or even have \"branch.defaultListFormat\" to get it\n>      without typing over and over).\n\nfor-each-peff ;)\n\nFor a moment, the use of the walker in builtin/branch.c even tricked me\ninto thinking that it might not use for-each-ref at all. God forbid!\n\nI actually like the format suggestion. Then we only need to discuss the\ndefault format, which is hopefully less of a problem. But that is\nsomething for later, I'll discard the -v[v[v]] patches for now. Have we\nunified log formats and for-each-ref formats and parsers already, btw? I\nrecall some efforts.\n\nMichael\n"},{"id":"174315","messageId":"cover.1314367414.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110825175301.GC519@sigill.intra.peff.net","subject":"[PATCHv2 0/5] patterns for branch list","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-26T14:05:10Z","receivedAt":"2011-08-26T14:05:10Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"In this iteration, I have incorporated Jeffs and Junios suggestions and Junios\npatches. Thanks!\n\nSo:\n\ngit branch --list is introduced before the patterns (though it is not needed at\nthat point)\n\nMultiple patterns are allowed.\n\nThe -v/vv/vvv changing patches are gone.\n\nAlso, the independent test for \"-vv\" is put first (which certainly can go in\nnow).  Next come long option names for \"git tag\" and \"git branch\", then the\npattern related patches.\n\nI have also rebased on next with nk/branch-v-abbrev (which conflicts, though\n\"trivially\").\n\n\"-l -> -g\" migration for \"git branch\" and such are issues for a later series.\n\nMichael J Gruber (5):\n  t6040: test branch -vv\n  git-tag: introduce long forms for the options\n  git-branch: introduce missing long forms for the options\n  branch: introduce --list option\n  branch: allow pattern arguments\n\n Documentation/git-branch.txt |   20 +++++++++++++++--\n Documentation/git-tag.txt    |    8 +++++++\n builtin/branch.c             |   46 +++++++++++++++++++++++++++++++----------\n builtin/tag.c                |   16 +++++++-------\n t/t3203-branch-output.sh     |   24 +++++++++++++++++++++\n t/t6040-tracking-info.sh     |   16 ++++++++++++++\n 6 files changed, 108 insertions(+), 22 deletions(-)\n\n-- \n1.7.6.845.gc3c05\n"},{"id":"174314","messageId":"5632527678d4e5ab5d6e7890e6620e663aa7e484.1314367414.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110825175301.GC519@sigill.intra.peff.net","subject":"[PATCHv2 1/5] t6040: test branch -vv","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-26T14:05:11Z","receivedAt":"2011-08-26T14:05:11Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"t6040 has a test for 'git branch -v' but not for 'git branch -vv'.\nAdd one.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n t/t6040-tracking-info.sh |   16 ++++++++++++++++\n 1 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh\nindex 19de5b1..19272bc 100755\n--- a/t/t6040-tracking-info.sh\n+++ b/t/t6040-tracking-info.sh\n@@ -51,6 +51,22 @@ test_expect_success 'branch -v' '\n \ttest_i18ncmp expect actual\n '\n \n+cat >expect <<\\EOF\n+b1 origin/master: ahead 1, behind 1\n+b2 origin/master: ahead 1, behind 1\n+b3 origin/master: behind 1\n+b4 origin/master: ahead 2\n+EOF\n+\n+test_expect_success 'branch -vv' '\n+\t(\n+\t\tcd test &&\n+\t\tgit branch -vv\n+\t) |\n+\tsed -n -e \"$script\" >actual &&\n+\ttest_i18ncmp expect actual\n+'\n+\n test_expect_success 'checkout' '\n \t(\n \t\tcd test && git checkout b1\n-- \n1.7.6.845.gc3c05\n"},{"id":"174316","messageId":"f02e446227a93fff37591f1a866566e6220ce283.1314367414.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110825175301.GC519@sigill.intra.peff.net","subject":"[PATCHv2 2/5] git-tag: introduce long forms for the options","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-26T14:05:12Z","receivedAt":"2011-08-26T14:05:12Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Long forms are better to memoize, and more reliably uniform across\ncommands.\n\nDesign notes:\n\n-u,--local-user is named following the analogous gnupg option.\n\n-l,--list is not an argument taking option but a mode switch.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-tag.txt |    8 ++++++++\n builtin/tag.c             |   16 ++++++++--------\n 2 files changed, 16 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt\nindex fb1c0ac..c83cb13 100644\n--- a/Documentation/git-tag.txt\n+++ b/Documentation/git-tag.txt\n@@ -43,12 +43,15 @@ GnuPG key for signing.\n OPTIONS\n -------\n -a::\n+--annotate::\n \tMake an unsigned, annotated tag object\n \n -s::\n+--sign::\n \tMake a GPG-signed tag, using the default e-mail address's key\n \n -u <key-id>::\n+--local-user=<key-id>::\n \tMake a GPG-signed tag, using the given key\n \n -f::\n@@ -56,9 +59,11 @@ OPTIONS\n \tReplace an existing tag with the given name (instead of failing)\n \n -d::\n+--delete::\n \tDelete existing tags with the given names.\n \n -v::\n+--verify::\n \tVerify the gpg signature of the given tag names.\n \n -n<num>::\n@@ -69,6 +74,7 @@ OPTIONS\n \tIf the tag is not annotated, the commit message is displayed instead.\n \n -l <pattern>::\n+--list <pattern>::\n \tList tags with names that match the given pattern (or all if no\n \tpattern is given).  Running \"git tag\" without arguments also\n \tlists all tags. The pattern is a shell wildcard (i.e., matched\n@@ -79,6 +85,7 @@ OPTIONS\n \tOnly list tags which contain the specified commit.\n \n -m <msg>::\n+--message=<msg>::\n \tUse the given tag message (instead of prompting).\n \tIf multiple `-m` options are given, their values are\n \tconcatenated as separate paragraphs.\n@@ -86,6 +93,7 @@ OPTIONS\n \tis given.\n \n -F <file>::\n+--file=<file>::\n \tTake the tag message from the given file.  Use '-' to\n \tread the message from the standard input.\n \tImplies `-a` if none of `-a`, `-s`, or `-u <key-id>`\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 667515e..9d89616 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -429,21 +429,21 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \tstruct msg_arg msg = { 0, STRBUF_INIT };\n \tstruct commit_list *with_commit = NULL;\n \tstruct option options[] = {\n-\t\tOPT_BOOLEAN('l', NULL, &list, \"list tag names\"),\n+\t\tOPT_BOOLEAN('l', \"list\", &list, \"list tag names\"),\n \t\t{ OPTION_INTEGER, 'n', NULL, &lines, \"n\",\n \t\t\t\t\"print <n> lines of each tag message\",\n \t\t\t\tPARSE_OPT_OPTARG, NULL, 1 },\n-\t\tOPT_BOOLEAN('d', NULL, &delete, \"delete tags\"),\n-\t\tOPT_BOOLEAN('v', NULL, &verify, \"verify tags\"),\n+\t\tOPT_BOOLEAN('d', \"delete\", &delete, \"delete tags\"),\n+\t\tOPT_BOOLEAN('v', \"verify\", &verify, \"verify tags\"),\n \n \t\tOPT_GROUP(\"Tag creation options\"),\n-\t\tOPT_BOOLEAN('a', NULL, &annotate,\n+\t\tOPT_BOOLEAN('a', \"annotate\", &annotate,\n \t\t\t\t\t\"annotated tag, needs a message\"),\n-\t\tOPT_CALLBACK('m', NULL, &msg, \"message\",\n+\t\tOPT_CALLBACK('m', \"message\", &msg, \"message\",\n \t\t\t     \"tag message\", parse_msg_arg),\n-\t\tOPT_FILENAME('F', NULL, &msgfile, \"read message from file\"),\n-\t\tOPT_BOOLEAN('s', NULL, &sign, \"annotated and GPG-signed tag\"),\n-\t\tOPT_STRING('u', NULL, &keyid, \"key-id\",\n+\t\tOPT_FILENAME('F', \"file\", &msgfile, \"read message from file\"),\n+\t\tOPT_BOOLEAN('s', \"sign\", &sign, \"annotated and GPG-signed tag\"),\n+\t\tOPT_STRING('u', \"local-user\", &keyid, \"key-id\",\n \t\t\t\t\t\"use another key to sign the tag\"),\n \t\tOPT__FORCE(&force, \"replace the tag if exists\"),\n \n-- \n1.7.6.845.gc3c05\n"},{"id":"174319","messageId":"c79179fa3476629ce47556c219719495c213f5f9.1314367414.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110825175301.GC519@sigill.intra.peff.net","subject":"[PATCHv2 3/5] git-branch: introduce missing long forms for the options","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-26T14:05:13Z","receivedAt":"2011-08-26T14:05:13Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Long forms are better to memoize, and more reliably uniform across\ncommands.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\nI'm somewhat torn between --move and --rename for -m. We have no real precedent\nbesides \"git remote rename\".\n\nI left out -M and -D because I feel they should really be -m -f resp. -d -f.\n---\n Documentation/git-branch.txt |    5 +++++\n builtin/branch.c             |   10 +++++-----\n 2 files changed, 10 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 507b8d0..4c64ac9 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -64,6 +64,7 @@ way to clean up all obsolete remote-tracking branches.\n OPTIONS\n -------\n -d::\n+--delete::\n \tDelete a branch. The branch must be fully merged in its\n \tupstream branch, or in `HEAD` if no upstream was set with\n \t`--track` or `--set-upstream`.\n@@ -72,6 +73,7 @@ OPTIONS\n \tDelete a branch irrespective of its merged status.\n \n -l::\n+--create-reflog::\n \tCreate the branch's reflog.  This activates recording of\n \tall changes made to the branch ref, enabling use of date\n \tbased sha1 expressions such as \"<branchname>@\\{yesterday}\".\n@@ -84,6 +86,7 @@ OPTIONS\n \talready. Without `-f` 'git branch' refuses to change an existing branch.\n \n -m::\n+--move::\n \tMove/rename a branch and the corresponding reflog.\n \n -M::\n@@ -100,9 +103,11 @@ OPTIONS\n \tSame as `--color=never`.\n \n -r::\n+--remotes::\n \tList or delete (if used with -d) the remote-tracking branches.\n \n -a::\n+--all::\n \tList both remote-tracking branches and local branches.\n \n -v::\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex aa705a0..94e41ae 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -624,7 +624,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_SET_INT( 0, \"set-upstream\",  &track, \"change upstream info\",\n \t\t\tBRANCH_TRACK_OVERRIDE),\n \t\tOPT__COLOR(&branch_use_color, \"use colored output\"),\n-\t\tOPT_SET_INT('r', NULL,     &kinds, \"act on remote-tracking branches\",\n+\t\tOPT_SET_INT('r', \"remotes\",     &kinds, \"act on remote-tracking branches\",\n \t\t\tREF_REMOTE_BRANCH),\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"contains\", &with_commit, \"commit\",\n@@ -641,13 +641,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT__ABBREV(&abbrev),\n \n \t\tOPT_GROUP(\"Specific git-branch actions:\"),\n-\t\tOPT_SET_INT('a', NULL, &kinds, \"list both remote-tracking and local branches\",\n+\t\tOPT_SET_INT('a', \"all\", &kinds, \"list both remote-tracking and local branches\",\n \t\t\tREF_REMOTE_BRANCH | REF_LOCAL_BRANCH),\n-\t\tOPT_BIT('d', NULL, &delete, \"delete fully merged branch\", 1),\n+\t\tOPT_BIT('d', \"delete\", &delete, \"delete fully merged branch\", 1),\n \t\tOPT_BIT('D', NULL, &delete, \"delete branch (even if not merged)\", 2),\n-\t\tOPT_BIT('m', NULL, &rename, \"move/rename a branch and its reflog\", 1),\n+\t\tOPT_BIT('m', \"move\", &rename, \"move/rename a branch and its reflog\", 1),\n \t\tOPT_BIT('M', NULL, &rename, \"move/rename a branch, even if target exists\", 2),\n-\t\tOPT_BOOLEAN('l', NULL, &reflog, \"create the branch's reflog\"),\n+\t\tOPT_BOOLEAN('l', \"create-reflog\", &reflog, \"create the branch's reflog\"),\n \t\tOPT__FORCE(&force_create, \"force creation (when already exists)\"),\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"no-merged\", &merge_filter_ref,\n-- \n1.7.6.845.gc3c05\n"},{"id":"174317","messageId":"0785cac235c3b45537cf161c86dde8e798c4ff3e.1314367414.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110825175301.GC519@sigill.intra.peff.net","subject":"[PATCHv2 4/5] branch: introduce --list option","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-26T14:05:14Z","receivedAt":"2011-08-26T14:05:14Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Currently, there is no way to invoke the list mode explicitly.\nIntroduce a --list option which invokes the list mode. This will be\nbeneficial for invoking list mode with pattern matching, which otherwise\nwould be interpreted as branch creation.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |    9 +++++++--\n builtin/branch.c             |   12 +++++++++---\n t/t3203-branch-output.sh     |   14 ++++++++++++++\n 3 files changed, 30 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 4c64ac9..ac278fb 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git branch' [--color[=<when>] | --no-color] [-r | -a]\n-\t[-v [--abbrev=<length> | --no-abbrev]]\n+\t[--list] [-v [--abbrev=<length> | --no-abbrev]]\n \t[(--merged | --no-merged | --contains) [<commit>]]\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n@@ -20,7 +20,8 @@ DESCRIPTION\n \n With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n-branches to be listed, and option `-a` shows both.\n+branches to be listed, and option `-a` shows both. This list mode is also\n+activated by the `--list` and `-v` options (see below).\n \n With `--contains`, shows only the branches that contain the named commit\n (in other words, the branches whose tip commits are descendants of the\n@@ -110,11 +111,15 @@ OPTIONS\n --all::\n \tList both remote-tracking branches and local branches.\n \n+--list::\n+\tActivate the list mode.\n+\n -v::\n --verbose::\n \tShow sha1 and commit subject line for each head, along with\n \trelationship to upstream branch (if any). If given twice, print\n \tthe name of the upstream branch, as well.\n+\t`--list` is implied by all verbosity options.\n \n --abbrev=<length>::\n \tAlter the sha1's minimum display length in the output listing.\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 94e41ae..4a33b07 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -608,7 +608,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int\n \n int cmd_branch(int argc, const char **argv, const char *prefix)\n {\n-\tint delete = 0, rename = 0, force_create = 0;\n+\tint delete = 0, rename = 0, force_create = 0, list = 0;\n \tint verbose = 0, abbrev = -1, detached = 0;\n \tint reflog = 0;\n \tenum branch_track track;\n@@ -647,6 +647,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT('D', NULL, &delete, \"delete branch (even if not merged)\", 2),\n \t\tOPT_BIT('m', \"move\", &rename, \"move/rename a branch and its reflog\", 1),\n \t\tOPT_BIT('M', NULL, &rename, \"move/rename a branch, even if target exists\", 2),\n+\t\tOPT_BOOLEAN(0, \"list\", &list, \"list branch names\"),\n \t\tOPT_BOOLEAN('l', \"create-reflog\", &reflog, \"create the branch's reflog\"),\n \t\tOPT__FORCE(&force_create, \"force creation (when already exists)\"),\n \t\t{\n@@ -686,7 +687,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, prefix, options, builtin_branch_usage,\n \t\t\t     0);\n-\tif (!!delete + !!rename + !!force_create > 1)\n+\n+\tif (!delete && !rename && !force_create &&\n+\t    (argc == 0 || (verbose && argc)))\n+\t\tlist = 1;\n+\n+\tif (!!delete + !!rename + !!force_create + !!list > 1)\n \t\tusage_with_options(builtin_branch_usage, options);\n \n \tif (abbrev == -1)\n@@ -694,7 +700,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n-\telse if (argc == 0)\n+\telse if (list)\n \t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex 6b7c118..61e095c 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git branch --list shows local branches' '\n+\tgit branch --list >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+  branch-one\n+  branch-two\n+EOF\n+test_expect_success 'git branch --list pattern shows matching local branches' '\n+\tgit branch --list branch* >actual &&\n+\ttest_cmp expect actual\n+'\n+\n cat >expect <<'EOF'\n   origin/HEAD -> origin/branch-one\n   origin/branch-one\n-- \n1.7.6.845.gc3c05\n"},{"id":"174318","messageId":"b4a43ac3686d66b3ef8eddbed2c98c56b6f13312.1314367414.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110825175301.GC519@sigill.intra.peff.net","subject":"[PATCHv2 5/5] branch: allow pattern arguments","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-26T14:05:15Z","receivedAt":"2011-08-26T14:05:15Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Allow pattern arguments for the list mode just like for git tag -l.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |    8 ++++++--\n builtin/branch.c             |   24 +++++++++++++++++++++---\n t/t3203-branch-output.sh     |   10 ++++++++++\n 3 files changed, 37 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex ac278fb..2b8bc84 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n [verse]\n 'git branch' [--color[=<when>] | --no-color] [-r | -a]\n \t[--list] [-v [--abbrev=<length> | --no-abbrev]]\n-\t[(--merged | --no-merged | --contains) [<commit>]]\n+\t[(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n 'git branch' (-d | -D) [-r] <branchname>...\n@@ -22,6 +22,9 @@ With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n branches to be listed, and option `-a` shows both. This list mode is also\n activated by the `--list` and `-v` options (see below).\n+<pattern> restricts the output to matching branches, the pattern is a shell\n+wildcard (i.e., matched using fnmatch(3))\n+Multiple patterns may be given; if any of them matches, the tag is shown.\n \n With `--contains`, shows only the branches that contain the named commit\n (in other words, the branches whose tip commits are descendants of the\n@@ -112,7 +115,8 @@ OPTIONS\n \tList both remote-tracking branches and local branches.\n \n --list::\n-\tActivate the list mode.\n+\tActivate the list mode. `git branch <pattern>` would try to create a branch,\n+\tuse `git branch --list <pattern>` to list matching branches.\n \n -v::\n --verbose::\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 4a33b07..e6bef49 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -260,9 +260,22 @@ static char *resolve_symref(const char *src, const char *prefix)\n \n struct append_ref_cb {\n \tstruct ref_list *ref_list;\n+\tconst char **pattern;\n \tint ret;\n };\n \n+static int match_patterns(const char **pattern, const char *refname)\n+{\n+\tif (!*pattern)\n+\t\treturn 1; /* no pattern always matches */\n+\twhile (*pattern) {\n+\t\tif (!fnmatch(*pattern, refname, 0))\n+\t\t\treturn 1;\n+\t\tpattern++;\n+\t}\n+\treturn 0;\n+}\n+\n static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)\n {\n \tstruct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);\n@@ -297,6 +310,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n \tif ((kind & ref_list->kinds) == 0)\n \t\treturn 0;\n \n+\tif (!match_patterns(cb->pattern, refname))\n+\t\treturn 0;\n+\n \tcommit = NULL;\n \tif (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {\n \t\tcommit = lookup_commit_reference_gently(sha1, 1);\n@@ -492,7 +508,7 @@ static void show_detached(struct ref_list *ref_list)\n \t}\n }\n \n-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)\n+static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)\n {\n \tint i;\n \tstruct append_ref_cb cb;\n@@ -506,6 +522,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tif (merge_filter != NO_FILTER)\n \t\tinit_revisions(&ref_list.revs, NULL);\n \tcb.ref_list = &ref_list;\n+\tcb.pattern = pattern;\n \tcb.ret = 0;\n \tfor_each_rawref(append_ref, &cb);\n \tif (merge_filter != NO_FILTER) {\n@@ -523,7 +540,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tqsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);\n \n \tdetached = (detached && (kinds & REF_LOCAL_BRANCH));\n-\tif (detached)\n+\tif (detached && match_patterns(pattern, \"HEAD\"))\n \t\tshow_detached(&ref_list);\n \n \tfor (i = 0; i < ref_list.index; i++) {\n@@ -701,7 +718,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n \telse if (list)\n-\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n+\t\treturn print_ref_list(kinds, detached, verbose, abbrev,\n+\t\t\t\t      with_commit, argv);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n \telse if (rename && (argc == 2))\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex 61e095c..f2b294b 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -81,6 +81,16 @@ test_expect_success 'git branch -v shows branch summaries' '\n '\n \n cat >expect <<'EOF'\n+two\n+one\n+EOF\n+test_expect_success 'git branch -v pattern shows branch summaries' '\n+\tgit branch -v branch* >tmp &&\n+\tawk \"{print \\$NF}\" <tmp >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n * (no branch)\n   branch-one\n   branch-two\n-- \n1.7.6.845.gc3c05\n"},{"id":"174327","messageId":"7vwre0dsdy.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"4E5759B1.50705@drmicha.warpmail.net","subject":"Re: [PATCH 0/5] RFC: patterns for branch list","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-26T16:55:37Z","receivedAt":"2011-08-26T16:55:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Jeff King venit, vidit, dixit 25.08.2011 19:53:\n>> On Thu, Aug 25, 2011 at 10:30:16AM +0200, Michael J Gruber wrote:\n>> \n>>> Both \"tag\" and \"branch\" could activate list mode automatically on an invalid\n>>> tag name rather than dieing:\n>>>\n>>> git tag v1.7.6\\*\n>>> Warning: tag 'v1.7.6*' not found.\n\nIf it is not found, the usual action is create it, no?\n\n>>> v1.7.6\n>>> v1.7.6-rc0\n>>> v1.7.6-rc1\n>>> v1.7.6-rc2\n>>> v1.7.6-rc3\n>>> v1.7.6.1\n>> \n>> That just seems confusing to me. What is the exit status? Shouldn't the\n>> warning be \"error: tag 'v1.7.6*' is not a valid tag name\"?\n>\n> Sure, and sorry, copied the wrong one. I'd just like to have the simple\n> way to say \"git branch peff/\\*\" at least as long as we don't have \"-l\"\n> for \"--list\".\n\nAs we use fnmatch() and not match_pathspec() for this pattern matching,\n\"git branch peff/\" will not list all the topics under the peff/ hierarchy\n(your example \"git branch peff/\\*\" would be the way), but I would imagine\nthat we may someday want to update it to allow the leading path match\nhere. And at that point, distinction between\n\n\tgit branch peff  ;# to create a \"peff\" branch\n        git branch peff/ ;# to list \"peff/\" branches, as \"peff/\" itself is\n        \t\t ;# an invalid branch name and your auto listing\n                         ;# heuristic kicks in\n\nwhile it might be very useful for experts, becomes too subtle and would\nconfuse new people. We should instead require an explicit -l/--list, and\nnot use the auto listing heuristics (it is fine for -v to imply -l).\n"},{"id":"174328","messageId":"7vpqjsdrnp.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"f02e446227a93fff37591f1a866566e6220ce283.1314367414.git.git@drmicha.warpmail.net","subject":"Re: [PATCHv2 2/5] git-tag: introduce long forms for the options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-26T17:11:22Z","receivedAt":"2011-08-26T17:11:22Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Long forms are better to memoize, and more reliably uniform across\n> commands.\n\nI think people \"memorize\" and machines \"memoize\"; machines will do so just\nfine without long forms, but I think you are talking about helping people.\n\nThe part after \", and\" lacks a verb, making it a non-sentence.\n\n> Design notes:\n>\n> -u,--local-user is named following the analogous gnupg option.\n>\n> -l,--list is not an argument taking option but a mode switch.\n\nOk.\n\nThe remainder looks good. Thanks.\n"},{"id":"174331","messageId":"7vk4a0drjj.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"c79179fa3476629ce47556c219719495c213f5f9.1314367414.git.git@drmicha.warpmail.net","subject":"Re: [PATCHv2 3/5] git-branch: introduce missing long forms for the options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-26T17:13:52Z","receivedAt":"2011-08-26T17:13:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> @@ -100,9 +103,11 @@ OPTIONS\n>  \tSame as `--color=never`.\n>  \n>  -r::\n> +--remotes::\n>  \tList or delete (if used with -d) the remote-tracking branches.\n\nI am not sure if this should be \"--remoteS\".\n"},{"id":"174332","messageId":"7vfwkodq5s.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"0785cac235c3b45537cf161c86dde8e798c4ff3e.1314367414.git.git@drmicha.warpmail.net","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-26T17:43:43Z","receivedAt":"2011-08-26T17:43:43Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Currently, there is no way to invoke the list mode explicitly.\n\n..., without giving -v to force verbose output.\n\n> Introduce a --list option which invokes the list mode. This will be\n> beneficial for invoking list mode with pattern matching, which otherwise\n> would be interpreted as branch creation.\n>\n> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n> ---\n\n> @@ -20,7 +20,8 @@ DESCRIPTION\n>  \n>  With no arguments, existing branches are listed and the current branch will\n>  be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n> -branches to be listed, and option `-a` shows both.\n> +branches to be listed, and option `-a` shows both. This list mode is also\n> +activated by the `--list` and `-v` options (see below).\n\nVery good to mention \"and -v\" here ;-)\n\n> diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\n> index 6b7c118..61e095c 100755\n> --- a/t/t3203-branch-output.sh\n> +++ b/t/t3203-branch-output.sh\n> @@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' '\n>  \ttest_cmp expect actual\n>  '\n>  \n> +test_expect_success 'git branch --list shows local branches' '\n> +\tgit branch --list >actual &&\n> +\ttest_cmp expect actual\n> +'\n> +\n> +cat >expect <<'EOF'\n> +  branch-one\n> +  branch-two\n> +EOF\n> +test_expect_success 'git branch --list pattern shows matching local branches' '\n> +\tgit branch --list branch* >actual &&\n> +\ttest_cmp expect actual\n> +'\n> +\n\nCould we have a test to check the code you updated to sanity check the\ncombination of options as well? I suspect the reason your initial round\nbotched the \"branch -v -m foo\" without realizing may be because we do not\ncover the error checking.\n"},{"id":"174337","messageId":"7vzkiwc8r4.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"b4a43ac3686d66b3ef8eddbed2c98c56b6f13312.1314367414.git.git@drmicha.warpmail.net","subject":"Re: [PATCHv2 5/5] branch: allow pattern arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-26T18:45:03Z","receivedAt":"2011-08-26T18:45:03Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This and [4/5] both looked good; will update mg/branch-list with this\nround.\n\nThanks.\n\n\n \n"},{"id":"174421","messageId":"4E5A4AC2.5000908@drmicha.warpmail.net","threadId":"27997","inReplyTo":"7vpqjsdrnp.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 2/5] git-tag: introduce long forms for the options","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-28T14:03:46Z","receivedAt":"2011-08-28T14:03:46Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 26.08.2011 19:11:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n> \n>> Long forms are better to memoize, and more reliably uniform across\n>> commands.\n> \n> I think people \"memorize\" and machines \"memoize\"; machines will do so just\n> fine without long forms, but I think you are talking about helping people.\n\nYep.\n\n> The part after \", and\" lacks a verb, making it a non-sentence.\n\nThey are better to memorize, and they are more reliably uniform... Maybe\ndrop the comma?\n\n> \n>> Design notes:\n>>\n>> -u,--local-user is named following the analogous gnupg option.\n>>\n>> -l,--list is not an argument taking option but a mode switch.\n> \n> Ok.\n> \n> The remainder looks good. Thanks.\n"},{"id":"174422","messageId":"4E5A4B31.80402@drmicha.warpmail.net","threadId":"27997","inReplyTo":"7vk4a0drjj.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 3/5] git-branch: introduce missing long forms for the options","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-28T14:05:37Z","receivedAt":"2011-08-28T14:05:37Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 26.08.2011 19:13:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n> \n>> @@ -100,9 +103,11 @@ OPTIONS\n>>  \tSame as `--color=never`.\n>>  \n>>  -r::\n>> +--remotes::\n>>  \tList or delete (if used with -d) the remote-tracking branches.\n> \n> I am not sure if this should be \"--remoteS\".\n\nlike \"git log --remotes\".\n"},{"id":"174423","messageId":"4E5A5290.4050005@drmicha.warpmail.net","threadId":"27997","inReplyTo":"7vfwkodq5s.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-28T14:37:04Z","receivedAt":"2011-08-28T14:37:04Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 26.08.2011 19:43:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n> \n>> Currently, there is no way to invoke the list mode explicitly.\n> \n> ..., without giving -v to force verbose output.\n> \n>> Introduce a --list option which invokes the list mode. This will be\n>> beneficial for invoking list mode with pattern matching, which otherwise\n>> would be interpreted as branch creation.\n>>\n>> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n>> ---\n> \n>> @@ -20,7 +20,8 @@ DESCRIPTION\n>>  \n>>  With no arguments, existing branches are listed and the current branch will\n>>  be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n>> -branches to be listed, and option `-a` shows both.\n>> +branches to be listed, and option `-a` shows both. This list mode is also\n>> +activated by the `--list` and `-v` options (see below).\n> \n> Very good to mention \"and -v\" here ;-)\n> \n>> diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\n>> index 6b7c118..61e095c 100755\n>> --- a/t/t3203-branch-output.sh\n>> +++ b/t/t3203-branch-output.sh\n>> @@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' '\n>>  \ttest_cmp expect actual\n>>  '\n>>  \n>> +test_expect_success 'git branch --list shows local branches' '\n>> +\tgit branch --list >actual &&\n>> +\ttest_cmp expect actual\n>> +'\n>> +\n>> +cat >expect <<'EOF'\n>> +  branch-one\n>> +  branch-two\n>> +EOF\n>> +test_expect_success 'git branch --list pattern shows matching local branches' '\n>> +\tgit branch --list branch* >actual &&\n>> +\ttest_cmp expect actual\n>> +'\n>> +\n> \n> Could we have a test to check the code you updated to sanity check the\n> combination of options as well? I suspect the reason your initial round\n> botched the \"branch -v -m foo\" without realizing may be because we do not\n> cover the error checking.\n\nCurrently, \"-m -d\" is forbidden\", but \"-m -v\" is \"-m\", same for \"-d -v\".\nDo we want to keep it like that? Probably. I'll add the tests to 4/5.\n\nMichael\n"},{"id":"174415","messageId":"cover.1314543252.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"cover.1314367414.git.git@drmicha.warpmail.net","subject":"[PATCHv3 0/5] patterns for branch list","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-28T14:54:27Z","receivedAt":"2011-08-28T14:54:27Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"v3 has reworded commit messages for 2,3,4 and tests for combinations\nof branch options in 4, as suggested.\n\nNo code changes (besides the additional tests in 4).\n\nMichael J Gruber (5):\n  t6040: test branch -vv\n  git-tag: introduce long forms for the options\n  git-branch: introduce missing long forms for the options\n  branch: introduce --list option\n  branch: allow pattern arguments\n\n Documentation/git-branch.txt |   20 +++++++++++++++--\n Documentation/git-tag.txt    |    8 +++++++\n builtin/branch.c             |   46 +++++++++++++++++++++++++++++++----------\n builtin/tag.c                |   16 +++++++-------\n t/t3200-branch.sh            |   32 +++++++++++++++++++++++++++++\n t/t3203-branch-output.sh     |   24 +++++++++++++++++++++\n t/t6040-tracking-info.sh     |   16 ++++++++++++++\n 7 files changed, 140 insertions(+), 22 deletions(-)\n\n-- \n1.7.6.845.gc3c05\n"},{"id":"174416","messageId":"5632527678d4e5ab5d6e7890e6620e663aa7e484.1314543252.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"cover.1314367414.git.git@drmicha.warpmail.net","subject":"[PATCHv3 1/5] t6040: test branch -vv","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-28T14:54:28Z","receivedAt":"2011-08-28T14:54:28Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"t6040 has a test for 'git branch -v' but not for 'git branch -vv'.\nAdd one.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n t/t6040-tracking-info.sh |   16 ++++++++++++++++\n 1 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh\nindex 19de5b1..19272bc 100755\n--- a/t/t6040-tracking-info.sh\n+++ b/t/t6040-tracking-info.sh\n@@ -51,6 +51,22 @@ test_expect_success 'branch -v' '\n \ttest_i18ncmp expect actual\n '\n \n+cat >expect <<\\EOF\n+b1 origin/master: ahead 1, behind 1\n+b2 origin/master: ahead 1, behind 1\n+b3 origin/master: behind 1\n+b4 origin/master: ahead 2\n+EOF\n+\n+test_expect_success 'branch -vv' '\n+\t(\n+\t\tcd test &&\n+\t\tgit branch -vv\n+\t) |\n+\tsed -n -e \"$script\" >actual &&\n+\ttest_i18ncmp expect actual\n+'\n+\n test_expect_success 'checkout' '\n \t(\n \t\tcd test && git checkout b1\n-- \n1.7.6.845.gc3c05\n"},{"id":"174417","messageId":"8968164b516a8d7c90cd7fef1c3b12c0e34b21a4.1314543252.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"cover.1314367414.git.git@drmicha.warpmail.net","subject":"[PATCHv3 2/5] git-tag: introduce long forms for the options","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-28T14:54:29Z","receivedAt":"2011-08-28T14:54:29Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Long forms are better to memorize and more reliably uniform across\ncommands.\n\nDesign notes:\n\n-u,--local-user is named following the analogous gnupg option.\n\n-l,--list is not an argument taking option but a mode switch.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-tag.txt |    8 ++++++++\n builtin/tag.c             |   16 ++++++++--------\n 2 files changed, 16 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt\nindex fb1c0ac..c83cb13 100644\n--- a/Documentation/git-tag.txt\n+++ b/Documentation/git-tag.txt\n@@ -43,12 +43,15 @@ GnuPG key for signing.\n OPTIONS\n -------\n -a::\n+--annotate::\n \tMake an unsigned, annotated tag object\n \n -s::\n+--sign::\n \tMake a GPG-signed tag, using the default e-mail address's key\n \n -u <key-id>::\n+--local-user=<key-id>::\n \tMake a GPG-signed tag, using the given key\n \n -f::\n@@ -56,9 +59,11 @@ OPTIONS\n \tReplace an existing tag with the given name (instead of failing)\n \n -d::\n+--delete::\n \tDelete existing tags with the given names.\n \n -v::\n+--verify::\n \tVerify the gpg signature of the given tag names.\n \n -n<num>::\n@@ -69,6 +74,7 @@ OPTIONS\n \tIf the tag is not annotated, the commit message is displayed instead.\n \n -l <pattern>::\n+--list <pattern>::\n \tList tags with names that match the given pattern (or all if no\n \tpattern is given).  Running \"git tag\" without arguments also\n \tlists all tags. The pattern is a shell wildcard (i.e., matched\n@@ -79,6 +85,7 @@ OPTIONS\n \tOnly list tags which contain the specified commit.\n \n -m <msg>::\n+--message=<msg>::\n \tUse the given tag message (instead of prompting).\n \tIf multiple `-m` options are given, their values are\n \tconcatenated as separate paragraphs.\n@@ -86,6 +93,7 @@ OPTIONS\n \tis given.\n \n -F <file>::\n+--file=<file>::\n \tTake the tag message from the given file.  Use '-' to\n \tread the message from the standard input.\n \tImplies `-a` if none of `-a`, `-s`, or `-u <key-id>`\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 667515e..9d89616 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -429,21 +429,21 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \tstruct msg_arg msg = { 0, STRBUF_INIT };\n \tstruct commit_list *with_commit = NULL;\n \tstruct option options[] = {\n-\t\tOPT_BOOLEAN('l', NULL, &list, \"list tag names\"),\n+\t\tOPT_BOOLEAN('l', \"list\", &list, \"list tag names\"),\n \t\t{ OPTION_INTEGER, 'n', NULL, &lines, \"n\",\n \t\t\t\t\"print <n> lines of each tag message\",\n \t\t\t\tPARSE_OPT_OPTARG, NULL, 1 },\n-\t\tOPT_BOOLEAN('d', NULL, &delete, \"delete tags\"),\n-\t\tOPT_BOOLEAN('v', NULL, &verify, \"verify tags\"),\n+\t\tOPT_BOOLEAN('d', \"delete\", &delete, \"delete tags\"),\n+\t\tOPT_BOOLEAN('v', \"verify\", &verify, \"verify tags\"),\n \n \t\tOPT_GROUP(\"Tag creation options\"),\n-\t\tOPT_BOOLEAN('a', NULL, &annotate,\n+\t\tOPT_BOOLEAN('a', \"annotate\", &annotate,\n \t\t\t\t\t\"annotated tag, needs a message\"),\n-\t\tOPT_CALLBACK('m', NULL, &msg, \"message\",\n+\t\tOPT_CALLBACK('m', \"message\", &msg, \"message\",\n \t\t\t     \"tag message\", parse_msg_arg),\n-\t\tOPT_FILENAME('F', NULL, &msgfile, \"read message from file\"),\n-\t\tOPT_BOOLEAN('s', NULL, &sign, \"annotated and GPG-signed tag\"),\n-\t\tOPT_STRING('u', NULL, &keyid, \"key-id\",\n+\t\tOPT_FILENAME('F', \"file\", &msgfile, \"read message from file\"),\n+\t\tOPT_BOOLEAN('s', \"sign\", &sign, \"annotated and GPG-signed tag\"),\n+\t\tOPT_STRING('u', \"local-user\", &keyid, \"key-id\",\n \t\t\t\t\t\"use another key to sign the tag\"),\n \t\tOPT__FORCE(&force, \"replace the tag if exists\"),\n \n-- \n1.7.6.845.gc3c05\n"},{"id":"174419","messageId":"fd5a9fe2fba27100a15136717dddccb54eb0b674.1314543252.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"cover.1314367414.git.git@drmicha.warpmail.net","subject":"[PATCHv3 3/5] git-branch: introduce missing long forms for the options","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-28T14:54:30Z","receivedAt":"2011-08-28T14:54:30Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Long forms are better to memorize and more reliably uniform across\ncommands.\n\nNames follow precedents, e.g. \"git log --remotes\".\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\nI'm somewhat torn between --move and --rename for -m. We have no real precedent\nbesides \"git remote rename\".\n\nI left out -M and -D because I feel they should really be -m -f resp. -d -f.\n---\n Documentation/git-branch.txt |    5 +++++\n builtin/branch.c             |   10 +++++-----\n 2 files changed, 10 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 507b8d0..4c64ac9 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -64,6 +64,7 @@ way to clean up all obsolete remote-tracking branches.\n OPTIONS\n -------\n -d::\n+--delete::\n \tDelete a branch. The branch must be fully merged in its\n \tupstream branch, or in `HEAD` if no upstream was set with\n \t`--track` or `--set-upstream`.\n@@ -72,6 +73,7 @@ OPTIONS\n \tDelete a branch irrespective of its merged status.\n \n -l::\n+--create-reflog::\n \tCreate the branch's reflog.  This activates recording of\n \tall changes made to the branch ref, enabling use of date\n \tbased sha1 expressions such as \"<branchname>@\\{yesterday}\".\n@@ -84,6 +86,7 @@ OPTIONS\n \talready. Without `-f` 'git branch' refuses to change an existing branch.\n \n -m::\n+--move::\n \tMove/rename a branch and the corresponding reflog.\n \n -M::\n@@ -100,9 +103,11 @@ OPTIONS\n \tSame as `--color=never`.\n \n -r::\n+--remotes::\n \tList or delete (if used with -d) the remote-tracking branches.\n \n -a::\n+--all::\n \tList both remote-tracking branches and local branches.\n \n -v::\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex aa705a0..94e41ae 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -624,7 +624,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_SET_INT( 0, \"set-upstream\",  &track, \"change upstream info\",\n \t\t\tBRANCH_TRACK_OVERRIDE),\n \t\tOPT__COLOR(&branch_use_color, \"use colored output\"),\n-\t\tOPT_SET_INT('r', NULL,     &kinds, \"act on remote-tracking branches\",\n+\t\tOPT_SET_INT('r', \"remotes\",     &kinds, \"act on remote-tracking branches\",\n \t\t\tREF_REMOTE_BRANCH),\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"contains\", &with_commit, \"commit\",\n@@ -641,13 +641,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT__ABBREV(&abbrev),\n \n \t\tOPT_GROUP(\"Specific git-branch actions:\"),\n-\t\tOPT_SET_INT('a', NULL, &kinds, \"list both remote-tracking and local branches\",\n+\t\tOPT_SET_INT('a', \"all\", &kinds, \"list both remote-tracking and local branches\",\n \t\t\tREF_REMOTE_BRANCH | REF_LOCAL_BRANCH),\n-\t\tOPT_BIT('d', NULL, &delete, \"delete fully merged branch\", 1),\n+\t\tOPT_BIT('d', \"delete\", &delete, \"delete fully merged branch\", 1),\n \t\tOPT_BIT('D', NULL, &delete, \"delete branch (even if not merged)\", 2),\n-\t\tOPT_BIT('m', NULL, &rename, \"move/rename a branch and its reflog\", 1),\n+\t\tOPT_BIT('m', \"move\", &rename, \"move/rename a branch and its reflog\", 1),\n \t\tOPT_BIT('M', NULL, &rename, \"move/rename a branch, even if target exists\", 2),\n-\t\tOPT_BOOLEAN('l', NULL, &reflog, \"create the branch's reflog\"),\n+\t\tOPT_BOOLEAN('l', \"create-reflog\", &reflog, \"create the branch's reflog\"),\n \t\tOPT__FORCE(&force_create, \"force creation (when already exists)\"),\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"no-merged\", &merge_filter_ref,\n-- \n1.7.6.845.gc3c05\n"},{"id":"174418","messageId":"05a1a73e0b942dd94dd091c233be964fa19dfc6a.1314543252.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"cover.1314367414.git.git@drmicha.warpmail.net","subject":"[PATCHv3 4/5] branch: introduce --list option","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-28T14:54:31Z","receivedAt":"2011-08-28T14:54:31Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Currently, there is no way to invoke the list mode explicitly, without\ngiving -v to force verbose output.\n\nIntroduce a --list option which invokes the list mode. This will be\nbeneficial for invoking list mode with pattern matching, which otherwise\nwould be interpreted as branch creation.\n\nAlong with --list, test also combinations of existing options.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |    9 +++++++--\n builtin/branch.c             |   12 +++++++++---\n t/t3200-branch.sh            |   32 ++++++++++++++++++++++++++++++++\n t/t3203-branch-output.sh     |   14 ++++++++++++++\n 4 files changed, 62 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 4c64ac9..ac278fb 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git branch' [--color[=<when>] | --no-color] [-r | -a]\n-\t[-v [--abbrev=<length> | --no-abbrev]]\n+\t[--list] [-v [--abbrev=<length> | --no-abbrev]]\n \t[(--merged | --no-merged | --contains) [<commit>]]\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n@@ -20,7 +20,8 @@ DESCRIPTION\n \n With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n-branches to be listed, and option `-a` shows both.\n+branches to be listed, and option `-a` shows both. This list mode is also\n+activated by the `--list` and `-v` options (see below).\n \n With `--contains`, shows only the branches that contain the named commit\n (in other words, the branches whose tip commits are descendants of the\n@@ -110,11 +111,15 @@ OPTIONS\n --all::\n \tList both remote-tracking branches and local branches.\n \n+--list::\n+\tActivate the list mode.\n+\n -v::\n --verbose::\n \tShow sha1 and commit subject line for each head, along with\n \trelationship to upstream branch (if any). If given twice, print\n \tthe name of the upstream branch, as well.\n+\t`--list` is implied by all verbosity options.\n \n --abbrev=<length>::\n \tAlter the sha1's minimum display length in the output listing.\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 94e41ae..4a33b07 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -608,7 +608,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int\n \n int cmd_branch(int argc, const char **argv, const char *prefix)\n {\n-\tint delete = 0, rename = 0, force_create = 0;\n+\tint delete = 0, rename = 0, force_create = 0, list = 0;\n \tint verbose = 0, abbrev = -1, detached = 0;\n \tint reflog = 0;\n \tenum branch_track track;\n@@ -647,6 +647,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT('D', NULL, &delete, \"delete branch (even if not merged)\", 2),\n \t\tOPT_BIT('m', \"move\", &rename, \"move/rename a branch and its reflog\", 1),\n \t\tOPT_BIT('M', NULL, &rename, \"move/rename a branch, even if target exists\", 2),\n+\t\tOPT_BOOLEAN(0, \"list\", &list, \"list branch names\"),\n \t\tOPT_BOOLEAN('l', \"create-reflog\", &reflog, \"create the branch's reflog\"),\n \t\tOPT__FORCE(&force_create, \"force creation (when already exists)\"),\n \t\t{\n@@ -686,7 +687,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, prefix, options, builtin_branch_usage,\n \t\t\t     0);\n-\tif (!!delete + !!rename + !!force_create > 1)\n+\n+\tif (!delete && !rename && !force_create &&\n+\t    (argc == 0 || (verbose && argc)))\n+\t\tlist = 1;\n+\n+\tif (!!delete + !!rename + !!force_create + !!list > 1)\n \t\tusage_with_options(builtin_branch_usage, options);\n \n \tif (abbrev == -1)\n@@ -694,7 +700,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n-\telse if (argc == 0)\n+\telse if (list)\n \t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex cb6458d..931373c 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -98,6 +98,38 @@ test_expect_success 'git branch -m q r/q should fail when r exists' '\n \ttest_must_fail git branch -m q r/q\n '\n \n+test_expect_success 'git branch -v -d t should work' '\n+\tgit branch t &&\n+\ttest .git/refs/heads/t &&\n+\tgit branch -v -d t &&\n+\ttest ! -f .git/refs/heads/t\n+'\n+\n+test_expect_success 'git branch -v -m t s should work' '\n+\tgit branch t &&\n+\ttest .git/refs/heads/t &&\n+\tgit branch -v -m t s &&\n+\ttest ! -f .git/refs/heads/t &&\n+\ttest -f .git/refs/heads/s &&\n+\tgit branch -d s\n+'\n+\n+test_expect_success 'git branch -m -d t s should fail' '\n+\tgit branch t &&\n+\ttest .git/refs/heads/t &&\n+\ttest_must_fail git branch -m -d t s &&\n+\tgit branch -d t &&\n+\ttest ! -f .git/refs/heads/t\n+'\n+\n+test_expect_success 'git branch --list -d t should fail' '\n+\tgit branch t &&\n+\ttest .git/refs/heads/t &&\n+\ttest_must_fail git branch --list -d t &&\n+\tgit branch -d t &&\n+\ttest ! -f .git/refs/heads/t\n+'\n+\n test_expect_success 'git branch -M foo bar should fail when bar is checked out' '\n \tgit branch bar &&\n \tgit checkout -b foo &&\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex 6b7c118..61e095c 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git branch --list shows local branches' '\n+\tgit branch --list >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+  branch-one\n+  branch-two\n+EOF\n+test_expect_success 'git branch --list pattern shows matching local branches' '\n+\tgit branch --list branch* >actual &&\n+\ttest_cmp expect actual\n+'\n+\n cat >expect <<'EOF'\n   origin/HEAD -> origin/branch-one\n   origin/branch-one\n-- \n1.7.6.845.gc3c05\n"},{"id":"174420","messageId":"0c487086643fbf0334140365f20fef62242b7dac.1314543252.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"cover.1314367414.git.git@drmicha.warpmail.net","subject":"[PATCHv3 5/5] branch: allow pattern arguments","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-28T14:54:32Z","receivedAt":"2011-08-28T14:54:32Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Allow pattern arguments for the list mode just like for git tag -l.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |    8 ++++++--\n builtin/branch.c             |   24 +++++++++++++++++++++---\n t/t3203-branch-output.sh     |   10 ++++++++++\n 3 files changed, 37 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex ac278fb..2b8bc84 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n [verse]\n 'git branch' [--color[=<when>] | --no-color] [-r | -a]\n \t[--list] [-v [--abbrev=<length> | --no-abbrev]]\n-\t[(--merged | --no-merged | --contains) [<commit>]]\n+\t[(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n 'git branch' (-d | -D) [-r] <branchname>...\n@@ -22,6 +22,9 @@ With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n branches to be listed, and option `-a` shows both. This list mode is also\n activated by the `--list` and `-v` options (see below).\n+<pattern> restricts the output to matching branches, the pattern is a shell\n+wildcard (i.e., matched using fnmatch(3))\n+Multiple patterns may be given; if any of them matches, the tag is shown.\n \n With `--contains`, shows only the branches that contain the named commit\n (in other words, the branches whose tip commits are descendants of the\n@@ -112,7 +115,8 @@ OPTIONS\n \tList both remote-tracking branches and local branches.\n \n --list::\n-\tActivate the list mode.\n+\tActivate the list mode. `git branch <pattern>` would try to create a branch,\n+\tuse `git branch --list <pattern>` to list matching branches.\n \n -v::\n --verbose::\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 4a33b07..e6bef49 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -260,9 +260,22 @@ static char *resolve_symref(const char *src, const char *prefix)\n \n struct append_ref_cb {\n \tstruct ref_list *ref_list;\n+\tconst char **pattern;\n \tint ret;\n };\n \n+static int match_patterns(const char **pattern, const char *refname)\n+{\n+\tif (!*pattern)\n+\t\treturn 1; /* no pattern always matches */\n+\twhile (*pattern) {\n+\t\tif (!fnmatch(*pattern, refname, 0))\n+\t\t\treturn 1;\n+\t\tpattern++;\n+\t}\n+\treturn 0;\n+}\n+\n static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)\n {\n \tstruct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);\n@@ -297,6 +310,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n \tif ((kind & ref_list->kinds) == 0)\n \t\treturn 0;\n \n+\tif (!match_patterns(cb->pattern, refname))\n+\t\treturn 0;\n+\n \tcommit = NULL;\n \tif (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {\n \t\tcommit = lookup_commit_reference_gently(sha1, 1);\n@@ -492,7 +508,7 @@ static void show_detached(struct ref_list *ref_list)\n \t}\n }\n \n-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)\n+static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)\n {\n \tint i;\n \tstruct append_ref_cb cb;\n@@ -506,6 +522,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tif (merge_filter != NO_FILTER)\n \t\tinit_revisions(&ref_list.revs, NULL);\n \tcb.ref_list = &ref_list;\n+\tcb.pattern = pattern;\n \tcb.ret = 0;\n \tfor_each_rawref(append_ref, &cb);\n \tif (merge_filter != NO_FILTER) {\n@@ -523,7 +540,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tqsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);\n \n \tdetached = (detached && (kinds & REF_LOCAL_BRANCH));\n-\tif (detached)\n+\tif (detached && match_patterns(pattern, \"HEAD\"))\n \t\tshow_detached(&ref_list);\n \n \tfor (i = 0; i < ref_list.index; i++) {\n@@ -701,7 +718,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n \telse if (list)\n-\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n+\t\treturn print_ref_list(kinds, detached, verbose, abbrev,\n+\t\t\t\t      with_commit, argv);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n \telse if (rename && (argc == 2))\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex 61e095c..f2b294b 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -81,6 +81,16 @@ test_expect_success 'git branch -v shows branch summaries' '\n '\n \n cat >expect <<'EOF'\n+two\n+one\n+EOF\n+test_expect_success 'git branch -v pattern shows branch summaries' '\n+\tgit branch -v branch* >tmp &&\n+\tawk \"{print \\$NF}\" <tmp >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n * (no branch)\n   branch-one\n   branch-two\n-- \n1.7.6.845.gc3c05\n"},{"id":"174443","messageId":"7v8vqc92yp.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"05a1a73e0b942dd94dd091c233be964fa19dfc6a.1314543252.git.git@drmicha.warpmail.net","subject":"Re: [PATCHv3 4/5] branch: introduce --list option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-29T05:55:10Z","receivedAt":"2011-08-29T05:55:10Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> +test_expect_success 'git branch --list shows local branches' '\n> +\tgit branch --list >actual &&\n> +\ttest_cmp expect actual\n> +'\n> +\n> +cat >expect <<'EOF'\n> +  branch-one\n> +  branch-two\n> +EOF\n> +test_expect_success 'git branch --list pattern shows matching local branches' '\n> +\tgit branch --list branch* >actual &&\n> +\ttest_cmp expect actual\n> +'\n\nDoes this one exclude the \"* master\" entry at this stage in the series?\n"},{"id":"174447","messageId":"4E5B3317.7000207@drmicha.warpmail.net","threadId":"27997","inReplyTo":"7v8vqc92yp.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv3 4/5] branch: introduce --list option","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-08-29T06:35:03Z","receivedAt":"2011-08-29T06:35:03Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 29.08.2011 07:55:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n> \n>> +test_expect_success 'git branch --list shows local branches' '\n>> +\tgit branch --list >actual &&\n>> +\ttest_cmp expect actual\n>> +'\n>> +\n>> +cat >expect <<'EOF'\n>> +  branch-one\n>> +  branch-two\n>> +EOF\n>> +test_expect_success 'git branch --list pattern shows matching local branches' '\n>> +\tgit branch --list branch* >actual &&\n>> +\ttest_cmp expect actual\n>> +'\n> \n> Does this one exclude the \"* master\" entry at this stage in the series?\n\nSheesh, that rebasing mistake (flipping the order of 4 and 5) was\npresent in v2 already. Only recently I learned about rebase-i's \"exec\"\nand have to make it a habit to use it for step-by-step series testing.\n\nSorry, I'll send out v3 a bit later when I see that there are no more\ncomments (and a full step-by-step series test has passed).\n\nMichael\n"},{"id":"174450","messageId":"7vippg7lsi.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"4E5B3317.7000207@drmicha.warpmail.net","subject":"Re: [PATCHv3 4/5] branch: introduce --list option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-29T06:51:25Z","receivedAt":"2011-08-29T06:51:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Sheesh, that rebasing mistake (flipping the order of 4 and 5) was\n> present in v2 already. Only recently I learned about rebase-i's \"exec\"\n> and have to make it a habit to use it for step-by-step series testing.\n\nThat's Ok. Locally moved the offending part of the test to 5 when\napplying.\n\nThanks.\n"},{"id":"174924","messageId":"4E661BDE.1080204@elegosoft.com","threadId":"27997","inReplyTo":"0c487086643fbf0334140365f20fef62242b7dac.1314543252.git.git@drmicha.warpmail.net","subject":"Re: [PATCHv3 5/5] branch: allow pattern arguments","fromName":"Michael Schubert","fromEmail":"mschub@elegosoft.com","sentAt":"2011-09-06T13:10:54Z","receivedAt":"2011-09-06T13:10:54Z","isPatch":false,"sender":{"key":"mschub@elegosoft.com","avatar":null},"body":"On 08/28/2011 04:54 PM, Michael J Gruber wrote:\n> +static int match_patterns(const char **pattern, const char *refname)\n> +{\n> +\tif (!*pattern)\n> +\t\treturn 1; /* no pattern always matches */\n> +\twhile (*pattern) {\n> +\t\tif (!fnmatch(*pattern, refname, 0))\n> +\t\t\treturn 1;\n> +\t\tpattern++;\n> +\t}\n> +\treturn 0;\n> +}\n\nNitpick: maybe builtin/branch.c and builtin/tag.c could share match_pattern().?\n\nA second thought: the printed \"remotes/\" prefix could be confusing for users,\nsince it seems to be part of the refname. For example:\n\n$ git branch -a\n* master\n  maint\n  man\n  remotes/origin/master\n  remotes/origin/maint\n  remotes/origin/man\n\n$ git branch -a --list remotes/origin*\n[no output]\n\nbut\n\n$ git branch -a --list origin*\n  remotes/origin/master\n  remotes/origin/maint\n  remotes/origin/man\n\n(Sorry in case I missed that) What's the reason you decided --list to show local\nbranches only? Maybe --list could show all refnames without any extra prefix.?\n\nThanks.\n"},{"id":"174927","messageId":"4E662C6F.7000205@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E661BDE.1080204@elegosoft.com","subject":"Re: [PATCHv3 5/5] branch: allow pattern arguments","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-06T14:21:35Z","receivedAt":"2011-09-06T14:21:35Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Michael Schubert venit, vidit, dixit 06.09.2011 15:10:\n> On 08/28/2011 04:54 PM, Michael J Gruber wrote:\n>> +static int match_patterns(const char **pattern, const char *refname)\n>> +{\n>> +\tif (!*pattern)\n>> +\t\treturn 1; /* no pattern always matches */\n>> +\twhile (*pattern) {\n>> +\t\tif (!fnmatch(*pattern, refname, 0))\n>> +\t\t\treturn 1;\n>> +\t\tpattern++;\n>> +\t}\n>> +\treturn 0;\n>> +}\n> \n> Nitpick: maybe builtin/branch.c and builtin/tag.c could share match_pattern().?\n\nI think all commands which list refs should share code - for-each-ref,\nbranch, tag, replace. I suggest to unify log and for-each-ref-formats\nfirst, the unify ref listers.\n\n> A second thought: the printed \"remotes/\" prefix could be confusing for users,\n> since it seems to be part of the refname. For example:\n> \n> $ git branch -a\n> * master\n>   maint\n>   man\n>   remotes/origin/master\n>   remotes/origin/maint\n>   remotes/origin/man\n> \n> $ git branch -a --list remotes/origin*\n> [no output]\n> \n> but\n> \n> $ git branch -a --list origin*\n>   remotes/origin/master\n>   remotes/origin/maint\n>   remotes/origin/man\n> \n> (Sorry in case I missed that) What's the reason you decided --list to show local\n> branches only? Maybe --list could show all refnames without any extra prefix.?\n\nI didn't decide anything here. \"git branch\" lists all local branches and\nhas been doing that forever, and \"--list\" is and should be a noop\nwithout a pattern. That was the idea: -r/-a select refnames,\n--list/-v/-vv activate the list mode(s), and the pattern is matched\nagainst the selected refs.\n\n(This is one reason why I didn't want it to be named --glob - the\npattern is a filter, not a selector.)\n\nThat being said, I find the fact that \"-a --list remotes/origin/*\" does\nnot match anything somewhat disconcerting, although it fits in with the\ngeneral idea of \"git branch\": it deals with branch names, not ref names.\nHave you ever tried to delete a remote branch?\n\ngit branch -r -d origin/maint # workee\ngit branch -r -d remotes/origin/maint # no workee\n\nWithout -r, it doesn't work either.\n\nSo, the way it is it fits in with how \"git branch\" works, and is\ndifferent from for-each-ref (and rev-list --glob). I don't like it,\nbecause you may have a local branch origin/maint (i.e.\nrefs/heads/origin/maint) which you can't distinguish from the remote\nbranch by a pattern, only by using or not using -r. But it's the same as\nwith \"git branch -d\", really.\n\nMichael\n"},{"id":"174928","messageId":"CAGdFq_jmW+VZygVj73EP_1oB5DDNp5rYZgZq+i9zf3w6BpsMYA@mail.gmail.com","threadId":"27997","inReplyTo":"4E662C6F.7000205@drmicha.warpmail.net","subject":"Re: [PATCHv3 5/5] branch: allow pattern arguments","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2011-09-06T14:26:06Z","receivedAt":"2011-09-06T14:26:06Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Tue, Sep 6, 2011 at 16:21, Michael J Gruber <git@drmicha.warpmail.net> wrote:\n> Have you ever tried to delete a remote branch?\n>\n> git branch -r -d origin/maint # workee\n> git branch -r -d remotes/origin/maint # no workee\n>\n> Without -r, it doesn't work either.\n\nHeh, I read this as \"worktree\" / \"no worktree\" at least 4 times.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"174936","messageId":"4E664624.7050209@drmicha.warpmail.net","threadId":"27997","inReplyTo":"CAGdFq_jmW+VZygVj73EP_1oB5DDNp5rYZgZq+i9zf3w6BpsMYA@mail.gmail.com","subject":"Re: [PATCHv3 5/5] branch: allow pattern arguments","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-06T16:11:16Z","receivedAt":"2011-09-06T16:11:16Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Sverre Rabbelier venit, vidit, dixit 06.09.2011 16:26:\n> Heya,\n> \n> On Tue, Sep 6, 2011 at 16:21, Michael J Gruber <git@drmicha.warpmail.net> wrote:\n>> Have you ever tried to delete a remote branch?\n>>\n>> git branch -r -d origin/maint # workee\n>> git branch -r -d remotes/origin/maint # no workee\n>>\n>> Without -r, it doesn't work either.\n> \n> Heh, I read this as \"worktree\" / \"no worktree\" at least 4 times.\n> \n\nYes, our require_work_tree should really be renamed to\n\nno_worktree_no_workee\n\nThe beauty of pidgin english ;)\n\nMichael\n"},{"id":"175024","messageId":"20110907195319.GC13364@sigill.intra.peff.net","threadId":"27997","inReplyTo":"7vwre0dsdy.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 0/5] RFC: patterns for branch list","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-07T19:53:19Z","receivedAt":"2011-09-07T19:53:19Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Aug 26, 2011 at 09:55:37AM -0700, Junio C Hamano wrote:\n\n> As we use fnmatch() and not match_pathspec() for this pattern matching,\n> \"git branch peff/\" will not list all the topics under the peff/ hierarchy\n> (your example \"git branch peff/\\*\" would be the way), but I would imagine\n> that we may someday want to update it to allow the leading path match\n> here. And at that point, distinction between\n> \n> \tgit branch peff  ;# to create a \"peff\" branch\n>         git branch peff/ ;# to list \"peff/\" branches, as \"peff/\" itself is\n>         \t\t ;# an invalid branch name and your auto listing\n>                          ;# heuristic kicks in\n> \n> while it might be very useful for experts, becomes too subtle and would\n> confuse new people. We should instead require an explicit -l/--list, and\n> not use the auto listing heuristics (it is fine for -v to imply -l).\n\nSorry, I'm atrociously behind on reviewing this topic. But FWIW, I\ncompletely agree with this. Detecting invalid branch formats is much too\nsubtle and error prone, and we are better off making a short and\neasy-to-type version of \"--list\".\n\n-Peff\n"},{"id":"175025","messageId":"20110907195611.GD13364@sigill.intra.peff.net","threadId":"27997","inReplyTo":"4E5A5290.4050005@drmicha.warpmail.net","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-07T19:56:11Z","receivedAt":"2011-09-07T19:56:11Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Aug 28, 2011 at 04:37:04PM +0200, Michael J Gruber wrote:\n\n> Currently, \"-m -d\" is forbidden\", but \"-m -v\" is \"-m\", same for \"-d -v\".\n> Do we want to keep it like that? Probably. I'll add the tests to 4/5.\n\nYes, I think so. \"-v\" just means \"be more verbose\"; the fact that\nthere is currently nothing to be more verbose about with \"-m\" and \"-d\"\nis irrelevant.\n\nIt does make me a little nervous about the \"'git branch -v'\nautomatically means 'git branch --list -v'\" patch, though. It closes the\ndoor in the future to us being more or less verbose about branch\ncreation details (and while helpful, it creates a slight inconsistency\nin the interface).\n\nIf we are adding \"-l\" anyway, is it really necessary? It's not much\nharder to do \"git branch -lv\" once that is in place.\n\n-Peff\n"},{"id":"175079","messageId":"4E6888CE.8070307@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110907195319.GC13364@sigill.intra.peff.net","subject":"Re: [PATCH 0/5] RFC: patterns for branch list","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-08T09:20:14Z","receivedAt":"2011-09-08T09:20:14Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 07.09.2011 21:53:\n> On Fri, Aug 26, 2011 at 09:55:37AM -0700, Junio C Hamano wrote:\n> \n>> As we use fnmatch() and not match_pathspec() for this pattern matching,\n>> \"git branch peff/\" will not list all the topics under the peff/ hierarchy\n>> (your example \"git branch peff/\\*\" would be the way), but I would imagine\n>> that we may someday want to update it to allow the leading path match\n>> here. And at that point, distinction between\n>>\n>> \tgit branch peff  ;# to create a \"peff\" branch\n>>         git branch peff/ ;# to list \"peff/\" branches, as \"peff/\" itself is\n>>         \t\t ;# an invalid branch name and your auto listing\n>>                          ;# heuristic kicks in\n>>\n>> while it might be very useful for experts, becomes too subtle and would\n>> confuse new people. We should instead require an explicit -l/--list, and\n>> not use the auto listing heuristics (it is fine for -v to imply -l).\n> \n> Sorry, I'm atrociously behind on reviewing this topic. But FWIW, I\n> completely agree with this. Detecting invalid branch formats is much too\n> subtle and error prone, and we are better off making a short and\n> easy-to-type version of \"--list\".\n\nWe all agreed on that, you didn't miss anything ;)\n\nMichael\n"},{"id":"175080","messageId":"4E6889DF.7030404@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110907195611.GD13364@sigill.intra.peff.net","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-08T09:24:47Z","receivedAt":"2011-09-08T09:24:47Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 07.09.2011 21:56:\n> On Sun, Aug 28, 2011 at 04:37:04PM +0200, Michael J Gruber wrote:\n> \n>> Currently, \"-m -d\" is forbidden\", but \"-m -v\" is \"-m\", same for \"-d -v\".\n>> Do we want to keep it like that? Probably. I'll add the tests to 4/5.\n> \n> Yes, I think so. \"-v\" just means \"be more verbose\"; the fact that\n> there is currently nothing to be more verbose about with \"-m\" and \"-d\"\n> is irrelevant.\n> \n> It does make me a little nervous about the \"'git branch -v'\n> automatically means 'git branch --list -v'\" patch, though. It closes the\n> door in the future to us being more or less verbose about branch\n> creation details (and while helpful, it creates a slight inconsistency\n> in the interface).\n> \n> If we are adding \"-l\" anyway, is it really necessary? It's not much\n> harder to do \"git branch -lv\" once that is in place.\n\nWell, it will take a while to (re-)take \"-l\". For the sake of\nconsistency I wouldn't mind making \"--verbose\" strictly a \"modifier\" for\nwhatever mode/subcommand of the command is going on, even though it\nwould mean having to type \"-v --list\" for a long time. In general,\n-v/--verbose should always be like that, but is not (e.g. tag -v).\n\nThis is in next now but no harm would be done changing it now.\n\nMichael\n"},{"id":"175095","messageId":"cover.1315491900.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E6889DF.7030404@drmicha.warpmail.net","subject":"[PATCHv4 0/5] mg/branch-list amendment","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-08T14:25:56Z","receivedAt":"2011-09-08T14:25:56Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"So, this is what the top 2 commits in mg/branch-list should be replaced\nwith if we don't let \"-v\" activate list mode, so that we can have a verbose\noption for branch creation later on, i.e.:\n\ngit branch -v foo is the verbose version of git branch\n\nMichael J Gruber (2):\n  branch: introduce --list option\n  branch: allow pattern arguments\n\n Documentation/git-branch.txt |   17 +++++++++++++----\n builtin/branch.c             |   35 +++++++++++++++++++++++++++++------\n t/t3200-branch.sh            |   32 ++++++++++++++++++++++++++++++++\n t/t3203-branch-output.sh     |   28 ++++++++++++++++++++++++++++\n 4 files changed, 102 insertions(+), 10 deletions(-)\n\n-- \n1.7.7.rc0.469.g9eb94\n"},{"id":"175096","messageId":"c259dcbada3de282325b59b143209ace57ff8b9d.1315491900.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E6889DF.7030404@drmicha.warpmail.net","subject":"[PATCHv4 4/5] branch: introduce --list option","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-08T14:25:57Z","receivedAt":"2011-09-08T14:25:57Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Currently, there is no way to invoke the list mode explicitly.\n\nIntroduce a --list option which invokes the list mode. This will be\nbeneficial for invoking list mode with pattern matching, which otherwise\nwould be interpreted as branch creation.\n\nAlong with --list, test also combinations of existing options.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |   11 ++++++++---\n builtin/branch.c             |   11 ++++++++---\n t/t3200-branch.sh            |   32 ++++++++++++++++++++++++++++++++\n t/t3203-branch-output.sh     |    5 +++++\n 4 files changed, 53 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 4c64ac9..26024b6 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git branch' [--color[=<when>] | --no-color] [-r | -a]\n-\t[-v [--abbrev=<length> | --no-abbrev]]\n+\t[--list] [-v [--abbrev=<length> | --no-abbrev]]\n \t[(--merged | --no-merged | --contains) [<commit>]]\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n@@ -20,7 +20,8 @@ DESCRIPTION\n \n With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n-branches to be listed, and option `-a` shows both.\n+branches to be listed, and option `-a` shows both. This list mode is also\n+activated by the `--list` option (see below).\n \n With `--contains`, shows only the branches that contain the named commit\n (in other words, the branches whose tip commits are descendants of the\n@@ -110,9 +111,13 @@ OPTIONS\n --all::\n \tList both remote-tracking branches and local branches.\n \n+--list::\n+\tActivate the list mode.\n+\n -v::\n --verbose::\n-\tShow sha1 and commit subject line for each head, along with\n+\tWhen in list mode,\n+\tshow sha1 and commit subject line for each head, along with\n \trelationship to upstream branch (if any). If given twice, print\n \tthe name of the upstream branch, as well.\n \ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex bd3a315..b17ad26 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -612,7 +612,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int\n \n int cmd_branch(int argc, const char **argv, const char *prefix)\n {\n-\tint delete = 0, rename = 0, force_create = 0;\n+\tint delete = 0, rename = 0, force_create = 0, list = 0;\n \tint verbose = 0, abbrev = -1, detached = 0;\n \tint reflog = 0;\n \tenum branch_track track;\n@@ -651,6 +651,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT('D', NULL, &delete, \"delete branch (even if not merged)\", 2),\n \t\tOPT_BIT('m', \"move\", &rename, \"move/rename a branch and its reflog\", 1),\n \t\tOPT_BIT('M', NULL, &rename, \"move/rename a branch, even if target exists\", 2),\n+\t\tOPT_BOOLEAN(0, \"list\", &list, \"list branch names\"),\n \t\tOPT_BOOLEAN('l', \"create-reflog\", &reflog, \"create the branch's reflog\"),\n \t\tOPT__FORCE(&force_create, \"force creation (when already exists)\"),\n \t\t{\n@@ -693,7 +694,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, prefix, options, builtin_branch_usage,\n \t\t\t     0);\n-\tif (!!delete + !!rename + !!force_create > 1)\n+\n+\tif (!delete && !rename && !force_create && argc == 0)\n+\t\tlist = 1;\n+\n+\tif (!!delete + !!rename + !!force_create + !!list > 1)\n \t\tusage_with_options(builtin_branch_usage, options);\n \n \tif (abbrev == -1)\n@@ -701,7 +706,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n-\telse if (argc == 0)\n+\telse if (list)\n \t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex 9e69c8c..c466b20 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -98,6 +98,38 @@ test_expect_success 'git branch -m q r/q should fail when r exists' '\n \ttest_must_fail git branch -m q r/q\n '\n \n+test_expect_success 'git branch -v -d t should work' '\n+\tgit branch t &&\n+\ttest .git/refs/heads/t &&\n+\tgit branch -v -d t &&\n+\ttest ! -f .git/refs/heads/t\n+'\n+\n+test_expect_success 'git branch -v -m t s should work' '\n+\tgit branch t &&\n+\ttest .git/refs/heads/t &&\n+\tgit branch -v -m t s &&\n+\ttest ! -f .git/refs/heads/t &&\n+\ttest -f .git/refs/heads/s &&\n+\tgit branch -d s\n+'\n+\n+test_expect_success 'git branch -m -d t s should fail' '\n+\tgit branch t &&\n+\ttest .git/refs/heads/t &&\n+\ttest_must_fail git branch -m -d t s &&\n+\tgit branch -d t &&\n+\ttest ! -f .git/refs/heads/t\n+'\n+\n+test_expect_success 'git branch --list -d t should fail' '\n+\tgit branch t &&\n+\ttest .git/refs/heads/t &&\n+\ttest_must_fail git branch --list -d t &&\n+\tgit branch -d t &&\n+\ttest ! -f .git/refs/heads/t\n+'\n+\n mv .git/config .git/config-saved\n \n test_expect_success 'git branch -m q q2 without config should succeed' '\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex 6b7c118..97d10b1 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -32,6 +32,11 @@ test_expect_success 'git branch shows local branches' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git branch --list shows local branches' '\n+\tgit branch --list >actual &&\n+\ttest_cmp expect actual\n+'\n+\n cat >expect <<'EOF'\n   origin/HEAD -> origin/branch-one\n   origin/branch-one\n-- \n1.7.7.rc0.469.g9eb94\n"},{"id":"175097","messageId":"26dcd6b4b97f848c4a417f07804a01be87188403.1315491900.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"4E6889DF.7030404@drmicha.warpmail.net","subject":"[PATCHv4 5/5] branch: allow pattern arguments","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-08T14:25:58Z","receivedAt":"2011-09-08T14:25:58Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Allow pattern arguments for the list mode just like for git tag -l.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-branch.txt |    8 ++++++--\n builtin/branch.c             |   24 +++++++++++++++++++++---\n t/t3203-branch-output.sh     |   23 +++++++++++++++++++++++\n 3 files changed, 50 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 26024b6..2e27ee4 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n [verse]\n 'git branch' [--color[=<when>] | --no-color] [-r | -a]\n \t[--list] [-v [--abbrev=<length> | --no-abbrev]]\n-\t[(--merged | --no-merged | --contains) [<commit>]]\n+\t[(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]\n 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]\n 'git branch' (-m | -M) [<oldbranch>] <newbranch>\n 'git branch' (-d | -D) [-r] <branchname>...\n@@ -22,6 +22,9 @@ With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n branches to be listed, and option `-a` shows both. This list mode is also\n activated by the `--list` option (see below).\n+<pattern> restricts the output to matching branches, the pattern is a shell\n+wildcard (i.e., matched using fnmatch(3)).\n+Multiple patterns may be given; if any of them matches, the tag is shown.\n \n With `--contains`, shows only the branches that contain the named commit\n (in other words, the branches whose tip commits are descendants of the\n@@ -112,7 +115,8 @@ OPTIONS\n \tList both remote-tracking branches and local branches.\n \n --list::\n-\tActivate the list mode.\n+\tActivate the list mode. `git branch <pattern>` would try to create a branch,\n+\tuse `git branch --list <pattern>` to list matching branches.\n \n -v::\n --verbose::\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex b17ad26..099c75c 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -260,9 +260,22 @@ static char *resolve_symref(const char *src, const char *prefix)\n \n struct append_ref_cb {\n \tstruct ref_list *ref_list;\n+\tconst char **pattern;\n \tint ret;\n };\n \n+static int match_patterns(const char **pattern, const char *refname)\n+{\n+\tif (!*pattern)\n+\t\treturn 1; /* no pattern always matches */\n+\twhile (*pattern) {\n+\t\tif (!fnmatch(*pattern, refname, 0))\n+\t\t\treturn 1;\n+\t\tpattern++;\n+\t}\n+\treturn 0;\n+}\n+\n static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)\n {\n \tstruct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);\n@@ -297,6 +310,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,\n \tif ((kind & ref_list->kinds) == 0)\n \t\treturn 0;\n \n+\tif (!match_patterns(cb->pattern, refname))\n+\t\treturn 0;\n+\n \tcommit = NULL;\n \tif (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {\n \t\tcommit = lookup_commit_reference_gently(sha1, 1);\n@@ -492,7 +508,7 @@ static void show_detached(struct ref_list *ref_list)\n \t}\n }\n \n-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)\n+static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)\n {\n \tint i;\n \tstruct append_ref_cb cb;\n@@ -506,6 +522,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tif (merge_filter != NO_FILTER)\n \t\tinit_revisions(&ref_list.revs, NULL);\n \tcb.ref_list = &ref_list;\n+\tcb.pattern = pattern;\n \tcb.ret = 0;\n \tfor_each_rawref(append_ref, &cb);\n \tif (merge_filter != NO_FILTER) {\n@@ -523,7 +540,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru\n \tqsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);\n \n \tdetached = (detached && (kinds & REF_LOCAL_BRANCH));\n-\tif (detached)\n+\tif (detached && match_patterns(pattern, \"HEAD\"))\n \t\tshow_detached(&ref_list);\n \n \tfor (i = 0; i < ref_list.index; i++) {\n@@ -707,7 +724,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n \telse if (list)\n-\t\treturn print_ref_list(kinds, detached, verbose, abbrev, with_commit);\n+\t\treturn print_ref_list(kinds, detached, verbose, abbrev,\n+\t\t\t\t      with_commit, argv);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n \telse if (rename && (argc == 2))\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex 97d10b1..76fe7e0 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -38,6 +38,15 @@ test_expect_success 'git branch --list shows local branches' '\n '\n \n cat >expect <<'EOF'\n+  branch-one\n+  branch-two\n+EOF\n+test_expect_success 'git branch --list pattern shows matching local branches' '\n+\tgit branch --list branch* >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n   origin/HEAD -> origin/branch-one\n   origin/branch-one\n   origin/branch-two\n@@ -72,6 +81,20 @@ test_expect_success 'git branch -v shows branch summaries' '\n '\n \n cat >expect <<'EOF'\n+two\n+one\n+EOF\n+test_expect_success 'git branch --list -v pattern shows branch summaries' '\n+\tgit branch --list -v branch* >tmp &&\n+\tawk \"{print \\$NF}\" <tmp >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git branch -v pattern does not show branch summaries' '\n+\ttest_must_fail git branch -v branch*\n+'\n+\n+cat >expect <<'EOF'\n * (no branch)\n   branch-one\n   branch-two\n-- \n1.7.7.rc0.469.g9eb94\n"},{"id":"175115","messageId":"7vr53qwxtz.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"4E6889DF.7030404@drmicha.warpmail.net","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-08T21:03:52Z","receivedAt":"2011-09-08T21:03:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Jeff King venit, vidit, dixit 07.09.2011 21:56:\n> ...\n>> It does make me a little nervous about the \"'git branch -v'\n>> automatically means 'git branch --list -v'\" patch, though. It closes the\n>> door in the future to us being more or less verbose about branch\n>> creation details (and while helpful, it creates a slight inconsistency\n>> in the interface).\n\nHasn't 'git branch -v' meant listing in verbose mode for a long enough\ntime that changing it now would mean a moderately major regression?\n\nAt least my copy of v1.7.0 seems to list with \"git branch -v\".\n"},{"id":"175112","messageId":"20110908211156.GA510@sigill.intra.peff.net","threadId":"27997","inReplyTo":"7vr53qwxtz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-08T21:11:56Z","receivedAt":"2011-09-08T21:11:56Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Sep 08, 2011 at 02:03:52PM -0700, Junio C Hamano wrote:\n\n> Hasn't 'git branch -v' meant listing in verbose mode for a long enough\n> time that changing it now would mean a moderately major regression?\n> \n> At least my copy of v1.7.0 seems to list with \"git branch -v\".\n\nNo, it will mean the same thing as in v1.7.0; it is not the \"-v\" which\ndoes it, but the lack of non-option arguments.\n\nRight now, \"-v\" just means \"if we are listing, do it verbosely\". And if\nyou don't specify any non-option arguments, it means \"list\". So right\nnow:\n\n  git branch        ;# list\n  git branch -v     ;# list verbosely\n  git branch -v foo ;# create branch 'foo', -v does nothing\n\nMichael's proposal was:\n\n  git branch -v foo ;# assume verbose list, interpret 'foo' as pattern\n\nwhich is actually a regression, albeit one that probably doesn't matter\n(because \"-v\" didn't ever do anything with a non-option argument).\n\nWhereas mine is:\n\n  git branch -v foo ;# create branch 'foo' verbosely\n\nWhich happens to do exactly the same thing as the current behavior,\nbecause there are no verbose messages to add to \"git branch\". But it\nleaves the door open to adding them in the future (and it's consistent\nwith \"git branch -m -v\" and \"git branch -d -v\", both of which could use\n\"-v\" to do their operations more verbosely).\n\n-Peff\n"},{"id":"175123","messageId":"7vmxeewx7f.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"7vr53qwxtz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-08T21:17:24Z","receivedAt":"2011-09-08T21:17:24Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n>\n>> Jeff King venit, vidit, dixit 07.09.2011 21:56:\n>> ...\n>>> It does make me a little nervous about the \"'git branch -v'\n>>> automatically means 'git branch --list -v'\" patch, though. It closes the\n>>> door in the future to us being more or less verbose about branch\n>>> creation details (and while helpful, it creates a slight inconsistency\n>>> in the interface).\n>\n> Hasn't 'git branch -v' meant listing in verbose mode for a long enough\n> time that changing it now would mean a moderately major regression?\n>\n> At least my copy of v1.7.0 seems to list with \"git branch -v\".\n\nAh, nevermind.\n\nAs the series is already in 'next', here is what I came up with.\n\n-- >8 --\nFrom: Michael J Gruber <git@drmicha.warpmail.net>\nDate: Thu, 8 Sep 2011 14:09:50 -0700\nSubject: [PATCH] branch: -v does not automatically imply --list\n\n\"branch -v\" without other options or parameters still works in the list\nmode, but that is not because there is \"-v\" but because there is no\nparameter nor option.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-branch.txt |    6 +++---\n builtin/branch.c             |    3 +--\n t/t3203-branch-output.sh     |    8 ++++++--\n 3 files changed, 10 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 2b8bc84..f46013c 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -21,7 +21,7 @@ DESCRIPTION\n With no arguments, existing branches are listed and the current branch will\n be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n branches to be listed, and option `-a` shows both. This list mode is also\n-activated by the `--list` and `-v` options (see below).\n+activated by the `--list` option (see below).\n <pattern> restricts the output to matching branches, the pattern is a shell\n wildcard (i.e., matched using fnmatch(3))\n Multiple patterns may be given; if any of them matches, the tag is shown.\n@@ -120,10 +120,10 @@ OPTIONS\n \n -v::\n --verbose::\n-\tShow sha1 and commit subject line for each head, along with\n+\tWhen in list mode,\n+\tshow sha1 and commit subject line for each head, along with\n \trelationship to upstream branch (if any). If given twice, print\n \tthe name of the upstream branch, as well.\n-\t`--list` is implied by all verbosity options.\n \n --abbrev=<length>::\n \tAlter the sha1's minimum display length in the output listing.\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex 98a420f..099c75c 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -712,8 +712,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, prefix, options, builtin_branch_usage,\n \t\t\t     0);\n \n-\tif (!delete && !rename && !force_create &&\n-\t    (argc == 0 || (verbose && argc)))\n+\tif (!delete && !rename && !force_create && argc == 0)\n \t\tlist = 1;\n \n \tif (!!delete + !!rename + !!force_create + !!list > 1)\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex f2b294b..76fe7e0 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -84,12 +84,16 @@ cat >expect <<'EOF'\n two\n one\n EOF\n-test_expect_success 'git branch -v pattern shows branch summaries' '\n-\tgit branch -v branch* >tmp &&\n+test_expect_success 'git branch --list -v pattern shows branch summaries' '\n+\tgit branch --list -v branch* >tmp &&\n \tawk \"{print \\$NF}\" <tmp >actual &&\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git branch -v pattern does not show branch summaries' '\n+\ttest_must_fail git branch -v branch*\n+'\n+\n cat >expect <<'EOF'\n * (no branch)\n   branch-one\n-- \n1.7.7.rc0.188.g3793ac\n"},{"id":"175138","messageId":"20110909010832.GA4809@sigill.intra.peff.net","threadId":"27997","inReplyTo":"7vmxeewx7f.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-09T01:08:32Z","receivedAt":"2011-09-09T01:08:32Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Sep 08, 2011 at 02:17:24PM -0700, Junio C Hamano wrote:\n\n> \"branch -v\" without other options or parameters still works in the list\n> mode, but that is not because there is \"-v\" but because there is no\n> parameter nor option.\n> [...]\n> +test_expect_success 'git branch -v pattern does not show branch summaries' '\n> +\ttest_must_fail git branch -v branch*\n> +'\n\nYou might also want to affirm that it does not just fail, but still\ncreates a branch, like:\n\n  test_expect_success 'git branch -v <name> creates a branch' '\n         git rev-parse HEAD >expect &&\n         git branch -v foo &&\n         git rev-parse foo >actual &&\n         test_cmp expect actual\n  '\n\n-Peff\n"},{"id":"175151","messageId":"4E69B832.9030503@drmicha.warpmail.net","threadId":"27997","inReplyTo":"7vmxeewx7f.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-09T06:54:42Z","receivedAt":"2011-09-09T06:54:42Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 08.09.2011 23:17:\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n>> Michael J Gruber <git@drmicha.warpmail.net> writes:\n>>\n>>> Jeff King venit, vidit, dixit 07.09.2011 21:56:\n>>> ...\n>>>> It does make me a little nervous about the \"'git branch -v'\n>>>> automatically means 'git branch --list -v'\" patch, though. It closes the\n>>>> door in the future to us being more or less verbose about branch\n>>>> creation details (and while helpful, it creates a slight inconsistency\n>>>> in the interface).\n>>\n>> Hasn't 'git branch -v' meant listing in verbose mode for a long enough\n>> time that changing it now would mean a moderately major regression?\n>>\n>> At least my copy of v1.7.0 seems to list with \"git branch -v\".\n> \n> Ah, nevermind.\n> \n> As the series is already in 'next', here is what I came up with.\n\nI thought you'll rebuild next anyways after 1.7.7, but either way it's\nfine. Thanks for holding this series in next long enough to really cook\nit (and Jeff for revisiting it), it's much better now, keeping the\n(undocumented, but expected) behavior of \"git branch -v foo\".\n\n> \n> -- >8 --\n> From: Michael J Gruber <git@drmicha.warpmail.net>\n> Date: Thu, 8 Sep 2011 14:09:50 -0700\n> Subject: [PATCH] branch: -v does not automatically imply --list\n> \n> \"branch -v\" without other options or parameters still works in the list\n> mode, but that is not because there is \"-v\" but because there is no\n> parameter nor option.\n> \n> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  Documentation/git-branch.txt |    6 +++---\n>  builtin/branch.c             |    3 +--\n>  t/t3203-branch-output.sh     |    8 ++++++--\n>  3 files changed, 10 insertions(+), 7 deletions(-)\n> \n> diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\n> index 2b8bc84..f46013c 100644\n> --- a/Documentation/git-branch.txt\n> +++ b/Documentation/git-branch.txt\n> @@ -21,7 +21,7 @@ DESCRIPTION\n>  With no arguments, existing branches are listed and the current branch will\n>  be highlighted with an asterisk.  Option `-r` causes the remote-tracking\n>  branches to be listed, and option `-a` shows both. This list mode is also\n> -activated by the `--list` and `-v` options (see below).\n> +activated by the `--list` option (see below).\n>  <pattern> restricts the output to matching branches, the pattern is a shell\n>  wildcard (i.e., matched using fnmatch(3))\n>  Multiple patterns may be given; if any of them matches, the tag is shown.\n> @@ -120,10 +120,10 @@ OPTIONS\n>  \n>  -v::\n>  --verbose::\n> -\tShow sha1 and commit subject line for each head, along with\n> +\tWhen in list mode,\n> +\tshow sha1 and commit subject line for each head, along with\n>  \trelationship to upstream branch (if any). If given twice, print\n>  \tthe name of the upstream branch, as well.\n> -\t`--list` is implied by all verbosity options.\n>  \n>  --abbrev=<length>::\n>  \tAlter the sha1's minimum display length in the output listing.\n> diff --git a/builtin/branch.c b/builtin/branch.c\n> index 98a420f..099c75c 100644\n> --- a/builtin/branch.c\n> +++ b/builtin/branch.c\n> @@ -712,8 +712,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n>  \targc = parse_options(argc, argv, prefix, options, builtin_branch_usage,\n>  \t\t\t     0);\n>  \n> -\tif (!delete && !rename && !force_create &&\n> -\t    (argc == 0 || (verbose && argc)))\n> +\tif (!delete && !rename && !force_create && argc == 0)\n>  \t\tlist = 1;\n>  \n>  \tif (!!delete + !!rename + !!force_create + !!list > 1)\n> diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\n> index f2b294b..76fe7e0 100755\n> --- a/t/t3203-branch-output.sh\n> +++ b/t/t3203-branch-output.sh\n> @@ -84,12 +84,16 @@ cat >expect <<'EOF'\n>  two\n>  one\n>  EOF\n> -test_expect_success 'git branch -v pattern shows branch summaries' '\n> -\tgit branch -v branch* >tmp &&\n> +test_expect_success 'git branch --list -v pattern shows branch summaries' '\n> +\tgit branch --list -v branch* >tmp &&\n>  \tawk \"{print \\$NF}\" <tmp >actual &&\n>  \ttest_cmp expect actual\n>  '\n>  \n> +test_expect_success 'git branch -v pattern does not show branch summaries' '\n> +\ttest_must_fail git branch -v branch*\n> +'\n> +\n>  cat >expect <<'EOF'\n>  * (no branch)\n>    branch-one\n"},{"id":"175207","messageId":"7vlitxvh45.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"4E69B832.9030503@drmicha.warpmail.net","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-09T16:02:34Z","receivedAt":"2011-09-09T16:02:34Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Junio C Hamano venit, vidit, dixit 08.09.2011 23:17:\n>> Ah, nevermind.\n>> \n>> As the series is already in 'next', here is what I came up with.\n>\n> I thought you'll rebuild next anyways after 1.7.7, but either way it's\n> fine. Thanks for holding this series in next long enough to really cook\n> it (and Jeff for revisiting it), it's much better now, keeping the\n> (undocumented, but expected) behavior of \"git branch -v foo\".\n\nThank *you* for all the work.\n\nI recall Peff had some comments on your new tests last night, by the way.\n"},{"id":"175232","messageId":"4E6A691C.2060803@drmicha.warpmail.net","threadId":"27997","inReplyTo":"7vlitxvh45.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-09T19:29:32Z","receivedAt":"2011-09-09T19:29:32Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 09.09.2011 18:02:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n> \n>> Junio C Hamano venit, vidit, dixit 08.09.2011 23:17:\n>>> Ah, nevermind.\n>>>\n>>> As the series is already in 'next', here is what I came up with.\n>>\n>> I thought you'll rebuild next anyways after 1.7.7, but either way it's\n>> fine. Thanks for holding this series in next long enough to really cook\n>> it (and Jeff for revisiting it), it's much better now, keeping the\n>> (undocumented, but expected) behavior of \"git branch -v foo\".\n> \n> Thank *you* for all the work.\n> \n> I recall Peff had some comments on your new tests last night, by the way.\n> \n\nYes, we have tests (now) for \"-v -d\", \"-v -m\", \"-v branch*\" and\ncombinations with --list. Testing \"-v foo\" for creation would be good\n(and belong into t3200). Is there anything to amend?\n\nMichael\n"},{"id":"175233","messageId":"20110909193033.GA31184@sigill.intra.peff.net","threadId":"27997","inReplyTo":"4E6A691C.2060803@drmicha.warpmail.net","subject":"Re: [PATCHv2 4/5] branch: introduce --list option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-09T19:30:34Z","receivedAt":"2011-09-09T19:30:34Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Sep 09, 2011 at 09:29:32PM +0200, Michael J Gruber wrote:\n\n> > I recall Peff had some comments on your new tests last night, by the way.\n> \n> Yes, we have tests (now) for \"-v -d\", \"-v -m\", \"-v branch*\" and\n> combinations with --list. Testing \"-v foo\" for creation would be good\n> (and belong into t3200). Is there anything to amend?\n\nI think my comment was just to add the \"-v foo\" test.\n\n-Peff\n"},{"id":"175235","messageId":"49578782dd114220aa2562b5bd29755fc2bdd0fa.1315597137.git.git@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110909193033.GA31184@sigill.intra.peff.net","subject":"[PATCH] t3200: test branch creation with -v","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-09T19:40:59Z","receivedAt":"2011-09-09T19:40:59Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Make sure that \"git branch -v t\" creates branch \"t\".\n\nSuggested-by: Jeff King <peff@peff.net>\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n t/t3200-branch.sh |    7 +++++++\n 1 files changed, 7 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex c466b20..8381f0c 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -105,6 +105,13 @@ test_expect_success 'git branch -v -d t should work' '\n \ttest ! -f .git/refs/heads/t\n '\n \n+test_expect_success 'git branch -v t should work' '\n+\tgit branch -v t &&\n+\ttest .git/refs/heads/t &&\n+\tgit branch -d t &&\n+\ttest ! -f .git/refs/heads/t\n+'\n+\n test_expect_success 'git branch -v -m t s should work' '\n \tgit branch t &&\n \ttest .git/refs/heads/t &&\n-- \n1.7.7.rc0.469.g9eb94\n"},{"id":"175236","messageId":"20110909194357.GA31446@sigill.intra.peff.net","threadId":"27997","inReplyTo":"49578782dd114220aa2562b5bd29755fc2bdd0fa.1315597137.git.git@drmicha.warpmail.net","subject":"Re: [PATCH] t3200: test branch creation with -v","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-09T19:43:57Z","receivedAt":"2011-09-09T19:43:57Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Sep 09, 2011 at 09:40:59PM +0200, Michael J Gruber wrote:\n\n> +test_expect_success 'git branch -v t should work' '\n> +\tgit branch -v t &&\n> +\ttest .git/refs/heads/t &&\n\ntest -f ?\n\nAlso, don't we have test_path_is_file which yields slightly prettier\noutput (and maybe some portability benefits; I don't remember)?\n\n> +\tgit branch -d t &&\n> +\ttest ! -f .git/refs/heads/t\n\nDitto for 'test_path_is_missing' here.\n\n-Peff\n"},{"id":"175237","messageId":"20110909194538.GA31721@sigill.intra.peff.net","threadId":"27997","inReplyTo":"20110909194357.GA31446@sigill.intra.peff.net","subject":"Re: [PATCH] t3200: test branch creation with -v","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-09T19:45:38Z","receivedAt":"2011-09-09T19:45:38Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Sep 09, 2011 at 03:43:57PM -0400, Jeff King wrote:\n\n> On Fri, Sep 09, 2011 at 09:40:59PM +0200, Michael J Gruber wrote:\n> \n> > +test_expect_success 'git branch -v t should work' '\n> > +\tgit branch -v t &&\n> > +\ttest .git/refs/heads/t &&\n> \n> test -f ?\n\nHmm, this also seems to be a problem in the other tests, too.\n\n-Peff\n"},{"id":"175275","messageId":"4E6B6647.7090802@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110909194357.GA31446@sigill.intra.peff.net","subject":"Re: [PATCH] t3200: test branch creation with -v","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-10T13:29:43Z","receivedAt":"2011-09-10T13:29:43Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 09.09.2011 21:43:\n> On Fri, Sep 09, 2011 at 09:40:59PM +0200, Michael J Gruber wrote:\n> \n>> +test_expect_success 'git branch -v t should work' ' +\tgit branch\n>> -v t && +\ttest .git/refs/heads/t &&\n> \n> test -f ?\n> \n> Also, don't we have test_path_is_file which yields slightly prettier \n> output (and maybe some portability benefits; I don't remember)?\n> \n>> +\tgit branch -d t && +\ttest ! -f .git/refs/heads/t\n> \n> Ditto for 'test_path_is_missing' here.\n> \n> -Peff\n\nWell, I tried to follow the surrounding style. That t3200 could benefit\nfrom some attention, though, which I did not want to mix in with the\nissue at hand.\n\nMichael\n"},{"id":"175383","messageId":"20110913035724.GA4828@sigill.intra.peff.net","threadId":"27997","inReplyTo":"4E6B6647.7090802@drmicha.warpmail.net","subject":"Re: [PATCH] t3200: test branch creation with -v","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-13T03:57:24Z","receivedAt":"2011-09-13T03:57:24Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Sep 10, 2011 at 03:29:43PM +0200, Michael J Gruber wrote:\n\n> Jeff King venit, vidit, dixit 09.09.2011 21:43:\n> > On Fri, Sep 09, 2011 at 09:40:59PM +0200, Michael J Gruber wrote:\n> > \n> >> +test_expect_success 'git branch -v t should work' ' +\tgit branch\n> >> -v t && +\ttest .git/refs/heads/t &&\n> > \n> > test -f ?\n> > \n> > Also, don't we have test_path_is_file which yields slightly prettier \n> > output (and maybe some portability benefits; I don't remember)?\n> > \n> >> +\tgit branch -d t && +\ttest ! -f .git/refs/heads/t\n> > \n> > Ditto for 'test_path_is_missing' here.\n> > \n> > -Peff\n> \n> Well, I tried to follow the surrounding style. That t3200 could benefit\n> from some attention, though, which I did not want to mix in with the\n> issue at hand.\n\nThe \"test_path_is_file\" thing is style. But not using \"test -f\" is just\nwrong; you are testing \"is .git/refs/heads/t an empty string?\" which is\nuseless.\n\nYou want this on top of what's in mg/branch-list:\n\ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex c466b20..b513115 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -100,14 +100,14 @@ test_expect_success 'git branch -m q r/q should fail when r exists' '\n \n test_expect_success 'git branch -v -d t should work' '\n \tgit branch t &&\n-\ttest .git/refs/heads/t &&\n+\ttest -f .git/refs/heads/t &&\n \tgit branch -v -d t &&\n \ttest ! -f .git/refs/heads/t\n '\n \n test_expect_success 'git branch -v -m t s should work' '\n \tgit branch t &&\n-\ttest .git/refs/heads/t &&\n+\ttest -f .git/refs/heads/t &&\n \tgit branch -v -m t s &&\n \ttest ! -f .git/refs/heads/t &&\n \ttest -f .git/refs/heads/s &&\n@@ -116,7 +116,7 @@ test_expect_success 'git branch -v -m t s should work' '\n \n test_expect_success 'git branch -m -d t s should fail' '\n \tgit branch t &&\n-\ttest .git/refs/heads/t &&\n+\ttest -f .git/refs/heads/t &&\n \ttest_must_fail git branch -m -d t s &&\n \tgit branch -d t &&\n \ttest ! -f .git/refs/heads/t\n@@ -124,7 +124,7 @@ test_expect_success 'git branch -m -d t s should fail' '\n \n test_expect_success 'git branch --list -d t should fail' '\n \tgit branch t &&\n-\ttest .git/refs/heads/t &&\n+\ttest -f .git/refs/heads/t &&\n \ttest_must_fail git branch --list -d t &&\n \tgit branch -d t &&\n \ttest ! -f .git/refs/heads/t\n\nI suspect you didn't notice the bogosity before because those are just\nconfirming the precondition that \"git branch\" actually created the file.\n\n-Peff\n"},{"id":"175399","messageId":"4E6F48C4.3030407@drmicha.warpmail.net","threadId":"27997","inReplyTo":"20110913035724.GA4828@sigill.intra.peff.net","subject":"Re: [PATCH] t3200: test branch creation with -v","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-13T12:12:52Z","receivedAt":"2011-09-13T12:12:52Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 13.09.2011 05:57:\n> On Sat, Sep 10, 2011 at 03:29:43PM +0200, Michael J Gruber wrote:\n> \n>> Jeff King venit, vidit, dixit 09.09.2011 21:43:\n>>> On Fri, Sep 09, 2011 at 09:40:59PM +0200, Michael J Gruber wrote:\n>>>\n>>>> +test_expect_success 'git branch -v t should work' ' +\tgit branch\n>>>> -v t && +\ttest .git/refs/heads/t &&\n>>>\n>>> test -f ?\n>>>\n>>> Also, don't we have test_path_is_file which yields slightly prettier \n>>> output (and maybe some portability benefits; I don't remember)?\n>>>\n>>>> +\tgit branch -d t && +\ttest ! -f .git/refs/heads/t\n>>>\n>>> Ditto for 'test_path_is_missing' here.\n>>>\n>>> -Peff\n>>\n>> Well, I tried to follow the surrounding style. That t3200 could benefit\n>> from some attention, though, which I did not want to mix in with the\n>> issue at hand.\n> \n> The \"test_path_is_file\" thing is style. But not using \"test -f\" is just\n> wrong; you are testing \"is .git/refs/heads/t an empty string?\" which is\n> useless.\n> \n> You want this on top of what's in mg/branch-list:\n\nYes, sorry. How did I miss that?\n\nI'd prefer your style anyway, but also prefer changing t3200 in one go.\n\n> \n> diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\n> index c466b20..b513115 100755\n> --- a/t/t3200-branch.sh\n> +++ b/t/t3200-branch.sh\n> @@ -100,14 +100,14 @@ test_expect_success 'git branch -m q r/q should fail when r exists' '\n>  \n>  test_expect_success 'git branch -v -d t should work' '\n>  \tgit branch t &&\n> -\ttest .git/refs/heads/t &&\n> +\ttest -f .git/refs/heads/t &&\n>  \tgit branch -v -d t &&\n>  \ttest ! -f .git/refs/heads/t\n>  '\n>  \n>  test_expect_success 'git branch -v -m t s should work' '\n>  \tgit branch t &&\n> -\ttest .git/refs/heads/t &&\n> +\ttest -f .git/refs/heads/t &&\n>  \tgit branch -v -m t s &&\n>  \ttest ! -f .git/refs/heads/t &&\n>  \ttest -f .git/refs/heads/s &&\n> @@ -116,7 +116,7 @@ test_expect_success 'git branch -v -m t s should work' '\n>  \n>  test_expect_success 'git branch -m -d t s should fail' '\n>  \tgit branch t &&\n> -\ttest .git/refs/heads/t &&\n> +\ttest -f .git/refs/heads/t &&\n>  \ttest_must_fail git branch -m -d t s &&\n>  \tgit branch -d t &&\n>  \ttest ! -f .git/refs/heads/t\n> @@ -124,7 +124,7 @@ test_expect_success 'git branch -m -d t s should fail' '\n>  \n>  test_expect_success 'git branch --list -d t should fail' '\n>  \tgit branch t &&\n> -\ttest .git/refs/heads/t &&\n> +\ttest -f .git/refs/heads/t &&\n>  \ttest_must_fail git branch --list -d t &&\n>  \tgit branch -d t &&\n>  \ttest ! -f .git/refs/heads/t\n> \n> I suspect you didn't notice the bogosity before because those are just\n> confirming the precondition that \"git branch\" actually created the file.\n> \n> -Peff\n"},{"id":"175403","messageId":"20110913161358.GB28634@sigill.intra.peff.net","threadId":"27997","inReplyTo":"4E6F48C4.3030407@drmicha.warpmail.net","subject":"[PATCH] t3200: clean up checks for file existence","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-13T16:13:58Z","receivedAt":"2011-09-13T16:13:58Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"This patch uses test_path_is_file and test_path_is_missing\ninstead of \"test -f / ! test -f\" checks. The former are more\nverbose in case of failure and more precise (e.g., is_missing\nwill check that the entry is actually missing, not just not\na regular file).\n\nAs a bonus, this also fixes a few buggy tests that used\n\"test foo\" instead of \"test -f foo\", and consequently always\nreported success.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nOn Tue, Sep 13, 2011 at 02:12:52PM +0200, Michael J Gruber wrote:\n\n> I'd prefer your style anyway, but also prefer changing t3200 in one go.\n\nHere it is, on top of mg/branch-list. The \"test without -f\" bits could\nactually be squashed in to your commits if we really want clean history,\nbut I don't think it's a big deal.\n\n t/t3200-branch.sh |   50 +++++++++++++++++++++++++-------------------------\n 1 files changed, 25 insertions(+), 25 deletions(-)\n\ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex c466b20..3988ec9 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -23,7 +23,7 @@ test_expect_success \\\n test_expect_success \\\n     'git branch --help should not have created a bogus branch' '\n      git branch --help </dev/null >/dev/null 2>/dev/null;\n-     ! test -f .git/refs/heads/--help\n+     test_path_is_missing .git/refs/heads/--help\n '\n \n test_expect_success 'branch -h in broken repository' '\n@@ -39,11 +39,11 @@ test_expect_success 'branch -h in broken repository' '\n \n test_expect_success \\\n     'git branch abc should create a branch' \\\n-    'git branch abc && test -f .git/refs/heads/abc'\n+    'git branch abc && test_path_is_file .git/refs/heads/abc'\n \n test_expect_success \\\n     'git branch a/b/c should create a branch' \\\n-    'git branch a/b/c && test -f .git/refs/heads/a/b/c'\n+    'git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c'\n \n cat >expect <<EOF\n $_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000\tbranch: Created from master\n@@ -52,15 +52,15 @@ test_expect_success \\\n     'git branch -l d/e/f should create a branch and a log' \\\n \t'GIT_COMMITTER_DATE=\"2005-05-26 23:30\" \\\n      git branch -l d/e/f &&\n-\t test -f .git/refs/heads/d/e/f &&\n-\t test -f .git/logs/refs/heads/d/e/f &&\n+\t test_path_is_file .git/refs/heads/d/e/f &&\n+\t test_path_is_file .git/logs/refs/heads/d/e/f &&\n \t test_cmp expect .git/logs/refs/heads/d/e/f'\n \n test_expect_success \\\n     'git branch -d d/e/f should delete a branch and a log' \\\n \t'git branch -d d/e/f &&\n-\t test ! -f .git/refs/heads/d/e/f &&\n-\t test ! -f .git/logs/refs/heads/d/e/f'\n+\t test_path_is_missing .git/refs/heads/d/e/f &&\n+\t test_path_is_missing .git/logs/refs/heads/d/e/f'\n \n test_expect_success \\\n     'git branch j/k should work after branch j has been deleted' \\\n@@ -78,13 +78,13 @@ test_expect_success \\\n     'git branch -m m m/m should work' \\\n        'git branch -l m &&\n         git branch -m m m/m &&\n-        test -f .git/logs/refs/heads/m/m'\n+        test_path_is_file .git/logs/refs/heads/m/m'\n \n test_expect_success \\\n     'git branch -m n/n n should work' \\\n        'git branch -l n/n &&\n         git branch -m n/n n\n-        test -f .git/logs/refs/heads/n'\n+        test_path_is_file .git/logs/refs/heads/n'\n \n test_expect_success 'git branch -m o/o o should fail when o/p exists' '\n \tgit branch o/o &&\n@@ -100,34 +100,34 @@ test_expect_success 'git branch -m q r/q should fail when r exists' '\n \n test_expect_success 'git branch -v -d t should work' '\n \tgit branch t &&\n-\ttest .git/refs/heads/t &&\n+\ttest_path_is_file .git/refs/heads/t &&\n \tgit branch -v -d t &&\n-\ttest ! -f .git/refs/heads/t\n+\ttest_path_is_missing .git/refs/heads/t\n '\n \n test_expect_success 'git branch -v -m t s should work' '\n \tgit branch t &&\n-\ttest .git/refs/heads/t &&\n+\ttest_path_is_file .git/refs/heads/t &&\n \tgit branch -v -m t s &&\n-\ttest ! -f .git/refs/heads/t &&\n-\ttest -f .git/refs/heads/s &&\n+\ttest_path_is_missing .git/refs/heads/t &&\n+\ttest_path_is_file .git/refs/heads/s &&\n \tgit branch -d s\n '\n \n test_expect_success 'git branch -m -d t s should fail' '\n \tgit branch t &&\n-\ttest .git/refs/heads/t &&\n+\ttest_path_is_file .git/refs/heads/t &&\n \ttest_must_fail git branch -m -d t s &&\n \tgit branch -d t &&\n-\ttest ! -f .git/refs/heads/t\n+\ttest_path_is_missing .git/refs/heads/t\n '\n \n test_expect_success 'git branch --list -d t should fail' '\n \tgit branch t &&\n-\ttest .git/refs/heads/t &&\n+\ttest_path_is_file .git/refs/heads/t &&\n \ttest_must_fail git branch --list -d t &&\n \tgit branch -d t &&\n-\ttest ! -f .git/refs/heads/t\n+\ttest_path_is_missing .git/refs/heads/t\n '\n \n mv .git/config .git/config-saved\n@@ -144,12 +144,12 @@ git config branch.s/s.dummy Hello\n test_expect_success \\\n     'git branch -m s/s s should work when s/t is deleted' \\\n        'git branch -l s/s &&\n-        test -f .git/logs/refs/heads/s/s &&\n+        test_path_is_file .git/logs/refs/heads/s/s &&\n         git branch -l s/t &&\n-        test -f .git/logs/refs/heads/s/t &&\n+        test_path_is_file .git/logs/refs/heads/s/t &&\n         git branch -d s/t &&\n         git branch -m s/s s &&\n-        test -f .git/logs/refs/heads/s'\n+        test_path_is_file .git/logs/refs/heads/s'\n \n test_expect_success 'config information was renamed, too' \\\n \t\"test $(git config branch.s.dummy) = Hello &&\n@@ -160,8 +160,8 @@ test_expect_success 'renaming a symref is not allowed' \\\n \tgit symbolic-ref refs/heads/master2 refs/heads/master &&\n \ttest_must_fail git branch -m master2 master3 &&\n \tgit symbolic-ref refs/heads/master2 &&\n-\ttest -f .git/refs/heads/master &&\n-\t! test -f .git/refs/heads/master3\n+\ttest_path_is_file .git/refs/heads/master &&\n+\ttest_path_is_missing .git/refs/heads/master3\n '\n \n test_expect_success SYMLINKS \\\n@@ -270,8 +270,8 @@ test_expect_success \\\n     'git checkout -b g/h/i -l should create a branch and a log' \\\n \t'GIT_COMMITTER_DATE=\"2005-05-26 23:30\" \\\n      git checkout -b g/h/i -l master &&\n-\t test -f .git/refs/heads/g/h/i &&\n-\t test -f .git/logs/refs/heads/g/h/i &&\n+\t test_path_is_file .git/refs/heads/g/h/i &&\n+\t test_path_is_file .git/logs/refs/heads/g/h/i &&\n \t test_cmp expect .git/logs/refs/heads/g/h/i'\n \n test_expect_success 'checkout -b makes reflog by default' '\n-- \n1.7.7.rc1.2.gb2409\n"},{"id":"175407","messageId":"7v62kwxt4b.fsf@alter.siamese.dyndns.org","threadId":"27997","inReplyTo":"20110913161358.GB28634@sigill.intra.peff.net","subject":"Re: [PATCH] t3200: clean up checks for file existence","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-13T17:13:56Z","receivedAt":"2011-09-13T17:13:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Here it is, on top of mg/branch-list. The \"test without -f\" bits could\n> actually be squashed in to your commits if we really want clean history,\n> but I don't think it's a big deal.\n\nThanks.\n\nIn the longer term, we might want to update these tests further so that\nthey do not fail when implementation is updated not to write loose refs,\ne.g.\n\n>  test_expect_success \\\n>      'git branch abc should create a branch' \\\n> -    'git branch abc && test -f .git/refs/heads/abc'\n> +    'git branch abc && test_path_is_file .git/refs/heads/abc'\n\n    git branch abc && git show-ref -q --verify refs/heads/abc\n\nBut this patch is about correctness first, so I'll queue it as-is.\n \n"},{"id":"175410","messageId":"20110913171612.GB32251@sigill.intra.peff.net","threadId":"27997","inReplyTo":"7v62kwxt4b.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] t3200: clean up checks for file existence","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-13T17:16:12Z","receivedAt":"2011-09-13T17:16:12Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Sep 13, 2011 at 10:13:56AM -0700, Junio C Hamano wrote:\n\n> In the longer term, we might want to update these tests further so that\n> they do not fail when implementation is updated not to write loose refs,\n> e.g.\n\nYeah, I noticed that, too, but figured to leave it for when such a\nchange came about (which is probably going to need to fix tests\neverywhere, not just here). I'm happy to fix this area now, though, if\nyou want.\n\n-Peff\n"}]}