branch: list branches by single remote
RFC 1/1 branch: list branches by single remote
I've always missed some option for "git branch" to limit the output to a single remote. What's the right place to filter the output? The code below doesn't look very smart..
--- builtin/branch.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-)
builtin/branch.c +13 -3
@@ -17,7 +17,7 @@#include "revision.h" static const char *const builtin_branch_usage[] = { -"git branch [options] [-r | -a] [--merged | --no-merged]" , +"git branch [options] [-r | -a] [-R <remote>] [--merged | --no-merged]" ,"git branch [options] [-l] [-f] <branchname> [<start-point>]" ,"git branch [options] [-r] (-d | -D) <branchname>..." ,"git branch [options] (-m | -M) [<oldbranch>] <newbranch>" ,
@@ -260,6 +260,7 @@ static char *resolve_symref(const char *src, const char *prefix)struct append_ref_cb {struct ref_list *ref_list; +const char *remote;int ret; };
@@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ; +if (cb->remote &&strncmp (cb->remote, refname,strlen (cb->remote))) +return 0 ; + commit =NULL ;if (ref_list->verbose || ref_list->with_commit || merge_filter !=NO_FILTER ) { commit =lookup_commit_reference_gently (sha1,1 );
@@ -492,7 +496,7 @@ static void show_detached(struct ref_list *ref_list) } } -static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit) +static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit,const char *only) {int i;struct append_ref_cb cb;
@@ -506,6 +510,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struif (merge_filter !=NO_FILTER )init_revisions (&ref_list.revs,NULL ); cb.ref_list = &ref_list; + cb.remote = only; cb.ret =0 ;for_each_rawref (append_ref, &cb);if (merge_filter !=NO_FILTER ) {
@@ -618,6 +623,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)enum branch_track track;int kinds =REF_LOCAL_BRANCH ;struct commit_list *with_commit =NULL ; +char *single_remote =NULL ;struct option options[] = {OPT_GROUP ("Generic options" ),
@@ -647,6 +653,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT_GROUP ("Specific git-branch actions:" ),OPT_SET_INT ('a' ,NULL , &kinds,"list both remote-tracking and local branches" ,REF_REMOTE_BRANCH |REF_LOCAL_BRANCH ), +OPT_STRING ('R' ,NULL , &single_remote,"remote" ,"list only branches by remote" ),OPT_BIT ('d' ,NULL , &delete,"delete fully merged branch" ,1 ),OPT_BIT ('D' ,NULL , &delete,"delete branch (even if not merged)" ,2 ), OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1),
@@ -696,10 +703,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (!!delete + !!rename + !!force_create >1 )usage_with_options (builtin_branch_usage, options); +if (single_remote) + kinds =REF_REMOTE_BRANCH ; +if (delete)return delete_branches (argc, argv, delete >1 , kinds);else if (argc ==0 ) -return print_ref_list (kinds, detached, verbose, abbrev, with_commit); +return print_ref_list (kinds, detached, verbose, abbrev, with_commit, single_remote);else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );else if (rename && (argc ==2 ))
Signature · 1 line
1.7.6.396.ge0613.dirty
builtin/branch.c static int append_ref(const char *refname, const unsigned char *sha1, int flags, · line 303
Quoted 7 lines · Michael Schubert
builtin/branch.c +3
-0@@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ; +if (cb->remote &&strncmp (cb->remote, refname,strlen (cb->remote))) +return 0 ; +
This isn't right. You are assuming that a remote called "foo" will have all of its branches in refs/remotes/foo. That's true under the default configuration, but technically speaking, the remote tracking branches of "foo" are defined by the right-hand side of foo's fetch refspecs.
So I think you want something more like this:
int i;
struct remote *remote = remote_get("foo");
for (i = 0; i < remote->fetch_refspec_nr; i++) {
struct refspec *rs = remote->fetch + i; /* if it's not a wildcard, then take the rhs verbatim */
if (!rs->pattern)
append_ref(rs->dst);
else {
/* it's a wildcard like refs/remotes/foo/*; glob in
* the ref list appropriately. Or we can cheat, noting
* that git's only allowed wildcard is "/*" at the
* end, and do this: */
char *prefix = xstrndup(rs->dst, strlen(rs->dst) - 1);
for_each_ref_in(prefix, append_ref, NULL);
}}
instead of the call to "for_each_rawref(append_ref, ...)" that would normally be used. You could even pretty easily allow selecting branches from multiple remotes, too, though I don't know if that is actually useful.
-Peff
Jeff King venit, vidit, dixit 04.08.2011 06:06:
Quoted 6 lines · Michael Schubert
Quoted 5 lines
builtin/branch.c +0
-0@@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ;
Quoted 8 lines
builtin/branch.c static int append_ref(const char *refname, const unsigned char *sha1, int flags, · line 303
Quoted 3 lines
builtin/branch.c +3
-0+if (cb->remote &&strncmp (cb->remote, refname,strlen (cb->remote))) +return 0 ; +This isn't right. You are assuming that a remote called "foo" will have all of its branches in refs/remotes/foo. That's true under the default configuration, but technically speaking, the remote tracking branches of "foo" are defined by the right-hand side of foo's fetch refspecs.
You are 100% right here, but...
Quoted 1 line
So I think you want something more like this:
...the op still might want to filter simply by the remote name.
Reminds me that I have to resurrect my patterns-with-branches series....
Michael
Quoted 10 lines · Michael J Gruber
Quoted 4 lines
This isn't right. You are assuming that a remote called "foo" will have all of its branches in refs/remotes/foo. That's true under the default configuration, but technically speaking, the remote tracking branches of "foo" are defined by the right-hand side of foo's fetch refspecs.
You are 100% right here, but...
Quoted 1 line
So I think you want something more like this:
...the op still might want to filter simply by the remote name.
That is a perfectly reasonable approach. It just should be called "--glob" or something, and not "remote". git-tag allows patterns to an explicit "tag -l", but "-l" is already taken for git-branch.
Quoted 1 line
Reminds me that I have to resurrect my patterns-with-branches series....
Please do. I think it's a much simpler and more versatile solution to the same problem.
-Peff
Quoted 9 lines · Jeff King
Quoted 7 lines · Michael J Gruber
Quoted 4 lines
This isn't right. You are assuming that a remote called "foo" will have all of its branches in refs/remotes/foo. That's true under the default configuration, but technically speaking, the remote tracking branches of "foo" are defined by the right-hand side of foo's fetch refspecs.
You are 100% right here, but...
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
So I think you want something more like this:
...the op still might want to filter simply by the remote name.
That is a perfectly reasonable approach. It just should be called "--glob" or something, and not "remote". git-tag allows patterns to an explicit "tag -l", but "-l" is already taken for git-branch.
As suggested, I've just called it "--glob" for now.
--- 8< ---
Subject: [PATCH] branch: add option "glob" to filter listed branches
When calling "git branch" with either "-r" or "-a", there is no way to further limit the output. Add an option "--glob=<pattern>" to allow limiting the output to matching branch names.
--- Documentation/git-branch.txt | 8 ++++++-- builtin/branch.c | 13 ++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-)
Documentation/git-branch.txt +6 -2
@@ -8,7 +8,7 @@ git-branch - List, create, or delete branches SYNOPSIS -------- [verse] -'git branch' [--color[=<when>] | --no-color] [-r | -a] +'git branch' [--color[=<when>] | --no-color] [(-r | -a) [--glob=<pattern>]] [-v [--abbrev=<length> | --no-abbrev]] [(--merged | --no-merged | --contains) [<commit>]] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
@@ -20,7 +20,8 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking -branches to be listed, and option `-a` shows both. +branches to be listed, option `-a` shows both and `--glob` limits the +output to branches matching <pattern>. With `--contains`, shows only the branches that contain the named commit (in other words, the branches whose tip commits are descendants of the
@@ -105,6 +106,9 @@ OPTIONS -a:: List both remote-tracking branches and local branches. +--glob=<pattern>:: + List only branches matching pattern. + -v:: --verbose:: Show sha1 and commit subject line for each head, along with
builtin/branch.c +10 -3
@@ -17,7 +17,7 @@#include "revision.h" static const char *const builtin_branch_usage[] = { -"git branch [options] [-r | -a] [--merged | --no-merged]" , +"git branch [options] [(-r | -a) [--glob=<pattern>]] [--merged | --no-merged]" ,"git branch [options] [-l] [-f] <branchname> [<start-point>]" ,"git branch [options] [-r] (-d | -D) <branchname>..." ,"git branch [options] (-m | -M) [<oldbranch>] <newbranch>" ,
@@ -260,6 +260,7 @@ static char *resolve_symref(const char *src, const char *prefix)struct append_ref_cb {struct ref_list *ref_list; +const char *glob;int ret; };
@@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ; +if (cb->glob &&fnmatch (cb->glob, refname,0 )) +return 0 ; + commit =NULL ;if (ref_list->verbose || ref_list->with_commit || merge_filter !=NO_FILTER ) { commit =lookup_commit_reference_gently (sha1,1 );
@@ -492,7 +496,7 @@ static void show_detached(struct ref_list *ref_list) } } -static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit) +static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit,const char *glob) {int i;struct append_ref_cb cb;
@@ -506,6 +510,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struif (merge_filter !=NO_FILTER )init_revisions (&ref_list.revs,NULL ); cb.ref_list = &ref_list; + cb.glob = glob; cb.ret =0 ;for_each_rawref (append_ref, &cb);if (merge_filter !=NO_FILTER ) {
@@ -618,6 +623,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)enum branch_track track;int kinds =REF_LOCAL_BRANCH ;struct commit_list *with_commit =NULL ; +char *glob =NULL ;struct option options[] = {OPT_GROUP ("Generic options" ),
@@ -647,6 +653,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT_GROUP ("Specific git-branch actions:" ),OPT_SET_INT ('a' ,NULL , &kinds,"list both remote-tracking and local branches" ,REF_REMOTE_BRANCH |REF_LOCAL_BRANCH ), +OPT_STRING (0 ,"glob" , &glob,"pattern" ,"list only branches matching the pattern" ),OPT_BIT ('d' ,NULL , &delete,"delete fully merged branch" ,1 ),OPT_BIT ('D' ,NULL , &delete,"delete branch (even if not merged)" ,2 ), OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1),
@@ -699,7 +706,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (delete)return delete_branches (argc, argv, delete >1 , kinds);else if (argc ==0 ) -return print_ref_list (kinds, detached, verbose, abbrev, with_commit); +return print_ref_list (kinds, detached, verbose, abbrev, with_commit, glob);else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );else if (rename && (argc ==2 ))
Signature · 1 line
1.7.6.577.g8d918.dirty
Michael Schubert venit, vidit, dixit 24.08.2011 17:14:
Quoted 12 lines · Jeff King
Quoted 11 lines · Michael J Gruber
Quoted 10 lines
Quoted 5 lines
This isn't right. You are assuming that a remote called "foo" will have all of its branches in refs/remotes/foo. That's true under the default configuration, but technically speaking, the remote tracking branches of "foo" are defined by the right-hand side of foo's fetch refspecs.
You are 100% right here, but...
Quoted 1 line
So I think you want something more like this:
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
...the op still might want to filter simply by the remote name.
That is a perfectly reasonable approach. It just should be called "--glob" or something, and not "remote". git-tag allows patterns to an explicit "tag -l", but "-l" is already taken for git-branch.
As suggested, I've just called it "--glob" for now.
Well, again, what's the point in replicating
http://permalink.gmane.org/gmane.comp.version-control.git/172228
and how is it different?
As I've mentioned, I've been in the middle of polishing that up. You can follow it if you like:
http://repo.or.cz/w/git/mjg.git/shortlog/refs/heads/branch-list-pattern
Also, again: git branch is much more like git tag than it is like git log, so I think the pattern matching options should be, too.
Michael
Quoted 19 lines · Michael J Gruber
Michael Schubert venit, vidit, dixit 24.08.2011 17:14:
Quoted 18 lines · Jeff King
Quoted 16 lines · Michael J Gruber
Quoted 11 lines
Quoted 5 lines
This isn't right. You are assuming that a remote called "foo" will have all of its branches in refs/remotes/foo. That's true under the default configuration, but technically speaking, the remote tracking branches of "foo" are defined by the right-hand side of foo's fetch refspecs.
You are 100% right here, but...
Quoted 1 line
So I think you want something more like this:
...the op still might want to filter simply by the remote name.
That is a perfectly reasonable approach. It just should be called "--glob" or something, and not "remote". git-tag allows patterns to an explicit "tag -l", but "-l" is already taken for git-branch.
Quoted 7 lines
Quoted 1 line
As suggested, I've just called it "--glob" for now.
Well, again, what's the point in replicating
http://permalink.gmane.org/gmane.comp.version-control.git/172228
and how is it different?
While I just haven't seen this,
Quoted 4 lines
As I've mentioned, I've been in the middle of polishing that up. You can follow it if you like:
http://repo.or.cz/w/git/mjg.git/shortlog/refs/heads/branch-list-pattern
I thought I just send it out not knowing you're actually into resurrecting the "patterns-with-branches series".
Thanks.
Quoted 8 lines · Michael J Gruber
Quoted 1 line
As suggested, I've just called it "--glob" for now.
Well, again, what's the point in replicating
http://permalink.gmane.org/gmane.comp.version-control.git/172228
and how is it different?
As I've mentioned, I've been in the middle of polishing that up.
It is not unusual for a similar itch to happen to different people independently.
If this were something you reposted even a WIP re-polish within the past two weeks, I would understand and even sympathise with your irritation, but please don't expect everybody to dig back FOUR MONTHS worth of mail backlog to find an topic that may or may not be abandoned by the original author. Perhaps we would need a weekly posting of topics people have posted, found to be not quite ready yet, and are still being polished and not abandoned [*1*]?
Having said that, I still appreciate that you posted a link to the previous topic:
http://thread.gmane.org/gmane.comp.version-control.git/172226
so that the discussions in this thread to scratch the same "itch" can benefit from the points raised in the previous thread that need to be considered.
The old thread talks about renaming existing options and transition plans to make the "listing" mode of "branch" and "tag" more similar, which may be a good plan in the longer term.
I however can see that teaching "--glob" to both "branch" and "tag" (in other words, "tag -l" would become a synonym for "tag --glob") an equally good longer term plan.
[Footnote]
*1* It does not have to be a weekly _posting_ on the list but can be a well-known Wiki page or even a bug tracker. Whatever medium is used for this purpose, there _must_ be a built-in mechanism to expire entries away that are inactive for more than some reasonable limit (say two to three weeks).
Junio C Hamano venit, vidit, dixit 24.08.2011 20:34:
Quoted 11 lines
Quoted 8 lines · Michael J Gruber
Quoted 1 line
As suggested, I've just called it "--glob" for now.
Well, again, what's the point in replicating
http://permalink.gmane.org/gmane.comp.version-control.git/172228
and how is it different?
As I've mentioned, I've been in the middle of polishing that up.
Quoted 8 lines
It is not unusual for a similar itch to happen to different people independently.
If this were something you reposted even a WIP re-polish within the past two weeks, I would understand and even sympathise with your irritation, but please don't expect everybody to dig back FOUR MONTHS worth of mail backlog to find an topic that may or may not be abandoned by the original author. Perhaps we would need a weekly posting of topics people have
Well, I've mentioned it earlier in this thread, though without a link. It's the time when several of us are off-line for a couple weeks. I've also mentioned it in the thread about filtering by remote.
On a side note, the list here usually does require people to search back, and much longer than this, on frequently requested issues. But how does a newcomer discover "frequently"? Right, by searching back years, not months.
Quoted 12 lines
posted, found to be not quite ready yet, and are still being polished and not abandoned [*1*]?
Having said that, I still appreciate that you posted a link to the previous topic:
http://thread.gmane.org/gmane.comp.version-control.git/172226
so that the discussions in this thread to scratch the same "itch" can benefit from the points raised in the previous thread that need to be considered.
Quoted 7 lines
The old thread talks about renaming existing options and transition plans to make the "listing" mode of "branch" and "tag" more similar, which may be a good plan in the longer term.
I however can see that teaching "--glob" to both "branch" and "tag" (in other words, "tag -l" would become a synonym for "tag --glob") an equally good longer term plan.
I don't care about the names, but I'd hate to introduce more inconsistencies. The implementation is a non-brainer, it's really something only Apple could get a patent on. The other Michael and I came up with basically the same patch because it follows "automatically". But the ui is important.
So I'll take the opportunity and discuss this further in the cover letter for the upcoming series.
Michael
cover RFC: patterns for branch list
This mini series is about introducing patterns to the list mode of 'git branch' much like the pattern for 'git tag -l'. There are several related things which are to be considered for the ui design:
git log
=======
For "log" and friends, "--glob" is a means to specify revision arguments by matching refs. Note that we have
--branches[=<pattern>] matching in refs/heads
--tags[=<pattern>] matching in refs/tags
--glob=<glob-pattern> matching in refs/
git tag
=======
For "tag", we have a pattern matching in refs/tags, but only in the list mode of "tag", which is invoked by "-l", or automatically when there are no arguments. There is no pattern related option, it's "always on" in list mode. I.e., in list mode it behaves much like
git log --no-walk --oneline --tags=
with a different format string, and an optional argument stuck at the end of the line. (git for-each-ref is another related interface, but plumbing, so I'll skip it here.)
git branch
==========
Analogous to "git tag", "branch" has several modes, one of which is list mode. It is currently activated (and possibly modified) by "-v" and "-vv", and when there are no arguments. So, at the least,
git branch -v[v] <pattern>
should match just like "git tag -l <pattern>" does. And that is what the first patch in my series does.
Then we need an option to invoke list mode. The natural candidate "-l" is taken by the badly named reflog option, which is why I suggested "--list" and moving the reflog option to "-g" over time.
I'm open to other suggestions as long as they keep and improve the consistency between "git tag" and "git branch". I never liked their different implicit modes/subcommands but have been around long enough to know that they are there to stay.
"git tag" should probably learn the same long option and others. And why not verify tags given by a pattern?
Both "tag" and "branch" could activate list mode automatically on an invalid tag name rather than dieing:
git tag v1.7.6\*
Warning: tag 'v1.7.6*' not found.
v1.7.6
v1.7.6-rc0
v1.7.6-rc1
v1.7.6-rc2
v1.7.6-rc3
v1.7.6.1
On the other hand, one might think about implementing both list modes (tag and branch) using the revision machinery and custom format strings, or for-each-ref; rather than both differently as it is now.
'-l' is the natural short option name for '--list'. This is taken for the rarely used or needed 'create reflog' option. I'd change the latter to '-g,--create-reflog' (cmp. log) and take '-l,--list' but know the reaction already.
-v[v] sanity
============
'-v' and '-vv' both take considerable time (because they need to walk). It makes more sense to have '-v' display cheap output (upstream name) and '-vv' add expensive output (ahead/behind info). '-vvv' could add super expensive info (ahead/equivalent/behind a la cherry-mark).
These are changes to current porcelain ui behaviour, so I deem this to be OK (too late for 1.7.7, of course). The option renaming needs a transition (not done in this series).
Michael J Gruber (5):
branch: allow pattern arguments
branch: introduce --list argument
t6040; test branch -vv [independent, can go in as is testing current behaviour]
branch: restructure -v vs. -vv
branch: give patchsame count with -vvv
Documentation/git-branch.txt | 20 +++++++++--- builtin/branch.c | 65 +++++++++++++++++++++++++---------------- remote.c | 12 ++++++-- remote.h | 2 +- t/t3203-branch-output.sh | 24 +++++++++++++++ t/t6040-tracking-info.sh | 41 ++++++++++++++++++++++++-- wt-status.c | 2 +- 7 files changed, 127 insertions(+), 39 deletions(-)
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCH 0/5] RFC: patterns for branch list
Quoted 5 lines · Michael J Gruber
This mini series is about introducing patterns to the list mode of 'git branch' much like the pattern for 'git tag -l'. There are several related things which are to be considered for the ui design:
[log vs tag vs branch]
I agree that the ideal UI change would be to move git-branch's "-l" to "-g", and make "-l|--list" work the same as it does for git-tag.
Even though branch is generally considered a porcelain, I worry a little about making that change. A script that wants to create a branch has no real choice other than to use "git branch" (OK, they can use "update-ref" themselves, but I seriously doubt that most scripts do so). However, I kind of doubt anyone actually uses "-l"; it is mostly pointless in the default config, so maybe it is safe.
Searching google code for "git.branch.*-l" turns up only one hit, and it is somebody who apparently thought that "-l" meant "list".
Quoted 8 lines
Analogous to "git tag", "branch" has several modes, one of which is list mode. It is currently activated (and possibly modified) by "-v" and "-vv", and when there are no arguments. So, at the least,
git branch -v[v] <pattern>
should match just like "git tag -l <pattern>" does. And that is what the first patch in my series does.
The order of your patches seems backwards to me. You add pattern-matching for "-v", but there is no way to get pattern-matching for the non-verbose case. Shouldn't "--list" come first?
Maybe I am just nitpicking, as I think the end result after the series is the same. I just found the first patch very confusing.
Quoted 2 lines
"git tag" should probably learn the same long option and others. And why not verify tags given by a pattern?
Yeah, having them both do --list makes sense. Whether it is appropriate to glob for other operations, I don't know. I think you'd have to look at each operation individually.
Quoted 11 lines
Both "tag" and "branch" could activate list mode automatically on an invalid tag name rather than dieing:
git tag v1.7.6\*
Warning: tag 'v1.7.6*' not found.
v1.7.6
v1.7.6-rc0
v1.7.6-rc1
v1.7.6-rc2
v1.7.6-rc3
v1.7.6.1
That just seems confusing to me. What is the exit status? Shouldn't the warning be "error: tag 'v1.7.6*' is not a valid tag name"?
Quoted 7 lines
-v[v] sanity
============'-v' and '-vv' both take considerable time (because they need to walk). It makes more sense to have '-v' display cheap output (upstream name) and '-vv' add expensive output (ahead/behind info). '-vvv' could add super expensive info (ahead/equivalent/behind a la cherry-mark).
I think the original rationale was not so much "how much time does it take", but rather "how much space do you want each line to take on your terminal". For many people, the upstream name in "-vv" is just cluttering noise.
Tag and branch listing are really just specialized versions of for-each-ref. I wonder if it makes sense to do:
1. Teach for-each-ref formats replacement tokens for ahead/behind counts.
2. Let the user specify a for-each-ref format for tag and branch listing output. Then the various levels of "-v" just become some special format strings, and the user is free to ask for whatever they want (or even have "branch.defaultListFormat" to get it without typing over and over).
-Peff
PATCH v2 1/5 t6040: test branch -vv
t6040 has a test for 'git branch -v' but not for 'git branch -vv'. Add one.
--- t/t6040-tracking-info.sh | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)
t/t6040-tracking-info.sh +16 -0
@@ -51,6 +51,22 @@ test_expect_success 'branch -v' ' test_i18ncmp expect actual ' +cat >expect <<\EOF +b1 origin/master: ahead 1, behind 1 +b2 origin/master: ahead 1, behind 1 +b3 origin/master: behind 1 +b4 origin/master: ahead 2 +EOF + +test_expect_success 'branch -vv' ' + ( + cd test && + git branch -vv + ) | + sed -n -e "$script" >actual && + test_i18ncmp expect actual +' + test_expect_success 'checkout' ' ( cd test && git checkout b1
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCH 0/5] RFC: patterns for branch list
In reply to Jeff KingJeff King venit, vidit, dixit 25.08.2011 19:53:
Quoted 18 lines · Michael J Gruber
Quoted 6 lines
This mini series is about introducing patterns to the list mode of 'git branch' much like the pattern for 'git tag -l'. There are several related things which are to be considered for the ui design:
[log vs tag vs branch]
I agree that the ideal UI change would be to move git-branch's "-l" to "-g", and make "-l|--list" work the same as it does for git-tag.
Even though branch is generally considered a porcelain, I worry a little about making that change. A script that wants to create a branch has no real choice other than to use "git branch" (OK, they can use "update-ref" themselves, but I seriously doubt that most scripts do so). However, I kind of doubt anyone actually uses "-l"; it is mostly pointless in the default config, so maybe it is safe.
Quoted 2 lines
Searching google code for "git.branch.*-l" turns up only one hit, and it is somebody who apparently thought that "-l" meant "list".
;)
Thanks for doing the search.
Quoted 9 lines
Quoted 8 lines
Analogous to "git tag", "branch" has several modes, one of which is list mode. It is currently activated (and possibly modified) by "-v" and "-vv", and when there are no arguments. So, at the least,
git branch -v[v] <pattern>
should match just like "git tag -l <pattern>" does. And that is what the first patch in my series does.
Quoted 6 lines
The order of your patches seems backwards to me. You add pattern-matching for "-v", but there is no way to get pattern-matching for the non-verbose case. Shouldn't "--list" come first?
Maybe I am just nitpicking, as I think the end result after the series is the same. I just found the first patch very confusing.
It's an RFC series to revive the discussion about what to aim for. Agreement about "--list" seems to be growing, so a natural first patch would introduce that.
Quoted 19 lines
Quoted 2 lines
"git tag" should probably learn the same long option and others. And why not verify tags given by a pattern?
Yeah, having them both do --list makes sense. Whether it is appropriate to glob for other operations, I don't know. I think you'd have to look at each operation individually.
Quoted 11 lines
Both "tag" and "branch" could activate list mode automatically on an invalid tag name rather than dieing:
git tag v1.7.6\*
Warning: tag 'v1.7.6*' not found.
v1.7.6
v1.7.6-rc0
v1.7.6-rc1
v1.7.6-rc2
v1.7.6-rc3
v1.7.6.1
Quoted 2 lines
That just seems confusing to me. What is the exit status? Shouldn't the warning be "error: tag 'v1.7.6*' is not a valid tag name"?
Sure, and sorry, copied the wrong one. I'd just like to have the simple way to say "git branch peff/\*" at least as long as we don't have "-l" for "--list".
Quoted 8 lines
Quoted 7 lines
-v[v] sanity
============'-v' and '-vv' both take considerable time (because they need to walk). It makes more sense to have '-v' display cheap output (upstream name) and '-vv' add expensive output (ahead/behind info). '-vvv' could add super expensive info (ahead/equivalent/behind a la cherry-mark).
Quoted 4 lines
I think the original rationale was not so much "how much time does it take", but rather "how much space do you want each line to take on your terminal". For many people, the upstream name in "-vv" is just cluttering noise.
According to my experience, the ahead/behind computations take so much time (in a git.git clone with my devel branches) that they render all "-v" versions unusable, unless I use a restrictive pattern.
On the other hand, I have branches based on all of origin/{master,next} and others, so having the upstream name is valuable.
Seems that I'm an outlier, though.
Quoted 11 lines
Tag and branch listing are really just specialized versions of for-each-ref. I wonder if it makes sense to do:
1. Teach for-each-ref formats replacement tokens for ahead/behind counts.
2. Let the user specify a for-each-ref format for tag and branch listing output. Then the various levels of "-v" just become some special format strings, and the user is free to ask for whatever they want (or even have "branch.defaultListFormat" to get it without typing over and over).
for-each-peff ;)
For a moment, the use of the walker in builtin/branch.c even tricked me into thinking that it might not use for-each-ref at all. God forbid!
I actually like the format suggestion. Then we only need to discuss the default format, which is hopefully less of a problem. But that is something for later, I'll discard the -v[v[v]] patches for now. Have we unified log formats and for-each-ref formats and parsers already, btw? I recall some efforts.
Michael
Re: [PATCH 0/5] RFC: patterns for branch list
Quoted 8 lines · Michael J Gruber
Jeff King venit, vidit, dixit 25.08.2011 19:53:
Quoted 7 lines · Michael J Gruber
Quoted 6 lines
Both "tag" and "branch" could activate list mode automatically on an invalid tag name rather than dieing:
git tag v1.7.6\*
Warning: tag 'v1.7.6*' not found.
If it is not found, the usual action is create it, no?
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
v1.7.6
v1.7.6-rc0
v1.7.6-rc1
v1.7.6-rc2
v1.7.6-rc3
v1.7.6.1
Quoted 6 lines
Quoted 2 lines
That just seems confusing to me. What is the exit status? Shouldn't the warning be "error: tag 'v1.7.6*' is not a valid tag name"?
Sure, and sorry, copied the wrong one. I'd just like to have the simple way to say "git branch peff/\*" at least as long as we don't have "-l" for "--list".
As we use fnmatch() and not match_pathspec() for this pattern matching, "git branch peff/" will not list all the topics under the peff/ hierarchy (your example "git branch peff/\*" would be the way), but I would imagine that we may someday want to update it to allow the leading path match here. And at that point, distinction between
git branch peff ;# to create a "peff" branch
git branch peff/ ;# to list "peff/" branches, as "peff/" itself is
;# an invalid branch name and your auto listing ;# heuristic kicks in
while it might be very useful for experts, becomes too subtle and would confuse new people. We should instead require an explicit -l/--list, and not use the auto listing heuristics (it is fine for -v to imply -l).
Re: [PATCH 0/5] RFC: patterns for branch list
Quoted 6 lines · Junio C Hamano
As we use
fnmatch()and notmatch_pathspec()for this pattern matching, "git branch peff/" will not list all the topics under the peff/ hierarchy (your example "git branch peff/\*" would be the way), but I would imagine that we may someday want to update it to allow the leading path match here. And at that point, distinction between
Quoted 8 lines
git branch peff ;# to create a "peff" branch
git branch peff/ ;# to list "peff/" branches, as "peff/" itself is
;# an invalid branch name and your auto listing ;# heuristic kicks inwhile it might be very useful for experts, becomes too subtle and would confuse new people. We should instead require an explicit -l/--list, and not use the auto listing heuristics (it is fine for -v to imply -l).
Sorry, I'm atrociously behind on reviewing this topic. But FWIW, I completely agree with this. Detecting invalid branch formats is much too subtle and error prone, and we are better off making a short and easy-to-type version of "--list".
-Peff
Re: [PATCH 0/5] RFC: patterns for branch list
Jeff King venit, vidit, dixit 07.09.2011 21:53:
Quoted 13 lines · Junio C Hamano
Quoted 12 lines
As we use
fnmatch()and notmatch_pathspec()for this pattern matching, "git branch peff/" will not list all the topics under the peff/ hierarchy (your example "git branch peff/\*" would be the way), but I would imagine that we may someday want to update it to allow the leading path match here. And at that point, distinction betweengit branch peff ;# to create a "peff" branch
git branch peff/ ;# to list "peff/" branches, as "peff/" itself is
;# an invalid branch name and your auto listing ;# heuristic kicks in
Quoted 8 lines
Quoted 3 lines
while it might be very useful for experts, becomes too subtle and would confuse new people. We should instead require an explicit -l/--list, and not use the auto listing heuristics (it is fine for -v to imply -l).
Sorry, I'm atrociously behind on reviewing this topic. But FWIW, I completely agree with this. Detecting invalid branch formats is much too subtle and error prone, and we are better off making a short and easy-to-type version of "--list".
We all agreed on that, you didn't miss anything ;)
Michael
PATCH v2 2/5 git-tag: introduce long forms for the options
In reply to Jeff KingLong forms are better to memoize, and more reliably uniform across commands.
Design notes:
-u,--local-user is named following the analogous gnupg option.
-l,--list is not an argument taking option but a mode switch.
--- Documentation/git-tag.txt | 8 ++++++++ builtin/tag.c | 16 ++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-)
Documentation/git-tag.txt +8 -0
@@ -43,12 +43,15 @@ GnuPG key for signing. OPTIONS ------- -a:: +--annotate:: Make an unsigned, annotated tag object -s:: +--sign:: Make a GPG-signed tag, using the default e-mail address's key -u <key-id>:: +--local-user=<key-id>:: Make a GPG-signed tag, using the given key -f::
@@ -56,9 +59,11 @@ OPTIONS Replace an existing tag with the given name (instead of failing) -d:: +--delete:: Delete existing tags with the given names. -v:: +--verify:: Verify the gpg signature of the given tag names. -n<num>::
@@ -69,6 +74,7 @@ OPTIONS If the tag is not annotated, the commit message is displayed instead. -l <pattern>:: +--list <pattern>:: List tags with names that match the given pattern (or all if no pattern is given). Running "git tag" without arguments also lists all tags. The pattern is a shell wildcard (i.e., matched
@@ -79,6 +85,7 @@ OPTIONS Only list tags which contain the specified commit. -m <msg>:: +--message=<msg>:: Use the given tag message (instead of prompting). If multiple `-m` options are given, their values are concatenated as separate paragraphs.
@@ -86,6 +93,7 @@ OPTIONS is given. -F <file>:: +--file=<file>:: Take the tag message from the given file. Use '-' to read the message from the standard input. Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
builtin/tag.c +8 -8
@@ -429,21 +429,21 @@ int cmd_tag(int argc, const char **argv, const char *prefix)struct msg_arg msg = {0 ,STRBUF_INIT };struct commit_list *with_commit =NULL ;struct option options[] = { -OPT_BOOLEAN ('l' ,NULL , &list,"list tag names" ), +OPT_BOOLEAN ('l' ,"list" , &list,"list tag names" ), {OPTION_INTEGER ,'n' ,NULL , &lines,"n" ,"print <n> lines of each tag message" ,PARSE_OPT_OPTARG ,NULL ,1 }, -OPT_BOOLEAN ('d' ,NULL , &delete,"delete tags" ), -OPT_BOOLEAN ('v' ,NULL , &verify,"verify tags" ), +OPT_BOOLEAN ('d' ,"delete" , &delete,"delete tags" ), +OPT_BOOLEAN ('v' ,"verify" , &verify,"verify tags" ),OPT_GROUP ("Tag creation options" ), -OPT_BOOLEAN ('a' ,NULL , &annotate, +OPT_BOOLEAN ('a' ,"annotate" , &annotate,"annotated tag, needs a message" ), -OPT_CALLBACK ('m' ,NULL , &msg,"message" , +OPT_CALLBACK ('m' ,"message" , &msg,"message" ,"tag message" , parse_msg_arg), -OPT_FILENAME ('F' ,NULL , &msgfile,"read message from file" ), -OPT_BOOLEAN ('s' ,NULL , &sign,"annotated and GPG-signed tag" ), -OPT_STRING ('u' ,NULL , &keyid,"key-id" , +OPT_FILENAME ('F' ,"file" , &msgfile,"read message from file" ), +OPT_BOOLEAN ('s' ,"sign" , &sign,"annotated and GPG-signed tag" ), +OPT_STRING ('u' ,"local-user" , &keyid,"key-id" ,"use another key to sign the tag" ),OPT__FORCE (&force,"replace the tag if exists" ),
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCHv2 2/5] git-tag: introduce long forms for the options
Quoted 2 lines · Michael J Gruber
Long forms are better to memoize, and more reliably uniform across commands.
I think people "memorize" and machines "memoize"; machines will do so just fine without long forms, but I think you are talking about helping people.
The part after ", and" lacks a verb, making it a non-sentence.
Review
Quoted 5 lines
Design notes:
(quoted diff) +0
-2-u,--local-user is named following the analogous gnupg option. -l,--list is not an argument taking option but a mode switch.
Ok.
The remainder looks good. Thanks.
Re: [PATCHv2 2/5] git-tag: introduce long forms for the options
Junio C Hamano venit, vidit, dixit 26.08.2011 19:11:
Quoted 7 lines
Quoted 2 lines · Michael J Gruber
Long forms are better to memoize, and more reliably uniform across commands.
I think people "memorize" and machines "memoize"; machines will do so just fine without long forms, but I think you are talking about helping people.
Yep.
Quoted 1 line
The part after ", and" lacks a verb, making it a non-sentence.
They are better to memorize, and they are more reliably uniform... Maybe drop the comma?
Quoted 10 lines
Review
Quoted 6 lines
Design notes:
(quoted diff) +0
-2-u,--local-user is named following the analogous gnupg option. -l,--list is not an argument taking option but a mode switch.Ok.
The remainder looks good. Thanks.
PATCH v2 3/5 git-branch: introduce missing long forms for the options
In reply to Jeff KingLong forms are better to memoize, and more reliably uniform across commands.
---
I'm somewhat torn between --move and --rename for -m. We have no real precedent besides "git remote rename".
I left out -M and -D because I feel they should really be -m -f resp. -d -f.
--- Documentation/git-branch.txt | 5 +++++ builtin/branch.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-)
Documentation/git-branch.txt +5 -0
@@ -64,6 +64,7 @@ way to clean up all obsolete remote-tracking branches. OPTIONS ------- -d:: +--delete:: Delete a branch. The branch must be fully merged in its upstream branch, or in `HEAD` if no upstream was set with `--track` or `--set-upstream`.
@@ -72,6 +73,7 @@ OPTIONS Delete a branch irrespective of its merged status. -l:: +--create-reflog:: Create the branch's reflog. This activates recording of all changes made to the branch ref, enabling use of date based sha1 expressions such as "<branchname>@\{yesterday}".
@@ -84,6 +86,7 @@ OPTIONS already. Without `-f` 'git branch' refuses to change an existing branch. -m:: +--move:: Move/rename a branch and the corresponding reflog. -M::
@@ -100,9 +103,11 @@ OPTIONS Same as `--color=never`. -r:: +--remotes:: List or delete (if used with -d) the remote-tracking branches. -a:: +--all:: List both remote-tracking branches and local branches. -v::
builtin/branch.c +5 -5
@@ -624,7 +624,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT_SET_INT (0 ,"set-upstream" , &track,"change upstream info" ,BRANCH_TRACK_OVERRIDE ),OPT__COLOR (&branch_use_color,"use colored output" ), -OPT_SET_INT ('r' ,NULL , &kinds,"act on remote-tracking branches" , +OPT_SET_INT ('r' ,"remotes" , &kinds,"act on remote-tracking branches" ,REF_REMOTE_BRANCH ), { OPTION_CALLBACK, 0, "contains", &with_commit, "commit",
@@ -641,13 +641,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT__ABBREV (&abbrev),OPT_GROUP ("Specific git-branch actions:" ), -OPT_SET_INT ('a' ,NULL , &kinds,"list both remote-tracking and local branches" , +OPT_SET_INT ('a' ,"all" , &kinds,"list both remote-tracking and local branches" ,REF_REMOTE_BRANCH |REF_LOCAL_BRANCH ), -OPT_BIT ('d' ,NULL , &delete,"delete fully merged branch" ,1 ), +OPT_BIT ('d' ,"delete" , &delete,"delete fully merged branch" ,1 ),OPT_BIT ('D' ,NULL , &delete,"delete branch (even if not merged)" ,2 ), -OPT_BIT ('m' ,NULL , &rename,"move/rename a branch and its reflog" ,1 ), +OPT_BIT ('m' ,"move" , &rename,"move/rename a branch and its reflog" ,1 ),OPT_BIT ('M' ,NULL , &rename,"move/rename a branch, even if target exists" ,2 ), -OPT_BOOLEAN ('l' ,NULL , &reflog,"create the branch's reflog" ), +OPT_BOOLEAN ('l' ,"create-reflog" , &reflog,"create the branch's reflog" ),OPT__FORCE (&force_create,"force creation (when already exists)" ), { OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCHv2 3/5] git-branch: introduce missing long forms for the options
Documentation/git-branch.txt OPTIONS · line 107
Quoted 6 lines · Michael J Gruber
Documentation/git-branch.txt +1
-0@@ -100,9 +103,11 @@ OPTIONS Same as `--color=never`. -r:: +--remotes:: List or delete (if used with -d) the remote-tracking branches.
I am not sure if this should be "--remoteS".
Re: [PATCHv2 3/5] git-branch: introduce missing long forms for the options
Junio C Hamano venit, vidit, dixit 26.08.2011 19:13:
Quoted 10 lines
Documentation/git-branch.txt OPTIONS · line 107
Quoted 6 lines · Michael J Gruber
Documentation/git-branch.txt +1
-0@@ -100,9 +103,11 @@ OPTIONS Same as `--color=never`. -r:: +--remotes:: List or delete (if used with -d) the remote-tracking branches.I am not sure if this should be "--remoteS".
like "git log --remotes".
PATCH v2 4/5 branch: introduce --list option
In reply to Jeff KingCurrently, there is no way to invoke the list mode explicitly. Introduce a --list option which invokes the list mode. This will be beneficial for invoking list mode with pattern matching, which otherwise would be interpreted as branch creation.
--- Documentation/git-branch.txt | 9 +++++++-- builtin/branch.c | 12 +++++++++--- t/t3203-branch-output.sh | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-)
Documentation/git-branch.txt +7 -2
@@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git branch' [--color[=<when>] | --no-color] [-r | -a] - [-v [--abbrev=<length> | --no-abbrev]] + [--list] [-v [--abbrev=<length> | --no-abbrev]] [(--merged | --no-merged | --contains) [<commit>]] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>] 'git branch' (-m | -M) [<oldbranch>] <newbranch>
@@ -20,7 +20,8 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking -branches to be listed, and option `-a` shows both. +branches to be listed, and option `-a` shows both. This list mode is also +activated by the `--list` and `-v` options (see below). With `--contains`, shows only the branches that contain the named commit (in other words, the branches whose tip commits are descendants of the
@@ -110,11 +111,15 @@ OPTIONS --all:: List both remote-tracking branches and local branches. +--list:: + Activate the list mode. + -v:: --verbose:: Show sha1 and commit subject line for each head, along with relationship to upstream branch (if any). If given twice, print the name of the upstream branch, as well. + `--list` is implied by all verbosity options. --abbrev=<length>:: Alter the sha1's minimum display length in the output listing.
builtin/branch.c +9 -3
@@ -608,7 +608,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, intint cmd_branch (int argc,const char **argv,const char *prefix) { -int delete =0 , rename =0 , force_create =0 ; +int delete =0 , rename =0 , force_create =0 , list =0 ;int verbose =0 , abbrev =-1 , detached =0 ;int reflog =0 ;enum branch_track track;
@@ -647,6 +647,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT_BIT ('D' ,NULL , &delete,"delete branch (even if not merged)" ,2 ),OPT_BIT ('m' ,"move" , &rename,"move/rename a branch and its reflog" ,1 ),OPT_BIT ('M' ,NULL , &rename,"move/rename a branch, even if target exists" ,2 ), +OPT_BOOLEAN (0 ,"list" , &list,"list branch names" ),OPT_BOOLEAN ('l' ,"create-reflog" , &reflog,"create the branch's reflog" ), OPT__FORCE(&force_create, "force creation (when already exists)"), {
@@ -686,7 +687,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc =parse_options (argc, argv, prefix, options, builtin_branch_usage,0 ); -if (!!delete + !!rename + !!force_create >1 ) + +if (!delete && !rename && !force_create && + (argc ==0 || (verbose && argc))) + list =1 ; + +if (!!delete + !!rename + !!force_create + !!list >1 )usage_with_options (builtin_branch_usage, options);if (abbrev ==-1 )
@@ -694,7 +700,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (delete)return delete_branches (argc, argv, delete >1 , kinds); -else if (argc ==0 ) +else if (list)return print_ref_list (kinds, detached, verbose, abbrev, with_commit);else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );
t/t3203-branch-output.sh +14 -0
@@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' ' test_cmp expect actual ' +test_expect_success 'git branch --list shows local branches' ' + git branch --list >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' + branch-one + branch-two +EOF +test_expect_success 'git branch --list pattern shows matching local branches' ' + git branch --list branch* >actual && + test_cmp expect actual +' + cat >expect <<'EOF' origin/HEAD -> origin/branch-one origin/branch-one
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCHv2 4/5] branch: introduce --list option
Quoted 1 line · Michael J Gruber
Currently, there is no way to invoke the list mode explicitly.
..., without giving -v to force verbose output.
Quoted 8 lines
Introduce a --list option which invokes the list mode. This will be beneficial for invoking list mode with pattern matching, which otherwise would be interpreted as branch creation.
Signed-off-by Michael J Gruber <[email protected]>---
Documentation/git-branch.txt DESCRIPTION · line 24
Quoted 6 lines
Documentation/git-branch.txt +2
-1@@ -20,7 +20,8 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking -branches to be listed, and option `-a` shows both. +branches to be listed, and option `-a` shows both. This list mode is also +activated by the `--list` and `-v` options (see below).
Very good to mention "and -v" here ;-)
Quoted 12 lines
t/t3203-branch-output.sh +4
-0@@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' ' test_cmp expect actual ' +test_expect_success 'git branch --list shows local branches' ' + git branch --list >actual && + test_cmp expect actual +'
t/t3203-branch-output.sh test_expect_success 'git branch shows local branches' ' · line 48
Quoted 10 lines
t/t3203-branch-output.sh +10
-0+ +cat >expect <<'EOF' + branch-one + branch-two +EOF +test_expect_success 'git branch --list pattern shows matching local branches' ' + git branch --list branch* >actual && + test_cmp expect actual +' +
Could we have a test to check the code you updated to sanity check the combination of options as well? I suspect the reason your initial round botched the "branch -v -m foo" without realizing may be because we do not cover the error checking.
Re: [PATCHv2 4/5] branch: introduce --list option
Junio C Hamano venit, vidit, dixit 26.08.2011 19:43:
Quoted 42 lines
Quoted 1 line · Michael J Gruber
Currently, there is no way to invoke the list mode explicitly.
..., without giving -v to force verbose output.
Quoted 8 lines
Introduce a --list option which invokes the list mode. This will be beneficial for invoking list mode with pattern matching, which otherwise would be interpreted as branch creation.
Signed-off-by Michael J Gruber <[email protected]>---
Documentation/git-branch.txt DESCRIPTION · line 24
Quoted 6 lines
Documentation/git-branch.txt +2
-1@@ -20,7 +20,8 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking -branches to be listed, and option `-a` shows both. +branches to be listed, and option `-a` shows both. This list mode is also +activated by the `--list` and `-v` options (see below).Very good to mention "and -v" here ;-)
Quoted 19 lines
t/t3203-branch-output.sh +11
-0@@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' ' test_cmp expect actual ' +test_expect_success 'git branch --list shows local branches' ' + git branch --list >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' + branch-one + branch-two +EOF +test_expect_success 'git branch --list pattern shows matching local branches' ' + git branch --list branch* >actual &&
Quoted 8 lines
t/t3203-branch-output.sh test_expect_success 'git branch shows local branches' ' · line 39
Quoted 3 lines
t/t3203-branch-output.sh +3
-0+ test_cmp expect actual +' +Could we have a test to check the code you updated to sanity check the combination of options as well? I suspect the reason your initial round botched the "branch -v -m foo" without realizing may be because we do not cover the error checking.
Currently, "-m -d" is forbidden", but "-m -v" is "-m", same for "-d -v". Do we want to keep it like that? Probably. I'll add the tests to 4/5.
Michael
Re: [PATCHv2 4/5] branch: introduce --list option
Quoted 2 lines · Michael J Gruber
Currently, "-m -d" is forbidden", but "-m -v" is "-m", same for "-d -v". Do we want to keep it like that? Probably. I'll add the tests to 4/5.
Yes, I think so. "-v" just means "be more verbose"; the fact that there is currently nothing to be more verbose about with "-m" and "-d" is irrelevant.
It does make me a little nervous about the "'git branch -v' automatically means 'git branch --list -v'" patch, though. It closes the door in the future to us being more or less verbose about branch creation details (and while helpful, it creates a slight inconsistency in the interface).
If we are adding "-l" anyway, is it really necessary? It's not much harder to do "git branch -lv" once that is in place.
-Peff
Re: [PATCHv2 4/5] branch: introduce --list option
Jeff King venit, vidit, dixit 07.09.2011 21:56:
Quoted 9 lines · Michael J Gruber
Quoted 3 lines
Currently, "-m -d" is forbidden", but "-m -v" is "-m", same for "-d -v". Do we want to keep it like that? Probably. I'll add the tests to 4/5.
Yes, I think so. "-v" just means "be more verbose"; the fact that there is currently nothing to be more verbose about with "-m" and "-d" is irrelevant.
Quoted 8 lines
It does make me a little nervous about the "'git branch -v' automatically means 'git branch --list -v'" patch, though. It closes the door in the future to us being more or less verbose about branch creation details (and while helpful, it creates a slight inconsistency in the interface).
If we are adding "-l" anyway, is it really necessary? It's not much harder to do "git branch -lv" once that is in place.
Well, it will take a while to (re-)take "-l". For the sake of consistency I wouldn't mind making "--verbose" strictly a "modifier" for whatever mode/subcommand of the command is going on, even though it would mean having to type "-v --list" for a long time. In general, -v/--verbose should always be like that, but is not (e.g. tag -v).
This is in next now but no harm would be done changing it now.
Michael
PATCH v4 4/5 branch: introduce --list option
Currently, there is no way to invoke the list mode explicitly.
Introduce a --list option which invokes the list mode. This will be beneficial for invoking list mode with pattern matching, which otherwise would be interpreted as branch creation.
Along with --list, test also combinations of existing options.
--- Documentation/git-branch.txt | 11 ++++++++--- builtin/branch.c | 11 ++++++++--- t/t3200-branch.sh | 32 ++++++++++++++++++++++++++++++++ t/t3203-branch-output.sh | 5 +++++ 4 files changed, 53 insertions(+), 6 deletions(-)
Documentation/git-branch.txt +8 -3
@@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git branch' [--color[=<when>] | --no-color] [-r | -a] - [-v [--abbrev=<length> | --no-abbrev]] + [--list] [-v [--abbrev=<length> | --no-abbrev]] [(--merged | --no-merged | --contains) [<commit>]] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>] 'git branch' (-m | -M) [<oldbranch>] <newbranch>
@@ -20,7 +20,8 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking -branches to be listed, and option `-a` shows both. +branches to be listed, and option `-a` shows both. This list mode is also +activated by the `--list` option (see below). With `--contains`, shows only the branches that contain the named commit (in other words, the branches whose tip commits are descendants of the
@@ -110,9 +111,13 @@ OPTIONS --all:: List both remote-tracking branches and local branches. +--list:: + Activate the list mode. + -v:: --verbose:: - Show sha1 and commit subject line for each head, along with + When in list mode, + show sha1 and commit subject line for each head, along with relationship to upstream branch (if any). If given twice, print the name of the upstream branch, as well.
builtin/branch.c +8 -3
@@ -612,7 +612,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, intint cmd_branch (int argc,const char **argv,const char *prefix) { -int delete =0 , rename =0 , force_create =0 ; +int delete =0 , rename =0 , force_create =0 , list =0 ;int verbose =0 , abbrev =-1 , detached =0 ;int reflog =0 ;enum branch_track track;
@@ -651,6 +651,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT_BIT ('D' ,NULL , &delete,"delete branch (even if not merged)" ,2 ),OPT_BIT ('m' ,"move" , &rename,"move/rename a branch and its reflog" ,1 ),OPT_BIT ('M' ,NULL , &rename,"move/rename a branch, even if target exists" ,2 ), +OPT_BOOLEAN (0 ,"list" , &list,"list branch names" ),OPT_BOOLEAN ('l' ,"create-reflog" , &reflog,"create the branch's reflog" ), OPT__FORCE(&force_create, "force creation (when already exists)"), {
@@ -693,7 +694,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc =parse_options (argc, argv, prefix, options, builtin_branch_usage,0 ); -if (!!delete + !!rename + !!force_create >1 ) + +if (!delete && !rename && !force_create && argc ==0 ) + list =1 ; + +if (!!delete + !!rename + !!force_create + !!list >1 )usage_with_options (builtin_branch_usage, options);if (abbrev ==-1 )
@@ -701,7 +706,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (delete)return delete_branches (argc, argv, delete >1 , kinds); -else if (argc ==0 ) +else if (list)return print_ref_list (kinds, detached, verbose, abbrev, with_commit);else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );
t/t3200-branch.sh +32 -0
@@ -98,6 +98,38 @@ test_expect_success 'git branch -m q r/q should fail when r exists' ' test_must_fail git branch -m q r/q ' +test_expect_success 'git branch -v -d t should work' ' + git branch t && + test .git/refs/heads/t && + git branch -v -d t && + test ! -f .git/refs/heads/t +' + +test_expect_success 'git branch -v -m t s should work' ' + git branch t && + test .git/refs/heads/t && + git branch -v -m t s && + test ! -f .git/refs/heads/t && + test -f .git/refs/heads/s && + git branch -d s +' + +test_expect_success 'git branch -m -d t s should fail' ' + git branch t && + test .git/refs/heads/t && + test_must_fail git branch -m -d t s && + git branch -d t && + test ! -f .git/refs/heads/t +' + +test_expect_success 'git branch --list -d t should fail' ' + git branch t && + test .git/refs/heads/t && + test_must_fail git branch --list -d t && + git branch -d t && + test ! -f .git/refs/heads/t +' + mv .git/config .git/config-saved test_expect_success 'git branch -m q q2 without config should succeed' '
t/t3203-branch-output.sh +5 -0
@@ -32,6 +32,11 @@ test_expect_success 'git branch shows local branches' ' test_cmp expect actual ' +test_expect_success 'git branch --list shows local branches' ' + git branch --list >actual && + test_cmp expect actual +' + cat >expect <<'EOF' origin/HEAD -> origin/branch-one origin/branch-one
Signature · 1 line
1.7.7.rc0.469.g9eb94
Re: [PATCHv2 4/5] branch: introduce --list option
In reply to Michael J GruberQuoted 7 lines · Michael J Gruber
Jeff King venit, vidit, dixit 07.09.2011 21:56:
...Quoted 5 lines
It does make me a little nervous about the "'git branch -v' automatically means 'git branch --list -v'" patch, though. It closes the door in the future to us being more or less verbose about branch creation details (and while helpful, it creates a slight inconsistency in the interface).
Hasn't 'git branch -v' meant listing in verbose mode for a long enough time that changing it now would mean a moderately major regression?
At least my copy of v1.7.0 seems to list with "git branch -v".
Re: [PATCHv2 4/5] branch: introduce --list option
Quoted 4 lines · Junio C Hamano
Hasn't 'git branch -v' meant listing in verbose mode for a long enough time that changing it now would mean a moderately major regression?
At least my copy of v1.7.0 seems to list with "git branch -v".
No, it will mean the same thing as in v1.7.0; it is not the "-v" which does it, but the lack of non-option arguments.
Right now, "-v" just means "if we are listing, do it verbosely". And if you don't specify any non-option arguments, it means "list". So right now:
git branch ;# list
git branch -v ;# list verbosely
git branch -v foo ;# create branch 'foo', -v does nothing
Michael's proposal was:
git branch -v foo ;# assume verbose list, interpret 'foo' as pattern
which is actually a regression, albeit one that probably doesn't matter (because "-v" didn't ever do anything with a non-option argument).
Whereas mine is:
git branch -v foo ;# create branch 'foo' verbosely
Which happens to do exactly the same thing as the current behavior, because there are no verbose messages to add to "git branch". But it leaves the door open to adding them in the future (and it's consistent with "git branch -m -v" and "git branch -d -v", both of which could use "-v" to do their operations more verbosely).
-Peff
Re: [PATCHv2 4/5] branch: introduce --list option
In reply to Junio C HamanoQuoted 10 lines · Junio C Hamano
Quoted 7 lines · Michael J Gruber
Jeff King venit, vidit, dixit 07.09.2011 21:56:
...Quoted 5 lines
It does make me a little nervous about the "'git branch -v' automatically means 'git branch --list -v'" patch, though. It closes the door in the future to us being more or less verbose about branch creation details (and while helpful, it creates a slight inconsistency in the interface).
Quoted 4 lines
Hasn't 'git branch -v' meant listing in verbose mode for a long enough time that changing it now would mean a moderately major regression?
At least my copy of v1.7.0 seems to list with "git branch -v".
Ah, nevermind.
As the series is already in 'next', here is what I came up with.
-- >8 --
From: Michael J Gruber <[email protected]>
Date: Thu, 8 Sep 2011 14:09:50 -0700
Subject: [PATCH] branch: -v does not automatically imply --list
"branch -v" without other options or parameters still works in the list mode, but that is not because there is "-v" but because there is no parameter nor option.
--- Documentation/git-branch.txt | 6 +++--- builtin/branch.c | 3 +-- t/t3203-branch-output.sh | 8 ++++++-- 3 files changed, 10 insertions(+), 7 deletions(-)
Documentation/git-branch.txt +3 -3
@@ -21,7 +21,7 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking branches to be listed, and option `-a` shows both. This list mode is also -activated by the `--list` and `-v` options (see below). +activated by the `--list` option (see below). <pattern> restricts the output to matching branches, the pattern is a shell wildcard (i.e., matched using fnmatch(3)) Multiple patterns may be given; if any of them matches, the tag is shown.
@@ -120,10 +120,10 @@ OPTIONS -v:: --verbose:: - Show sha1 and commit subject line for each head, along with + When in list mode, + show sha1 and commit subject line for each head, along with relationship to upstream branch (if any). If given twice, print the name of the upstream branch, as well. - `--list` is implied by all verbosity options. --abbrev=<length>:: Alter the sha1's minimum display length in the output listing.
builtin/branch.c +1 -2
@@ -712,8 +712,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc =parse_options (argc, argv, prefix, options, builtin_branch_usage,0 ); -if (!delete && !rename && !force_create && - (argc ==0 || (verbose && argc))) +if (!delete && !rename && !force_create && argc ==0 ) list =1 ;if (!!delete + !!rename + !!force_create + !!list >1 )
t/t3203-branch-output.sh +6 -2
@@ -84,12 +84,16 @@ cat >expect <<'EOF' two one EOF -test_expect_success 'git branch -v pattern shows branch summaries' ' - git branch -v branch* >tmp && +test_expect_success 'git branch --list -v pattern shows branch summaries' ' + git branch --list -v branch* >tmp && awk "{print \$NF}" <tmp >actual && test_cmp expect actual ' +test_expect_success 'git branch -v pattern does not show branch summaries' ' + test_must_fail git branch -v branch* +' + cat >expect <<'EOF' * (no branch) branch-one
Signature · 1 line
1.7.7.rc0.188.g3793ac
Re: [PATCHv2 4/5] branch: introduce --list option
t/t3203-branch-output.sh cat >expect <<'EOF' · line 95
Quoted 7 lines · Junio C Hamano
"branch -v" without other options or parameters still works in the list mode, but that is not because there is "-v" but because there is no parameter nor option.
[...]t/t3203-branch-output.sh +3
-0+test_expect_success 'git branch -v pattern does not show branch summaries' ' + test_must_fail git branch -v branch* +'
You might also want to affirm that it does not just fail, but still creates a branch, like:
test_expect_success 'git branch -v <name> creates a branch' '
git rev-parse HEAD >expect &&
git branch -v foo &&
git rev-parse foo >actual &&
test_cmp expect actual'
-Peff
Re: [PATCHv2 4/5] branch: introduce --list option
In reply to Junio C HamanoJunio C Hamano venit, vidit, dixit 08.09.2011 23:17:
Quoted 12 lines
Quoted 10 lines · Junio C Hamano
Quoted 7 lines · Michael J Gruber
Jeff King venit, vidit, dixit 07.09.2011 21:56:
...Quoted 5 lines
It does make me a little nervous about the "'git branch -v' automatically means 'git branch --list -v'" patch, though. It closes the door in the future to us being more or less verbose about branch creation details (and while helpful, it creates a slight inconsistency in the interface).
Quoted 8 lines
Quoted 4 lines
Hasn't 'git branch -v' meant listing in verbose mode for a long enough time that changing it now would mean a moderately major regression?
At least my copy of v1.7.0 seems to list with "git branch -v".
Ah, nevermind.
As the series is already in 'next', here is what I came up with.
I thought you'll rebuild next anyways after 1.7.7, but either way it's fine. Thanks for holding this series in next long enough to really cook it (and Jeff for revisiting it), it's much better now, keeping the (undocumented, but expected) behavior of "git branch -v foo".
Quoted 81 lines
-- >8 --
From: Michael J Gruber <[email protected]>
Date: Thu, 8 Sep 2011 14:09:50 -0700
Subject: [PATCH] branch: -v does not automatically imply --list"branch -v" without other options or parameters still works in the list mode, but that is not because there is "-v" but because there is no parameter nor option.
Signed-off-by Michael J Gruber <[email protected]>Signed-off-by Junio C Hamano <[email protected]>--- Documentation/git-branch.txt | 6 +++--- builtin/branch.c | 3 +-- t/t3203-branch-output.sh | 8 ++++++-- 3 files changed, 10 insertions(+), 7 deletions(-)Documentation/git-branch.txt +3
-3@@ -21,7 +21,7 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking branches to be listed, and option `-a` shows both. This list mode is also -activated by the `--list` and `-v` options (see below). +activated by the `--list` option (see below). <pattern> restricts the output to matching branches, the pattern is a shell wildcard (i.e., matched using fnmatch(3)) Multiple patterns may be given; if any of them matches, the tag is shown.@@ -120,10 +120,10 @@ OPTIONS -v:: --verbose:: - Show sha1 and commit subject line for each head, along with + When in list mode, + show sha1 and commit subject line for each head, along with relationship to upstream branch (if any). If given twice, print the name of the upstream branch, as well. - `--list` is implied by all verbosity options. --abbrev=<length>:: Alter the sha1's minimum display length in the output listing.builtin/branch.c +1
-2@@ -712,8 +712,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc =parse_options (argc, argv, prefix, options, builtin_branch_usage,0 ); -if (!delete && !rename && !force_create && - (argc ==0 || (verbose && argc))) +if (!delete && !rename && !force_create && argc ==0 ) list =1 ;if (!!delete + !!rename + !!force_create + !!list >1 )t/t3203-branch-output.sh +6
-2@@ -84,12 +84,16 @@ cat >expect <<'EOF' two one EOF -test_expect_success 'git branch -v pattern shows branch summaries' ' - git branch -v branch* >tmp && +test_expect_success 'git branch --list -v pattern shows branch summaries' ' + git branch --list -v branch* >tmp && awk "{print \$NF}" <tmp >actual && test_cmp expect actual ' +test_expect_success 'git branch -v pattern does not show branch summaries' ' + test_must_fail git branch -v branch* +' + cat >expect <<'EOF' * (no branch) branch-one
Re: [PATCHv2 4/5] branch: introduce --list option
Quoted 9 lines · Michael J Gruber
Junio C Hamano venit, vidit, dixit 08.09.2011 23:17:
Quoted 3 lines
Ah, nevermind.
As the series is already in 'next', here is what I came up with.
I thought you'll rebuild next anyways after 1.7.7, but either way it's fine. Thanks for holding this series in next long enough to really cook it (and Jeff for revisiting it), it's much better now, keeping the (undocumented, but expected) behavior of "git branch -v foo".
Thank *you* for all the work.
I recall Peff had some comments on your new tests last night, by the way.
Re: [PATCHv2 4/5] branch: introduce --list option
Junio C Hamano venit, vidit, dixit 09.09.2011 18:02:
Quoted 7 lines
Quoted 5 lines · Michael J Gruber
Junio C Hamano venit, vidit, dixit 08.09.2011 23:17:
Quoted 3 lines
Ah, nevermind.
As the series is already in 'next', here is what I came up with.
Quoted 9 lines
Quoted 4 lines
I thought you'll rebuild next anyways after 1.7.7, but either way it's fine. Thanks for holding this series in next long enough to really cook it (and Jeff for revisiting it), it's much better now, keeping the (undocumented, but expected) behavior of "git branch -v foo".
Thank *you* for all the work.
I recall Peff had some comments on your new tests last night, by the way.
Yes, we have tests (now) for "-v -d", "-v -m", "-v branch*" and combinations with --list. Testing "-v foo" for creation would be good (and belong into t3200). Is there anything to amend?
Michael
Re: [PATCHv2 4/5] branch: introduce --list option
Quoted 5 lines · Michael J Gruber
Quoted 1 line
I recall Peff had some comments on your new tests last night, by the way.
Yes, we have tests (now) for "-v -d", "-v -m", "-v branch*" and combinations with --list. Testing "-v foo" for creation would be good (and belong into t3200). Is there anything to amend?
I think my comment was just to add the "-v foo" test.
-Peff
PATCH 1/1 t3200: test branch creation with -v
Make sure that "git branch -v t" creates branch "t".
--- t/t3200-branch.sh | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
t/t3200-branch.sh +7 -0
@@ -105,6 +105,13 @@ test_expect_success 'git branch -v -d t should work' ' test ! -f .git/refs/heads/t ' +test_expect_success 'git branch -v t should work' ' + git branch -v t && + test .git/refs/heads/t && + git branch -d t && + test ! -f .git/refs/heads/t +' + test_expect_success 'git branch -v -m t s should work' ' git branch t && test .git/refs/heads/t &&
Signature · 1 line
1.7.7.rc0.469.g9eb94
Re: [PATCH] t3200: test branch creation with -v
t/t3200-branch.sh test_expect_success 'git branch -v -d t should work' ' · line 110
Quoted 3 lines · Michael J Gruber
t/t3200-branch.sh +3
-0+test_expect_success 'git branch -v t should work' ' + git branch -v t && + test .git/refs/heads/t &&
test -f ?
Also, don't we have test_path_is_file which yields slightly prettier output (and maybe some portability benefits; I don't remember)?
t/t3200-branch.sh test_expect_success 'git branch -v -d t should work' ' · line 112
Quoted 2 lines
t/t3200-branch.sh +2
-0+ git branch -d t && + test ! -f .git/refs/heads/t
Ditto for 'test_path_is_missing' here.
-Peff
Re: [PATCH] t3200: test branch creation with -v
Quoted 7 lines · Jeff King
t/t3200-branch.sh test_expect_success 'git branch -v -d t should work' ' · line 110
Quoted 3 lines · Michael J Gruber
t/t3200-branch.sh +3
-0+test_expect_success 'git branch -v t should work' ' + git branch -v t && + test .git/refs/heads/t &&test -f ?
Hmm, this also seems to be a problem in the other tests, too.
-Peff
Re: [PATCH] t3200: test branch creation with -v
In reply to Jeff KingJeff King venit, vidit, dixit 09.09.2011 21:43:
Quoted 7 lines · Michael J Gruber
Review
Quoted 3 lines
(quoted diff) +1
-1+test_expect_success 'git branch -v t should work' ' + git branch -v t && + test .git/refs/heads/t &&test -f ?
Quoted 8 lines
Also, don't we have
test_path_is_filewhich yields slightly prettier output (and maybe some portability benefits; I don't remember)?Review
Quoted 1 line
(quoted diff) +1
-0+ git branch -d t && + test ! -f .git/refs/heads/tDitto for '
test_path_is_missing' here.-Peff
Well, I tried to follow the surrounding style. That t3200 could benefit from some attention, though, which I did not want to mix in with the issue at hand.
Michael
Re: [PATCH] t3200: test branch creation with -v
Quoted 15 lines · Michael J Gruber
Jeff King venit, vidit, dixit 09.09.2011 21:43:
Quoted 14 lines · Michael J Gruber
Review
Quoted 3 lines
(quoted diff) +1
-1+test_expect_success 'git branch -v t should work' ' + git branch -v t && + test .git/refs/heads/t &&test -f ?
Also, don't we have
test_path_is_filewhich yields slightly prettier output (and maybe some portability benefits; I don't remember)?Review
Quoted 1 line
(quoted diff) +1
-0+ git branch -d t && + test ! -f .git/refs/heads/tDitto for '
test_path_is_missing' here.
Quoted 5 lines
Quoted 1 line
-Peff
Well, I tried to follow the surrounding style. That t3200 could benefit from some attention, though, which I did not want to mix in with the issue at hand.
The "test_path_is_file" thing is style. But not using "test -f" is just wrong; you are testing "is .git/refs/heads/t an empty string?" which is useless.
You want this on top of what's in mg/branch-list:
t/t3200-branch.sh +4 -4
@@ -100,14 +100,14 @@ test_expect_success 'git branch -m q r/q should fail when r exists' ' test_expect_success 'git branch -v -d t should work' ' git branch t && - test .git/refs/heads/t && + test -f .git/refs/heads/t && git branch -v -d t && test ! -f .git/refs/heads/t ' test_expect_success 'git branch -v -m t s should work' ' git branch t && - test .git/refs/heads/t && + test -f .git/refs/heads/t && git branch -v -m t s && test ! -f .git/refs/heads/t && test -f .git/refs/heads/s &&
@@ -116,7 +116,7 @@ test_expect_success 'git branch -v -m t s should work' ' test_expect_success 'git branch -m -d t s should fail' ' git branch t && - test .git/refs/heads/t && + test -f .git/refs/heads/t && test_must_fail git branch -m -d t s && git branch -d t && test ! -f .git/refs/heads/t
@@ -124,7 +124,7 @@ test_expect_success 'git branch -m -d t s should fail' ' test_expect_success 'git branch --list -d t should fail' ' git branch t && - test .git/refs/heads/t && + test -f .git/refs/heads/t && test_must_fail git branch --list -d t && git branch -d t && test ! -f .git/refs/heads/t
I suspect you didn't notice the bogosity before because those are just confirming the precondition that "git branch" actually created the file.
-Peff
Re: [PATCH] t3200: test branch creation with -v
Jeff King venit, vidit, dixit 13.09.2011 05:57:
Quoted 23 lines · Michael J Gruber
Quoted 16 lines
Jeff King venit, vidit, dixit 09.09.2011 21:43:
Quoted 14 lines · Michael J Gruber
Review
Quoted 3 lines
(quoted diff) +1
-1+test_expect_success 'git branch -v t should work' ' + git branch -v t && + test .git/refs/heads/t &&test -f ?
Also, don't we have
test_path_is_filewhich yields slightly prettier output (and maybe some portability benefits; I don't remember)?Review
Quoted 1 line
(quoted diff) +1
-0+ git branch -d t && + test ! -f .git/refs/heads/tDitto for '
test_path_is_missing' here.Quoted 5 lines
Quoted 1 line
-Peff
Well, I tried to follow the surrounding style. That t3200 could benefit from some attention, though, which I did not want to mix in with the issue at hand.
Quoted 5 lines
The "
test_path_is_file" thing is style. But not using "test -f" is just wrong; you are testing "is .git/refs/heads/t an empty string?" which is useless.You want this on top of what's in mg/branch-list:
Yes, sorry. How did I miss that?
I'd prefer your style anyway, but also prefer changing t3200 in one go.
Quoted 45 lines
t/t3200-branch.sh +4
-4@@ -100,14 +100,14 @@ test_expect_success 'git branch -m q r/q should fail when r exists' ' test_expect_success 'git branch -v -d t should work' ' git branch t && - test .git/refs/heads/t && + test -f .git/refs/heads/t && git branch -v -d t && test ! -f .git/refs/heads/t ' test_expect_success 'git branch -v -m t s should work' ' git branch t && - test .git/refs/heads/t && + test -f .git/refs/heads/t && git branch -v -m t s && test ! -f .git/refs/heads/t && test -f .git/refs/heads/s &&@@ -116,7 +116,7 @@ test_expect_success 'git branch -v -m t s should work' ' test_expect_success 'git branch -m -d t s should fail' ' git branch t && - test .git/refs/heads/t && + test -f .git/refs/heads/t && test_must_fail git branch -m -d t s && git branch -d t && test ! -f .git/refs/heads/t@@ -124,7 +124,7 @@ test_expect_success 'git branch -m -d t s should fail' ' test_expect_success 'git branch --list -d t should fail' ' git branch t && - test .git/refs/heads/t && + test -f .git/refs/heads/t && test_must_fail git branch --list -d t && git branch -d t && test ! -f .git/refs/heads/tI suspect you didn't notice the bogosity before because those are just confirming the precondition that "git branch" actually created the file.
-Peff
PATCH 1/1 t3200: clean up checks for file existence
This patch uses test_path_is_file and test_path_is_missing instead of "test -f / ! test -f" checks. The former are more verbose in case of failure and more precise (e.g., is_missing will check that the entry is actually missing, not just not a regular file).
As a bonus, this also fixes a few buggy tests that used "test foo" instead of "test -f foo", and consequently always reported success.
---
Quoted 1 line · Michael J Gruber
I'd prefer your style anyway, but also prefer changing t3200 in one go.
Here it is, on top of mg/branch-list. The "test without -f" bits could actually be squashed in to your commits if we really want clean history, but I don't think it's a big deal.
t/t3200-branch.sh | 50 +++++++++++++++++++++++++------------------------- 1 files changed, 25 insertions(+), 25 deletions(-)
t/t3200-branch.sh +25 -25
@@ -23,7 +23,7 @@ test_expect_success \ test_expect_success \ 'git branch --help should not have created a bogus branch' ' git branch --help </dev/null >/dev/null 2>/dev/null; - ! test -f .git/refs/heads/--help + test_path_is_missing .git/refs/heads/--help ' test_expect_success 'branch -h in broken repository' '
@@ -39,11 +39,11 @@ test_expect_success 'branch -h in broken repository' ' test_expect_success \ 'git branch abc should create a branch' \ - 'git branch abc && test -f .git/refs/heads/abc' + 'git branch abc && test_path_is_file .git/refs/heads/abc' test_expect_success \ 'git branch a/b/c should create a branch' \ - 'git branch a/b/c && test -f .git/refs/heads/a/b/c' + 'git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c' cat >expect <<EOF $_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
@@ -52,15 +52,15 @@ test_expect_success \ 'git branch -l d/e/f should create a branch and a log' \ 'GIT_COMMITTER_DATE="2005-05-26 23:30" \ git branch -l d/e/f && - test -f .git/refs/heads/d/e/f && - test -f .git/logs/refs/heads/d/e/f && + test_path_is_file .git/refs/heads/d/e/f && + test_path_is_file .git/logs/refs/heads/d/e/f && test_cmp expect .git/logs/refs/heads/d/e/f' test_expect_success \ 'git branch -d d/e/f should delete a branch and a log' \ 'git branch -d d/e/f && - test ! -f .git/refs/heads/d/e/f && - test ! -f .git/logs/refs/heads/d/e/f' + test_path_is_missing .git/refs/heads/d/e/f && + test_path_is_missing .git/logs/refs/heads/d/e/f' test_expect_success \ 'git branch j/k should work after branch j has been deleted' \
@@ -78,13 +78,13 @@ test_expect_success \ 'git branch -m m m/m should work' \ 'git branch -l m && git branch -m m m/m && - test -f .git/logs/refs/heads/m/m' + test_path_is_file .git/logs/refs/heads/m/m' test_expect_success \ 'git branch -m n/n n should work' \ 'git branch -l n/n && git branch -m n/n n - test -f .git/logs/refs/heads/n' + test_path_is_file .git/logs/refs/heads/n' test_expect_success 'git branch -m o/o o should fail when o/p exists' ' git branch o/o &&
@@ -100,34 +100,34 @@ test_expect_success 'git branch -m q r/q should fail when r exists' ' test_expect_success 'git branch -v -d t should work' ' git branch t && - test .git/refs/heads/t && + test_path_is_file .git/refs/heads/t && git branch -v -d t && - test ! -f .git/refs/heads/t + test_path_is_missing .git/refs/heads/t ' test_expect_success 'git branch -v -m t s should work' ' git branch t && - test .git/refs/heads/t && + test_path_is_file .git/refs/heads/t && git branch -v -m t s && - test ! -f .git/refs/heads/t && - test -f .git/refs/heads/s && + test_path_is_missing .git/refs/heads/t && + test_path_is_file .git/refs/heads/s && git branch -d s ' test_expect_success 'git branch -m -d t s should fail' ' git branch t && - test .git/refs/heads/t && + test_path_is_file .git/refs/heads/t && test_must_fail git branch -m -d t s && git branch -d t && - test ! -f .git/refs/heads/t + test_path_is_missing .git/refs/heads/t ' test_expect_success 'git branch --list -d t should fail' ' git branch t && - test .git/refs/heads/t && + test_path_is_file .git/refs/heads/t && test_must_fail git branch --list -d t && git branch -d t && - test ! -f .git/refs/heads/t + test_path_is_missing .git/refs/heads/t ' mv .git/config .git/config-saved
@@ -144,12 +144,12 @@ git config branch.s/s.dummy Hello test_expect_success \ 'git branch -m s/s s should work when s/t is deleted' \ 'git branch -l s/s && - test -f .git/logs/refs/heads/s/s && + test_path_is_file .git/logs/refs/heads/s/s && git branch -l s/t && - test -f .git/logs/refs/heads/s/t && + test_path_is_file .git/logs/refs/heads/s/t && git branch -d s/t && git branch -m s/s s && - test -f .git/logs/refs/heads/s' + test_path_is_file .git/logs/refs/heads/s' test_expect_success 'config information was renamed, too' \ "test $(git config branch.s.dummy) = Hello &&
@@ -160,8 +160,8 @@ test_expect_success 'renaming a symref is not allowed' \ git symbolic-ref refs/heads/master2 refs/heads/master && test_must_fail git branch -m master2 master3 && git symbolic-ref refs/heads/master2 && - test -f .git/refs/heads/master && - ! test -f .git/refs/heads/master3 + test_path_is_file .git/refs/heads/master && + test_path_is_missing .git/refs/heads/master3 ' test_expect_success SYMLINKS \
@@ -270,8 +270,8 @@ test_expect_success \ 'git checkout -b g/h/i -l should create a branch and a log' \ 'GIT_COMMITTER_DATE="2005-05-26 23:30" \ git checkout -b g/h/i -l master && - test -f .git/refs/heads/g/h/i && - test -f .git/logs/refs/heads/g/h/i && + test_path_is_file .git/refs/heads/g/h/i && + test_path_is_file .git/logs/refs/heads/g/h/i && test_cmp expect .git/logs/refs/heads/g/h/i' test_expect_success 'checkout -b makes reflog by default' '
Signature · 1 line
1.7.7.rc1.2.gb2409
Re: [PATCH] t3200: clean up checks for file existence
Quoted 3 lines · Jeff King
Here it is, on top of mg/branch-list. The "test without -f" bits could actually be squashed in to your commits if we really want clean history, but I don't think it's a big deal.
Thanks.
In the longer term, we might want to update these tests further so that they do not fail when implementation is updated not to write loose refs, e.g.
t/t3200-branch.sh test_expect_success 'branch -h in broken repository' ' · line 42
Quoted 4 lines
test_expect_success \ 'git branch abc should create a branch' \t/t3200-branch.sh +1
-1- 'git branch abc && test -f .git/refs/heads/abc' + 'git branch abc && test_path_is_file .git/refs/heads/abc'
git branch abc && git show-ref -q --verify refs/heads/abc
But this patch is about correctness first, so I'll queue it as-is.
Re: [PATCH] t3200: clean up checks for file existence
Quoted 3 lines · Junio C Hamano
In the longer term, we might want to update these tests further so that they do not fail when implementation is updated not to write loose refs, e.g.
Yeah, I noticed that, too, but figured to leave it for when such a change came about (which is probably going to need to fix tests everywhere, not just here). I'm happy to fix this area now, though, if you want.
-Peff
PATCH v4 5/5 branch: allow pattern arguments
In reply to Michael J GruberAllow pattern arguments for the list mode just like for git tag -l.
--- Documentation/git-branch.txt | 8 ++++++-- builtin/branch.c | 24 +++++++++++++++++++++--- t/t3203-branch-output.sh | 23 +++++++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-)
Documentation/git-branch.txt +6 -2
@@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git branch' [--color[=<when>] | --no-color] [-r | -a] [--list] [-v [--abbrev=<length> | --no-abbrev]] - [(--merged | --no-merged | --contains) [<commit>]] + [(--merged | --no-merged | --contains) [<commit>]] [<pattern>...] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>] 'git branch' (-m | -M) [<oldbranch>] <newbranch> 'git branch' (-d | -D) [-r] <branchname>...
@@ -22,6 +22,9 @@ With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking branches to be listed, and option `-a` shows both. This list mode is also activated by the `--list` option (see below). +<pattern> restricts the output to matching branches, the pattern is a shell +wildcard (i.e., matched using fnmatch(3)). +Multiple patterns may be given; if any of them matches, the tag is shown. With `--contains`, shows only the branches that contain the named commit (in other words, the branches whose tip commits are descendants of the
@@ -112,7 +115,8 @@ OPTIONS List both remote-tracking branches and local branches. --list:: - Activate the list mode. + Activate the list mode. `git branch <pattern>` would try to create a branch, + use `git branch --list <pattern>` to list matching branches. -v:: --verbose::
builtin/branch.c +21 -3
@@ -260,9 +260,22 @@ static char *resolve_symref(const char *src, const char *prefix)struct append_ref_cb {struct ref_list *ref_list; +const char **pattern;int ret; }; +static int match_patterns (const char **pattern,const char *refname) +{ +if (!*pattern) +return 1 ;/* no pattern always matches */ +while (*pattern) { +if (!fnmatch (*pattern, refname,0 )) +return 1 ; + pattern++; + } +return 0 ; +} +static int append_ref (const char *refname,const unsigned char *sha1,int flags,void *cb_data) {struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);
@@ -297,6 +310,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ; +if (!match_patterns (cb->pattern, refname)) +return 0 ; + commit =NULL ;if (ref_list->verbose || ref_list->with_commit || merge_filter !=NO_FILTER ) { commit =lookup_commit_reference_gently (sha1,1 );
@@ -492,7 +508,7 @@ static void show_detached(struct ref_list *ref_list) } } -static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit) +static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit,const char **pattern) {int i;struct append_ref_cb cb;
@@ -506,6 +522,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struif (merge_filter !=NO_FILTER )init_revisions (&ref_list.revs,NULL ); cb.ref_list = &ref_list; + cb.pattern = pattern; cb.ret =0 ;for_each_rawref (append_ref, &cb);if (merge_filter !=NO_FILTER ) {
@@ -523,7 +540,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struqsort (ref_list.list, ref_list.index,sizeof (struct ref_item ), ref_cmp); detached = (detached && (kinds &REF_LOCAL_BRANCH )); -if (detached) +if (detached &&match_patterns (pattern,"HEAD" ))show_detached (&ref_list);for (i =0 ; i < ref_list.index; i++) {
@@ -707,7 +724,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (delete)return delete_branches (argc, argv, delete >1 , kinds);else if (list) -return print_ref_list (kinds, detached, verbose, abbrev, with_commit); +return print_ref_list (kinds, detached, verbose, abbrev, + with_commit, argv);else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );else if (rename && (argc ==2 ))
t/t3203-branch-output.sh +23 -0
@@ -38,6 +38,15 @@ test_expect_success 'git branch --list shows local branches' ' ' cat >expect <<'EOF' + branch-one + branch-two +EOF +test_expect_success 'git branch --list pattern shows matching local branches' ' + git branch --list branch* >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' origin/HEAD -> origin/branch-one origin/branch-one origin/branch-two
@@ -72,6 +81,20 @@ test_expect_success 'git branch -v shows branch summaries' ' ' cat >expect <<'EOF' +two +one +EOF +test_expect_success 'git branch --list -v pattern shows branch summaries' ' + git branch --list -v branch* >tmp && + awk "{print \$NF}" <tmp >actual && + test_cmp expect actual +' + +test_expect_success 'git branch -v pattern does not show branch summaries' ' + test_must_fail git branch -v branch* +' + +cat >expect <<'EOF' * (no branch) branch-one branch-two
Signature · 1 line
1.7.7.rc0.469.g9eb94
v4 cover mg/branch-list amendment
In reply to Michael J GruberSo, this is what the top 2 commits in mg/branch-list should be replaced with if we don't let "-v" activate list mode, so that we can have a verbose option for branch creation later on, i.e.:
git branch -v foo is the verbose version of git branch
Michael J Gruber (2):
branch: introduce --list option
branch: allow pattern arguments
Documentation/git-branch.txt | 17 +++++++++++++---- builtin/branch.c | 35 +++++++++++++++++++++++++++++------ t/t3200-branch.sh | 32 ++++++++++++++++++++++++++++++++ t/t3203-branch-output.sh | 28 ++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 10 deletions(-)
Signature · 1 line
1.7.7.rc0.469.g9eb94
v2 cover patterns for branch list
In reply to Jeff KingIn this iteration, I have incorporated Jeffs and Junios suggestions and Junios patches. Thanks!
So:
git branch --list is introduced before the patterns (though it is not needed at that point)
Multiple patterns are allowed.
The -v/vv/vvv changing patches are gone.
Also, the independent test for "-vv" is put first (which certainly can go in now). Next come long option names for "git tag" and "git branch", then the pattern related patches.
I have also rebased on next with nk/branch-v-abbrev (which conflicts, though "trivially").
"-l -> -g" migration for "git branch" and such are issues for a later series.
Michael J Gruber (5):
t6040: test branch -vv
git-tag: introduce long forms for the options
git-branch: introduce missing long forms for the options
branch: introduce --list option
branch: allow pattern arguments
Documentation/git-branch.txt | 20 +++++++++++++++-- Documentation/git-tag.txt | 8 +++++++ builtin/branch.c | 46 +++++++++++++++++++++++++++++++---------- builtin/tag.c | 16 +++++++------- t/t3203-branch-output.sh | 24 +++++++++++++++++++++ t/t6040-tracking-info.sh | 16 ++++++++++++++ 6 files changed, 108 insertions(+), 22 deletions(-)
Signature · 1 line
1.7.6.845.gc3c05
PATCH v3 1/5 t6040: test branch -vv
t6040 has a test for 'git branch -v' but not for 'git branch -vv'. Add one.
--- t/t6040-tracking-info.sh | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)
t/t6040-tracking-info.sh +16 -0
@@ -51,6 +51,22 @@ test_expect_success 'branch -v' ' test_i18ncmp expect actual ' +cat >expect <<\EOF +b1 origin/master: ahead 1, behind 1 +b2 origin/master: ahead 1, behind 1 +b3 origin/master: behind 1 +b4 origin/master: ahead 2 +EOF + +test_expect_success 'branch -vv' ' + ( + cd test && + git branch -vv + ) | + sed -n -e "$script" >actual && + test_i18ncmp expect actual +' + test_expect_success 'checkout' ' ( cd test && git checkout b1
Signature · 1 line
1.7.6.845.gc3c05
PATCH v3 2/5 git-tag: introduce long forms for the options
In reply to Michael J GruberLong forms are better to memorize and more reliably uniform across commands.
Design notes:
-u,--local-user is named following the analogous gnupg option.
-l,--list is not an argument taking option but a mode switch.
--- Documentation/git-tag.txt | 8 ++++++++ builtin/tag.c | 16 ++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-)
Documentation/git-tag.txt +8 -0
@@ -43,12 +43,15 @@ GnuPG key for signing. OPTIONS ------- -a:: +--annotate:: Make an unsigned, annotated tag object -s:: +--sign:: Make a GPG-signed tag, using the default e-mail address's key -u <key-id>:: +--local-user=<key-id>:: Make a GPG-signed tag, using the given key -f::
@@ -56,9 +59,11 @@ OPTIONS Replace an existing tag with the given name (instead of failing) -d:: +--delete:: Delete existing tags with the given names. -v:: +--verify:: Verify the gpg signature of the given tag names. -n<num>::
@@ -69,6 +74,7 @@ OPTIONS If the tag is not annotated, the commit message is displayed instead. -l <pattern>:: +--list <pattern>:: List tags with names that match the given pattern (or all if no pattern is given). Running "git tag" without arguments also lists all tags. The pattern is a shell wildcard (i.e., matched
@@ -79,6 +85,7 @@ OPTIONS Only list tags which contain the specified commit. -m <msg>:: +--message=<msg>:: Use the given tag message (instead of prompting). If multiple `-m` options are given, their values are concatenated as separate paragraphs.
@@ -86,6 +93,7 @@ OPTIONS is given. -F <file>:: +--file=<file>:: Take the tag message from the given file. Use '-' to read the message from the standard input. Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
builtin/tag.c +8 -8
@@ -429,21 +429,21 @@ int cmd_tag(int argc, const char **argv, const char *prefix)struct msg_arg msg = {0 ,STRBUF_INIT };struct commit_list *with_commit =NULL ;struct option options[] = { -OPT_BOOLEAN ('l' ,NULL , &list,"list tag names" ), +OPT_BOOLEAN ('l' ,"list" , &list,"list tag names" ), {OPTION_INTEGER ,'n' ,NULL , &lines,"n" ,"print <n> lines of each tag message" ,PARSE_OPT_OPTARG ,NULL ,1 }, -OPT_BOOLEAN ('d' ,NULL , &delete,"delete tags" ), -OPT_BOOLEAN ('v' ,NULL , &verify,"verify tags" ), +OPT_BOOLEAN ('d' ,"delete" , &delete,"delete tags" ), +OPT_BOOLEAN ('v' ,"verify" , &verify,"verify tags" ),OPT_GROUP ("Tag creation options" ), -OPT_BOOLEAN ('a' ,NULL , &annotate, +OPT_BOOLEAN ('a' ,"annotate" , &annotate,"annotated tag, needs a message" ), -OPT_CALLBACK ('m' ,NULL , &msg,"message" , +OPT_CALLBACK ('m' ,"message" , &msg,"message" ,"tag message" , parse_msg_arg), -OPT_FILENAME ('F' ,NULL , &msgfile,"read message from file" ), -OPT_BOOLEAN ('s' ,NULL , &sign,"annotated and GPG-signed tag" ), -OPT_STRING ('u' ,NULL , &keyid,"key-id" , +OPT_FILENAME ('F' ,"file" , &msgfile,"read message from file" ), +OPT_BOOLEAN ('s' ,"sign" , &sign,"annotated and GPG-signed tag" ), +OPT_STRING ('u' ,"local-user" , &keyid,"key-id" ,"use another key to sign the tag" ),OPT__FORCE (&force,"replace the tag if exists" ),
Signature · 1 line
1.7.6.845.gc3c05
PATCH v3 3/5 git-branch: introduce missing long forms for the options
In reply to Michael J GruberLong forms are better to memorize and more reliably uniform across commands.
Names follow precedents, e.g. "git log --remotes".
---
I'm somewhat torn between --move and --rename for -m. We have no real precedent besides "git remote rename".
I left out -M and -D because I feel they should really be -m -f resp. -d -f.
--- Documentation/git-branch.txt | 5 +++++ builtin/branch.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-)
Documentation/git-branch.txt +5 -0
@@ -64,6 +64,7 @@ way to clean up all obsolete remote-tracking branches. OPTIONS ------- -d:: +--delete:: Delete a branch. The branch must be fully merged in its upstream branch, or in `HEAD` if no upstream was set with `--track` or `--set-upstream`.
@@ -72,6 +73,7 @@ OPTIONS Delete a branch irrespective of its merged status. -l:: +--create-reflog:: Create the branch's reflog. This activates recording of all changes made to the branch ref, enabling use of date based sha1 expressions such as "<branchname>@\{yesterday}".
@@ -84,6 +86,7 @@ OPTIONS already. Without `-f` 'git branch' refuses to change an existing branch. -m:: +--move:: Move/rename a branch and the corresponding reflog. -M::
@@ -100,9 +103,11 @@ OPTIONS Same as `--color=never`. -r:: +--remotes:: List or delete (if used with -d) the remote-tracking branches. -a:: +--all:: List both remote-tracking branches and local branches. -v::
builtin/branch.c +5 -5
@@ -624,7 +624,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT_SET_INT (0 ,"set-upstream" , &track,"change upstream info" ,BRANCH_TRACK_OVERRIDE ),OPT__COLOR (&branch_use_color,"use colored output" ), -OPT_SET_INT ('r' ,NULL , &kinds,"act on remote-tracking branches" , +OPT_SET_INT ('r' ,"remotes" , &kinds,"act on remote-tracking branches" ,REF_REMOTE_BRANCH ), { OPTION_CALLBACK, 0, "contains", &with_commit, "commit",
@@ -641,13 +641,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT__ABBREV (&abbrev),OPT_GROUP ("Specific git-branch actions:" ), -OPT_SET_INT ('a' ,NULL , &kinds,"list both remote-tracking and local branches" , +OPT_SET_INT ('a' ,"all" , &kinds,"list both remote-tracking and local branches" ,REF_REMOTE_BRANCH |REF_LOCAL_BRANCH ), -OPT_BIT ('d' ,NULL , &delete,"delete fully merged branch" ,1 ), +OPT_BIT ('d' ,"delete" , &delete,"delete fully merged branch" ,1 ),OPT_BIT ('D' ,NULL , &delete,"delete branch (even if not merged)" ,2 ), -OPT_BIT ('m' ,NULL , &rename,"move/rename a branch and its reflog" ,1 ), +OPT_BIT ('m' ,"move" , &rename,"move/rename a branch and its reflog" ,1 ),OPT_BIT ('M' ,NULL , &rename,"move/rename a branch, even if target exists" ,2 ), -OPT_BOOLEAN ('l' ,NULL , &reflog,"create the branch's reflog" ), +OPT_BOOLEAN ('l' ,"create-reflog" , &reflog,"create the branch's reflog" ),OPT__FORCE (&force_create,"force creation (when already exists)" ), { OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
Signature · 1 line
1.7.6.845.gc3c05
PATCH v3 4/5 branch: introduce --list option
In reply to Michael J GruberCurrently, there is no way to invoke the list mode explicitly, without giving -v to force verbose output.
Introduce a --list option which invokes the list mode. This will be beneficial for invoking list mode with pattern matching, which otherwise would be interpreted as branch creation.
Along with --list, test also combinations of existing options.
--- Documentation/git-branch.txt | 9 +++++++-- builtin/branch.c | 12 +++++++++--- t/t3200-branch.sh | 32 ++++++++++++++++++++++++++++++++ t/t3203-branch-output.sh | 14 ++++++++++++++ 4 files changed, 62 insertions(+), 5 deletions(-)
Documentation/git-branch.txt +7 -2
@@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git branch' [--color[=<when>] | --no-color] [-r | -a] - [-v [--abbrev=<length> | --no-abbrev]] + [--list] [-v [--abbrev=<length> | --no-abbrev]] [(--merged | --no-merged | --contains) [<commit>]] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>] 'git branch' (-m | -M) [<oldbranch>] <newbranch>
@@ -20,7 +20,8 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking -branches to be listed, and option `-a` shows both. +branches to be listed, and option `-a` shows both. This list mode is also +activated by the `--list` and `-v` options (see below). With `--contains`, shows only the branches that contain the named commit (in other words, the branches whose tip commits are descendants of the
@@ -110,11 +111,15 @@ OPTIONS --all:: List both remote-tracking branches and local branches. +--list:: + Activate the list mode. + -v:: --verbose:: Show sha1 and commit subject line for each head, along with relationship to upstream branch (if any). If given twice, print the name of the upstream branch, as well. + `--list` is implied by all verbosity options. --abbrev=<length>:: Alter the sha1's minimum display length in the output listing.
builtin/branch.c +9 -3
@@ -608,7 +608,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, intint cmd_branch (int argc,const char **argv,const char *prefix) { -int delete =0 , rename =0 , force_create =0 ; +int delete =0 , rename =0 , force_create =0 , list =0 ;int verbose =0 , abbrev =-1 , detached =0 ;int reflog =0 ;enum branch_track track;
@@ -647,6 +647,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT_BIT ('D' ,NULL , &delete,"delete branch (even if not merged)" ,2 ),OPT_BIT ('m' ,"move" , &rename,"move/rename a branch and its reflog" ,1 ),OPT_BIT ('M' ,NULL , &rename,"move/rename a branch, even if target exists" ,2 ), +OPT_BOOLEAN (0 ,"list" , &list,"list branch names" ),OPT_BOOLEAN ('l' ,"create-reflog" , &reflog,"create the branch's reflog" ), OPT__FORCE(&force_create, "force creation (when already exists)"), {
@@ -686,7 +687,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc =parse_options (argc, argv, prefix, options, builtin_branch_usage,0 ); -if (!!delete + !!rename + !!force_create >1 ) + +if (!delete && !rename && !force_create && + (argc ==0 || (verbose && argc))) + list =1 ; + +if (!!delete + !!rename + !!force_create + !!list >1 )usage_with_options (builtin_branch_usage, options);if (abbrev ==-1 )
@@ -694,7 +700,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (delete)return delete_branches (argc, argv, delete >1 , kinds); -else if (argc ==0 ) +else if (list)return print_ref_list (kinds, detached, verbose, abbrev, with_commit);else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );
t/t3200-branch.sh +32 -0
@@ -98,6 +98,38 @@ test_expect_success 'git branch -m q r/q should fail when r exists' ' test_must_fail git branch -m q r/q ' +test_expect_success 'git branch -v -d t should work' ' + git branch t && + test .git/refs/heads/t && + git branch -v -d t && + test ! -f .git/refs/heads/t +' + +test_expect_success 'git branch -v -m t s should work' ' + git branch t && + test .git/refs/heads/t && + git branch -v -m t s && + test ! -f .git/refs/heads/t && + test -f .git/refs/heads/s && + git branch -d s +' + +test_expect_success 'git branch -m -d t s should fail' ' + git branch t && + test .git/refs/heads/t && + test_must_fail git branch -m -d t s && + git branch -d t && + test ! -f .git/refs/heads/t +' + +test_expect_success 'git branch --list -d t should fail' ' + git branch t && + test .git/refs/heads/t && + test_must_fail git branch --list -d t && + git branch -d t && + test ! -f .git/refs/heads/t +' + test_expect_success 'git branch -M foo bar should fail when bar is checked out' ' git branch bar && git checkout -b foo &&
t/t3203-branch-output.sh +14 -0
@@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' ' test_cmp expect actual ' +test_expect_success 'git branch --list shows local branches' ' + git branch --list >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' + branch-one + branch-two +EOF +test_expect_success 'git branch --list pattern shows matching local branches' ' + git branch --list branch* >actual && + test_cmp expect actual +' + cat >expect <<'EOF' origin/HEAD -> origin/branch-one origin/branch-one
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCHv3 4/5] branch: introduce --list option
t/t3203-branch-output.sh test_expect_success 'git branch shows local branches' ' · line 47
Quoted 13 lines · Michael J Gruber
t/t3203-branch-output.sh +13
-0+test_expect_success 'git branch --list shows local branches' ' + git branch --list >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' + branch-one + branch-two +EOF +test_expect_success 'git branch --list pattern shows matching local branches' ' + git branch --list branch* >actual && + test_cmp expect actual +'
Does this one exclude the "* master" entry at this stage in the series?
Re: [PATCHv3 4/5] branch: introduce --list option
Junio C Hamano venit, vidit, dixit 29.08.2011 07:55:
Quoted 17 lines
t/t3203-branch-output.sh test_expect_success 'git branch shows local branches' ' · line 47
Quoted 13 lines · Michael J Gruber
t/t3203-branch-output.sh +13
-0+test_expect_success 'git branch --list shows local branches' ' + git branch --list >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' + branch-one + branch-two +EOF +test_expect_success 'git branch --list pattern shows matching local branches' ' + git branch --list branch* >actual && + test_cmp expect actual +'Does this one exclude the "* master" entry at this stage in the series?
Sheesh, that rebasing mistake (flipping the order of 4 and 5) was present in v2 already. Only recently I learned about rebase-i's "exec" and have to make it a habit to use it for step-by-step series testing.
Sorry, I'll send out v3 a bit later when I see that there are no more comments (and a full step-by-step series test has passed).
Michael
Re: [PATCHv3 4/5] branch: introduce --list option
Quoted 3 lines · Michael J Gruber
Sheesh, that rebasing mistake (flipping the order of 4 and 5) was present in v2 already. Only recently I learned about rebase-i's "exec" and have to make it a habit to use it for step-by-step series testing.
That's Ok. Locally moved the offending part of the test to 5 when applying.
Thanks.
v3 cover patterns for branch list
In reply to Michael J Gruberv3 has reworded commit messages for 2,3,4 and tests for combinations of branch options in 4, as suggested.
No code changes (besides the additional tests in 4).
Michael J Gruber (5):
t6040: test branch -vv
git-tag: introduce long forms for the options
git-branch: introduce missing long forms for the options
branch: introduce --list option
branch: allow pattern arguments
Documentation/git-branch.txt | 20 +++++++++++++++-- Documentation/git-tag.txt | 8 +++++++ builtin/branch.c | 46 +++++++++++++++++++++++++++++++---------- builtin/tag.c | 16 +++++++------- t/t3200-branch.sh | 32 +++++++++++++++++++++++++++++ t/t3203-branch-output.sh | 24 +++++++++++++++++++++ t/t6040-tracking-info.sh | 16 ++++++++++++++ 7 files changed, 140 insertions(+), 22 deletions(-)
Signature · 1 line
1.7.6.845.gc3c05
PATCH v3 5/5 branch: allow pattern arguments
In reply to Michael J GruberAllow pattern arguments for the list mode just like for git tag -l.
--- Documentation/git-branch.txt | 8 ++++++-- builtin/branch.c | 24 +++++++++++++++++++++--- t/t3203-branch-output.sh | 10 ++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-)
Documentation/git-branch.txt +6 -2
@@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git branch' [--color[=<when>] | --no-color] [-r | -a] [--list] [-v [--abbrev=<length> | --no-abbrev]] - [(--merged | --no-merged | --contains) [<commit>]] + [(--merged | --no-merged | --contains) [<commit>]] [<pattern>...] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>] 'git branch' (-m | -M) [<oldbranch>] <newbranch> 'git branch' (-d | -D) [-r] <branchname>...
@@ -22,6 +22,9 @@ With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking branches to be listed, and option `-a` shows both. This list mode is also activated by the `--list` and `-v` options (see below). +<pattern> restricts the output to matching branches, the pattern is a shell +wildcard (i.e., matched using fnmatch(3)) +Multiple patterns may be given; if any of them matches, the tag is shown. With `--contains`, shows only the branches that contain the named commit (in other words, the branches whose tip commits are descendants of the
@@ -112,7 +115,8 @@ OPTIONS List both remote-tracking branches and local branches. --list:: - Activate the list mode. + Activate the list mode. `git branch <pattern>` would try to create a branch, + use `git branch --list <pattern>` to list matching branches. -v:: --verbose::
builtin/branch.c +21 -3
@@ -260,9 +260,22 @@ static char *resolve_symref(const char *src, const char *prefix)struct append_ref_cb {struct ref_list *ref_list; +const char **pattern;int ret; }; +static int match_patterns (const char **pattern,const char *refname) +{ +if (!*pattern) +return 1 ;/* no pattern always matches */ +while (*pattern) { +if (!fnmatch (*pattern, refname,0 )) +return 1 ; + pattern++; + } +return 0 ; +} +static int append_ref (const char *refname,const unsigned char *sha1,int flags,void *cb_data) {struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);
@@ -297,6 +310,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ; +if (!match_patterns (cb->pattern, refname)) +return 0 ; + commit =NULL ;if (ref_list->verbose || ref_list->with_commit || merge_filter !=NO_FILTER ) { commit =lookup_commit_reference_gently (sha1,1 );
@@ -492,7 +508,7 @@ static void show_detached(struct ref_list *ref_list) } } -static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit) +static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit,const char **pattern) {int i;struct append_ref_cb cb;
@@ -506,6 +522,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struif (merge_filter !=NO_FILTER )init_revisions (&ref_list.revs,NULL ); cb.ref_list = &ref_list; + cb.pattern = pattern; cb.ret =0 ;for_each_rawref (append_ref, &cb);if (merge_filter !=NO_FILTER ) {
@@ -523,7 +540,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struqsort (ref_list.list, ref_list.index,sizeof (struct ref_item ), ref_cmp); detached = (detached && (kinds &REF_LOCAL_BRANCH )); -if (detached) +if (detached &&match_patterns (pattern,"HEAD" ))show_detached (&ref_list);for (i =0 ; i < ref_list.index; i++) {
@@ -701,7 +718,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (delete)return delete_branches (argc, argv, delete >1 , kinds);else if (list) -return print_ref_list (kinds, detached, verbose, abbrev, with_commit); +return print_ref_list (kinds, detached, verbose, abbrev, + with_commit, argv);else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );else if (rename && (argc ==2 ))
t/t3203-branch-output.sh +10 -0
@@ -81,6 +81,16 @@ test_expect_success 'git branch -v shows branch summaries' ' ' cat >expect <<'EOF' +two +one +EOF +test_expect_success 'git branch -v pattern shows branch summaries' ' + git branch -v branch* >tmp && + awk "{print \$NF}" <tmp >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' * (no branch) branch-one branch-two
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCHv3 5/5] branch: allow pattern arguments
builtin/branch.c static char *resolve_symref(const char *src, const char *prefix) · line 277
Quoted 11 lines · Michael J Gruber
builtin/branch.c +11
-0+static int match_patterns (const char **pattern,const char *refname) +{ +if (!*pattern) +return 1 ;/* no pattern always matches */ +while (*pattern) { +if (!fnmatch (*pattern, refname,0 )) +return 1 ; + pattern++; + } +return 0 ; +}
Nitpick: maybe builtin/branch.c and builtin/tag.c could share match_pattern().?
A second thought: the printed "remotes/" prefix could be confusing for users, since it seems to be part of the refname. For example:
$ git branch -a * master maint man remotes/origin/master remotes/origin/maint remotes/origin/man
$ git branch -a --list remotes/origin* [no output]
but
$ git branch -a --list origin* remotes/origin/master remotes/origin/maint remotes/origin/man
(Sorry in case I missed that) What's the reason you decided --list to show local branches only? Maybe --list could show all refnames without any extra prefix.?
Thanks.
Re: [PATCHv3 5/5] branch: allow pattern arguments
Michael Schubert venit, vidit, dixit 06.09.2011 15:10:
Quoted 6 lines · Michael J Gruber
Quoted 5 lines
builtin/branch.c +5
-0+static int match_patterns (const char **pattern,const char *refname) +{ +if (!*pattern) +return 1 ;/* no pattern always matches */ +while (*pattern) {
Quoted 8 lines
builtin/branch.c static char *resolve_symref(const char *src, const char *prefix) · line 277
Quoted 6 lines
builtin/branch.c +6
-0+if (!fnmatch (*pattern, refname,0 )) +return 1 ; + pattern++; + } +return 0 ; +}Nitpick: maybe
builtin/branch.candbuiltin/tag.ccould sharematch_pattern().?
I think all commands which list refs should share code - for-each-ref, branch, tag, replace. I suggest to unify log and for-each-ref-formats first, the unify ref listers.
Quoted 16 lines
A second thought: the printed "remotes/" prefix could be confusing for users, since it seems to be part of the refname. For example:
$ git branch -a * master maint man remotes/origin/master remotes/origin/maint remotes/origin/man$ git branch -a --list remotes/origin* [no output]but
Quoted 7 lines
$ git branch -a --list origin* remotes/origin/master remotes/origin/maint remotes/origin/man(Sorry in case I missed that) What's the reason you decided --list to show local branches only? Maybe --list could show all refnames without any extra prefix.?
I didn't decide anything here. "git branch" lists all local branches and has been doing that forever, and "--list" is and should be a noop without a pattern. That was the idea: -r/-a select refnames, --list/-v/-vv activate the list mode(s), and the pattern is matched against the selected refs.
(This is one reason why I didn't want it to be named --glob - the pattern is a filter, not a selector.)
That being said, I find the fact that "-a --list remotes/origin/*" does not match anything somewhat disconcerting, although it fits in with the general idea of "git branch": it deals with branch names, not ref names. Have you ever tried to delete a remote branch?
git branch -r -d origin/maint # workee
git branch -r -d remotes/origin/maint # no workee
Without -r, it doesn't work either.
So, the way it is it fits in with how "git branch" works, and is different from for-each-ref (and rev-list --glob). I don't like it, because you may have a local branch origin/maint (i.e. refs/heads/origin/maint) which you can't distinguish from the remote branch by a pattern, only by using or not using -r. But it's the same as with "git branch -d", really.
Michael
Re: [PATCHv3 5/5] branch: allow pattern arguments
Heya,
Quoted 6 lines · Michael J Gruber
Have you ever tried to delete a remote branch?
git branch -r -d origin/maint # workee
git branch -r -d remotes/origin/maint # no workeeWithout -r, it doesn't work either.
Heh, I read this as "worktree" / "no worktree" at least 4 times.
Signature · 3 lines
Cheers, Sverre Rabbelier
Re: [PATCHv3 5/5] branch: allow pattern arguments
Sverre Rabbelier venit, vidit, dixit 06.09.2011 16:26:
Quoted 12 lines
Heya,
Quoted 6 lines · Michael J Gruber
Have you ever tried to delete a remote branch?
git branch -r -d origin/maint # workee
git branch -r -d remotes/origin/maint # no workeeWithout -r, it doesn't work either.
Heh, I read this as "worktree" / "no worktree" at least 4 times.
Yes, our require_work_tree should really be renamed to
no_worktree_no_workee
The beauty of pidgin english ;)
Michael
PATCH v2 5/5 branch: allow pattern arguments
In reply to Jeff KingAllow pattern arguments for the list mode just like for git tag -l.
--- Documentation/git-branch.txt | 8 ++++++-- builtin/branch.c | 24 +++++++++++++++++++++--- t/t3203-branch-output.sh | 10 ++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-)
Documentation/git-branch.txt +6 -2
@@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git branch' [--color[=<when>] | --no-color] [-r | -a] [--list] [-v [--abbrev=<length> | --no-abbrev]] - [(--merged | --no-merged | --contains) [<commit>]] + [(--merged | --no-merged | --contains) [<commit>]] [<pattern>...] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>] 'git branch' (-m | -M) [<oldbranch>] <newbranch> 'git branch' (-d | -D) [-r] <branchname>...
@@ -22,6 +22,9 @@ With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking branches to be listed, and option `-a` shows both. This list mode is also activated by the `--list` and `-v` options (see below). +<pattern> restricts the output to matching branches, the pattern is a shell +wildcard (i.e., matched using fnmatch(3)) +Multiple patterns may be given; if any of them matches, the tag is shown. With `--contains`, shows only the branches that contain the named commit (in other words, the branches whose tip commits are descendants of the
@@ -112,7 +115,8 @@ OPTIONS List both remote-tracking branches and local branches. --list:: - Activate the list mode. + Activate the list mode. `git branch <pattern>` would try to create a branch, + use `git branch --list <pattern>` to list matching branches. -v:: --verbose::
builtin/branch.c +21 -3
@@ -260,9 +260,22 @@ static char *resolve_symref(const char *src, const char *prefix)struct append_ref_cb {struct ref_list *ref_list; +const char **pattern;int ret; }; +static int match_patterns (const char **pattern,const char *refname) +{ +if (!*pattern) +return 1 ;/* no pattern always matches */ +while (*pattern) { +if (!fnmatch (*pattern, refname,0 )) +return 1 ; + pattern++; + } +return 0 ; +} +static int append_ref (const char *refname,const unsigned char *sha1,int flags,void *cb_data) {struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);
@@ -297,6 +310,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ; +if (!match_patterns (cb->pattern, refname)) +return 0 ; + commit =NULL ;if (ref_list->verbose || ref_list->with_commit || merge_filter !=NO_FILTER ) { commit =lookup_commit_reference_gently (sha1,1 );
@@ -492,7 +508,7 @@ static void show_detached(struct ref_list *ref_list) } } -static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit) +static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit,const char **pattern) {int i;struct append_ref_cb cb;
@@ -506,6 +522,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struif (merge_filter !=NO_FILTER )init_revisions (&ref_list.revs,NULL ); cb.ref_list = &ref_list; + cb.pattern = pattern; cb.ret =0 ;for_each_rawref (append_ref, &cb);if (merge_filter !=NO_FILTER ) {
@@ -523,7 +540,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struqsort (ref_list.list, ref_list.index,sizeof (struct ref_item ), ref_cmp); detached = (detached && (kinds &REF_LOCAL_BRANCH )); -if (detached) +if (detached &&match_patterns (pattern,"HEAD" ))show_detached (&ref_list);for (i =0 ; i < ref_list.index; i++) {
@@ -701,7 +718,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (delete)return delete_branches (argc, argv, delete >1 , kinds);else if (list) -return print_ref_list (kinds, detached, verbose, abbrev, with_commit); +return print_ref_list (kinds, detached, verbose, abbrev, + with_commit, argv);else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );else if (rename && (argc ==2 ))
t/t3203-branch-output.sh +10 -0
@@ -81,6 +81,16 @@ test_expect_success 'git branch -v shows branch summaries' ' ' cat >expect <<'EOF' +two +one +EOF +test_expect_success 'git branch -v pattern shows branch summaries' ' + git branch -v branch* >tmp && + awk "{print \$NF}" <tmp >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' * (no branch) branch-one branch-two
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCHv2 5/5] branch: allow pattern arguments
This and [4/5] both looked good; will update mg/branch-list with this round.
Thanks.
PATCH v2 1/5 branch: allow pattern arguments
In reply to Michael J GruberAllow pattern arguments for the list mode just like for git tag -l.
--- Documentation/git-branch.txt | 7 +++++-- builtin/branch.c | 13 +++++++++---- t/t3203-branch-output.sh | 10 ++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-)
Documentation/git-branch.txt +5 -2
@@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git branch' [--color[=<when>] | --no-color] [-r | -a] [-v [--abbrev=<length> | --no-abbrev]] - [(--merged | --no-merged | --contains) [<commit>]] + [(--merged | --no-merged | --contains) [<commit>]] [<pattern>] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>] 'git branch' (-m | -M) [<oldbranch>] <newbranch> 'git branch' (-d | -D) [-r] <branchname>...
@@ -20,7 +20,10 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking -branches to be listed, and option `-a` shows both. +branches to be listed, and option `-a` shows both. This list mode is also +activated by the `-v` option (see below). +<pattern> restricts the output to matching branches, the pattern is a shell +wildcard (i.e., matched using fnmatch(3)) With `--contains`, shows only the branches that contain the named commit (in other words, the branches whose tip commits are descendants of the
builtin/branch.c +9 -4
@@ -260,6 +260,7 @@ static char *resolve_symref(const char *src, const char *prefix)struct append_ref_cb {struct ref_list *ref_list; +const char *pattern;int ret; };
@@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ; +if (cb->pattern &&fnmatch (cb->pattern, refname,0 )) +return 0 ; + commit =NULL ;if (ref_list->verbose || ref_list->with_commit || merge_filter !=NO_FILTER ) { commit =lookup_commit_reference_gently (sha1,1 );
@@ -492,7 +496,7 @@ static void show_detached(struct ref_list *ref_list) } } -static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit) +static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit,const char *pattern) {int i;struct append_ref_cb cb;
@@ -506,6 +510,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struif (merge_filter !=NO_FILTER )init_revisions (&ref_list.revs,NULL ); cb.ref_list = &ref_list; + cb.pattern = pattern; cb.ret =0 ;for_each_rawref (append_ref, &cb);if (merge_filter !=NO_FILTER ) {
@@ -523,7 +528,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struqsort (ref_list.list, ref_list.index,sizeof (struct ref_item ), ref_cmp); detached = (detached && (kinds &REF_LOCAL_BRANCH )); -if (detached) +if (detached && (!pattern || !fnmatch (pattern,"HEAD" ,0 )))show_detached (&ref_list);for (i =0 ; i < ref_list.index; i++) {
@@ -695,8 +700,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (delete)return delete_branches (argc, argv, delete >1 , kinds); -else if (argc ==0 ) -return print_ref_list (kinds, detached, verbose, abbrev, with_commit); +else if (argc ==0 || (verbose && argc ==1 )) +return print_ref_list (kinds, detached, verbose, abbrev, with_commit, argc ? argv[0 ] :NULL );else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );else if (rename && (argc ==2 ))
t/t3203-branch-output.sh +10 -0
@@ -67,6 +67,16 @@ test_expect_success 'git branch -v shows branch summaries' ' ' cat >expect <<'EOF' +two +one +EOF +test_expect_success 'git branch -v pattern shows branch summaries' ' + git branch -v branch* >tmp && + awk "{print \$NF}" <tmp >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' * (no branch) branch-one branch-two
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCH 1/5] branch: allow pattern arguments
builtin/branch.c int cmd_branch(int argc, const char **argv, const char *prefix) · line 704
Quoted 4 lines · Michael J Gruber
builtin/branch.c +2
-2-else if (argc ==0 ) -return print_ref_list (kinds, detached, verbose, abbrev, with_commit); +else if (argc ==0 || (verbose && argc ==1 )) +return print_ref_list (kinds, detached, verbose, abbrev, with_commit, argc ? argv[0 ] :NULL );
Note that "git tag -l" takes multiple patterns these days (it used to silently ignore everything after the first one!). "git branch" should probably do the same.
-Peff
Re: [PATCH 1/5] branch: allow pattern arguments
Quoted 10 lines · Jeff King
builtin/branch.c int cmd_branch(int argc, const char **argv, const char *prefix) · line 704
Quoted 4 lines · Michael J Gruber
builtin/branch.c +2
-2-else if (argc ==0 ) -return print_ref_list (kinds, detached, verbose, abbrev, with_commit); +else if (argc ==0 || (verbose && argc ==1 )) +return print_ref_list (kinds, detached, verbose, abbrev, with_commit, argc ? argv[0 ] :NULL );Note that "git tag -l" takes multiple patterns these days (it used to silently ignore everything after the first one!). "git branch" should probably do the same.
Agreed.
Re: [PATCH 1/5] branch: allow pattern arguments
Quoted 13 lines · Junio C Hamano
Quoted 10 lines · Jeff King
Review
Quoted 4 lines · Michael J Gruber
(quoted diff) +2
-2- else if (argc == 0) - return print_ref_list(kinds, detached, verbose, abbrev, with_commit); + else if (argc == 0 || (verbose && argc == 1)) + return print_ref_list(kinds, detached, verbose, abbrev, with_commit, argc ? argv[0] : NULL);Note that "git tag -l" takes multiple patterns these days (it used to silently ignore everything after the first one!). "git branch" should probably do the same.
Quoted 1 line
Agreed.
... and can be done without too much additional code.
An offtopic side note about naming:
I called it "const char **pattern" not "patterns" and that is deliberate. I find it natural to be able to call the 2nd pattern, counting from 0 as any CS person would, by spelling "pattern[2]". "patterns[2]" sounds as if I am have multiple sets of patterns and refering to the second set of patterns.
builtin/branch.c | 25 +++++++++++++++++++------ 1 files changed, 19 insertions(+), 6 deletions(-)
builtin/branch.c +19 -6
@@ -260,10 +260,22 @@ static char *resolve_symref(const char *src, const char *prefix)struct append_ref_cb {struct ref_list *ref_list; -const char *pattern; +const char **pattern;int ret; }; +static int match_patterns (const char **pattern,const char *refname) +{ +if (!*pattern) +return 1 ;/* no pattern always matches */ +while (*pattern) { +if (!fnmatch (*pattern, refname,0 )) +return 1 ; + pattern++; + } +return 0 ; +} +static int append_ref (const char *refname,const unsigned char *sha1,int flags,void *cb_data) {struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);
@@ -298,7 +310,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ; -if (cb->pattern &&fnmatch (cb->pattern, refname,0 )) +if (!match_patterns (cb->pattern, refname))return 0 ; commit =NULL ;
@@ -496,7 +508,7 @@ static void show_detached(struct ref_list *ref_list) } } -static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit,const char *pattern) +static int print_ref_list (int kinds,int detached,int verbose,int abbrev,struct commit_list *with_commit,const char **pattern) {int i;struct append_ref_cb cb;
@@ -528,7 +540,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struqsort (ref_list.list, ref_list.index,sizeof (struct ref_item ), ref_cmp); detached = (detached && (kinds &REF_LOCAL_BRANCH )); -if (detached && (!pattern || !fnmatch (pattern,"HEAD" ,0 ))) +if (detached &&match_patterns (pattern,"HEAD" ))show_detached (&ref_list);for (i =0 ; i < ref_list.index; i++) {
@@ -703,8 +715,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)if (delete)return delete_branches (argc, argv, delete >1 , kinds); -else if (argc ==0 || (verbose && argc ==1 )) -return print_ref_list (kinds, detached, verbose, abbrev, with_commit, argc ? argv[0 ] :NULL ); +else if (argc ==0 || (verbose && argc)) +return print_ref_list (kinds, detached, verbose, abbrev, + with_commit, argv);else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );else if (rename && (argc ==2 ))
PATCH v2 2/5 branch: introduce --list argument
In reply to Michael J GruberCurrently, there is no way to invoke the list mode with a pattern because this is interpreted as branch creation.
Introduce a --list argument which invokes the list mode.
--- Documentation/git-branch.txt | 9 +++++++-- builtin/branch.c | 10 +++++++--- t/t3203-branch-output.sh | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-)
Documentation/git-branch.txt +7 -2
@@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git branch' [--color[=<when>] | --no-color] [-r | -a] - [-v [--abbrev=<length> | --no-abbrev]] + [--list] [-v [--abbrev=<length> | --no-abbrev]] [(--merged | --no-merged | --contains) [<commit>]] [<pattern>] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>] 'git branch' (-m | -M) [<oldbranch>] <newbranch>
@@ -21,7 +21,7 @@ DESCRIPTION With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. Option `-r` causes the remote-tracking branches to be listed, and option `-a` shows both. This list mode is also -activated by the `-v` option (see below). +activated by the `--list` and `-v` options (see below). <pattern> restricts the output to matching branches, the pattern is a shell wildcard (i.e., matched using fnmatch(3))
@@ -108,11 +108,16 @@ OPTIONS -a:: List both remote-tracking branches and local branches. +--list:: + Activate the list mode. `git branch <pattern>` would try to create a branch, + use `git branch --list <pattern>` to list matching branches. + -v:: --verbose:: Show sha1 and commit subject line for each head, along with relationship to upstream branch (if any). If given twice, print the name of the upstream branch, as well. + `--list` is implied by all verbosity options. --abbrev=<length>:: Alter the sha1's minimum display length in the output listing.
builtin/branch.c +7 -3
@@ -617,7 +617,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, intint cmd_branch (int argc,const char **argv,const char *prefix) { -int delete =0 , rename =0 , force_create =0 ; +int delete =0 , rename =0 , force_create =0 , list =0 ;int verbose =0 , abbrev =DEFAULT_ABBREV , detached =0 ;int reflog =0 ;enum branch_track track;
@@ -656,6 +656,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT_BIT ('D' ,NULL , &delete,"delete branch (even if not merged)" ,2 ),OPT_BIT ('m' ,NULL , &rename,"move/rename a branch and its reflog" ,1 ),OPT_BIT ('M' ,NULL , &rename,"move/rename a branch, even if target exists" ,2 ), +OPT_BOOLEAN (0 ,"list" , &list,"list branch names" ),OPT_BOOLEAN ('l' ,NULL , &reflog,"create the branch's reflog" ), OPT__FORCE(&force_create, "force creation (when already exists)"), {
@@ -695,12 +696,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc =parse_options (argc, argv, prefix, options, builtin_branch_usage,0 ); -if (!!delete + !!rename + !!force_create >1 ) +if (!!delete + !!rename + !!force_create + !!list >1 )usage_with_options (builtin_branch_usage, options); +if (argc ==0 || (verbose && argc ==1 )) + list =1 ; +if (delete)return delete_branches (argc, argv, delete >1 , kinds); -else if (argc ==0 || (verbose && argc ==1 )) +else if (list)return print_ref_list (kinds, detached, verbose, abbrev, with_commit, argc ? argv[0 ] :NULL );else if (rename && (argc ==1 ))rename_branch (head, argv[0 ], rename >1 );
t/t3203-branch-output.sh +14 -0
@@ -32,6 +32,20 @@ test_expect_success 'git branch shows local branches' ' test_cmp expect actual ' +test_expect_success 'git branch --list shows local branches' ' + git branch --list >actual && + test_cmp expect actual +' + +cat >expect <<'EOF' + branch-one + branch-two +EOF +test_expect_success 'git branch --list pattern shows matching local branches' ' + git branch --list branch* >actual && + test_cmp expect actual +' + cat >expect <<'EOF' origin/HEAD -> origin/branch-one origin/branch-one
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCH 2/5] branch: introduce --list argument
Quoted 4 lines · Michael J Gruber
Currently, there is no way to invoke the list mode with a pattern because this is interpreted as branch creation.
Introduce a --list argument which invokes the list mode.
Probably this is --list "option", but I think this is a good idea to allow "we are in list mode" without having to invoke "verbose" output.
Re: [PATCH 2/5] branch: introduce --list argument
In reply to Michael J GruberReview int cmd_branch(int argc, const char **argv, const char *prefix) · line 704
Quoted 11 lines · Michael J Gruber
(quoted diff) +4
-1@@ -695,12 +696,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, builtin_branch_usage, 0); - if (!!delete + !!rename + !!force_create > 1) + if (!!delete + !!rename + !!force_create + !!list > 1) usage_with_options(builtin_branch_usage, options); + if (argc == 0 || (verbose && argc == 1)) + list = 1; +
I am afraid this is not quite right.
What happens if one of delete/rename/force-create can take a single argument, or more importantly, if we someday gain another option that can take zero or one argument and is incompatible with other operating mode?
For example, what happens to this command line with your "git branch":
$ git branch -v -m boo
The first test passes (no explicit --list), and then you violate the "only one of these operating mode can be set" assertion you made yourself by flipping list on, no?
It is a good practice to always run the defaulting tweak *before* checking options that are mutually incompatible, to catch your own mistake in the tweaking code.
On top of my previous "multiple patterns allowed" tweak, a replacement patch to this file may look like this. I suspect there should be a better way to represent the mode in a single variable and enforce that there is only one chosen, but that is left for another day.
builtin/branch.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-)
builtin/branch.c +9 -3
@@ -629,7 +629,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, intint cmd_branch (int argc,const char **argv,const char *prefix) { -int delete =0 , rename =0 , force_create =0 ; +int delete =0 , rename =0 , force_create =0 , list =0 ;int verbose =0 , abbrev =DEFAULT_ABBREV , detached =0 ;int reflog =0 ;enum branch_track track;
@@ -668,6 +668,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)OPT_BIT ('D' ,NULL , &delete,"delete branch (even if not merged)" ,2 ),OPT_BIT ('m' ,NULL , &rename,"move/rename a branch and its reflog" ,1 ),OPT_BIT ('M' ,NULL , &rename,"move/rename a branch, even if target exists" ,2 ), +OPT_BOOLEAN (0 ,"list" , &list,"list branch names" ),OPT_BOOLEAN ('l' ,NULL , &reflog,"create the branch's reflog" ), OPT__FORCE(&force_create, "force creation (when already exists)"), {
@@ -710,12 +711,17 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc =parse_options (argc, argv, prefix, options, builtin_branch_usage,0 ); -if (!!delete + !!rename + !!force_create >1 ) + +if (!delete && !rename && !force_create && + (argc ==0 || (verbose && argc))) + list =1 ; + +if (!!delete + !!rename + !!force_create + !!list >1 )usage_with_options (builtin_branch_usage, options);if (delete)return delete_branches (argc, argv, delete >1 , kinds); -else if (argc ==0 || (verbose && argc)) +else if (list)return print_ref_list (kinds, detached, verbose, abbrev, with_commit, argv);else if (rename && (argc ==1 ))
PATCH v2 3/5 t6040; test branch -vv
In reply to Michael J Grubert6040 has a test for 'git branch -v' but not for 'git branch -vv'. Add one.
--- t/t6040-tracking-info.sh | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)
t/t6040-tracking-info.sh +16 -0
@@ -51,6 +51,22 @@ test_expect_success 'branch -v' ' test_i18ncmp expect actual ' +cat >expect <<\EOF +b1 origin/master: ahead 1, behind 1 +b2 origin/master: ahead 1, behind 1 +b3 origin/master: behind 1 +b4 origin/master: ahead 2 +EOF + +test_expect_success 'branch -vv' ' + ( + cd test && + git branch -vv + ) | + sed -n -e "$script" >actual && + test_i18ncmp expect actual +' + test_expect_success 'checkout' ' ( cd test && git checkout b1
Signature · 1 line
1.7.6.845.gc3c05
PATCH v2 4/5 branch: restructure -v vs. -vv
In reply to Michael J Gruberahead/behind info is expensive, upstream name info cheap. Therefore, make -v output the upstream branch name and -vv add the ahead/behind info.
--- Documentation/git-branch.txt | 4 ++-- builtin/branch.c | 34 ++++++++++++++++------------------ t/t6040-tracking-info.sh | 8 ++++---- 3 files changed, 22 insertions(+), 24 deletions(-)
Documentation/git-branch.txt +2 -2
@@ -115,8 +115,8 @@ OPTIONS -v:: --verbose:: Show sha1 and commit subject line for each head, along with - relationship to upstream branch (if any). If given twice, print - the name of the upstream branch, as well. + the name of the upstream branch (if any). If given twice, print + the relationship to the upstream branch (ahead/behind), as well. `--list` is implied by all verbosity options. --abbrev=<length>::
builtin/branch.c +16 -18
@@ -359,29 +359,27 @@ static int ref_cmp(const void *r1, const void *r2) }static void fill_tracking_info (struct strbuf *stat,const char *branch_name, -int show_upstream_ref) +int verbose) {int ours, theirs;struct branch *branch =branch_get (branch_name); -if (!stat_tracking_info (branch, &ours, &theirs)) { -if (branch && branch->merge && branch->merge[0 ]->dst && - show_upstream_ref) -strbuf_addf (stat,"[%s] " , -shorten_unambiguous_ref (branch->merge[0 ]->dst,0 )); +/* verbose >= 1 */ +if (!(branch && branch->merge && branch->merge[0 ]->dst))return ; - } -strbuf_addch (stat,'[' ); -if (show_upstream_ref) -strbuf_addf (stat,"%s: " , -shorten_unambiguous_ref (branch->merge[0 ]->dst,0 )); -if (!ours) -strbuf_addf (stat,_ ("behind %d] " ), theirs); -else if (!theirs) -strbuf_addf (stat,_ ("ahead %d] " ), ours); -else -strbuf_addf (stat,_ ("ahead %d, behind %d] " ), ours, theirs); +strbuf_addstr (stat,shorten_unambiguous_ref (branch->merge[0 ]->dst,0 )); + +if (verbose >=2 &&stat_tracking_info (branch, &ours, &theirs)) { +strbuf_addstr (stat,": " ); +if (!ours) +strbuf_addf (stat,_ ("behind %d" ), theirs); +else if (!theirs) +strbuf_addf (stat,_ ("ahead %d" ), ours); +else +strbuf_addf (stat,_ ("ahead %d, behind %d" ), ours, theirs); + } +strbuf_addstr (stat,"] " ); }static int matches_merge_filter (struct commit *commit)
@@ -408,7 +406,7 @@ static void add_verbose_info(struct strbuf *out, struct ref_item *item, }if (item->kind ==REF_LOCAL_BRANCH ) -fill_tracking_info (&stat, item->name, verbose >1 ); +fill_tracking_info (&stat, item->name, verbose); strbuf_addf(out, " %s %s%s", find_unique_abbrev(item->commit->object.sha1, abbrev),
t/t6040-tracking-info.sh +4 -4
@@ -36,10 +36,10 @@ test_expect_success setup ' script='s/^..\(b.\)[ 0-9a-f]*\[\([^]]*\)\].*/\1 \2/p' cat >expect <<\EOF -b1 ahead 1, behind 1 -b2 ahead 1, behind 1 -b3 behind 1 -b4 ahead 2 +b1 origin/master +b2 origin/master +b3 origin/master +b4 origin/master EOF test_expect_success 'branch -v' '
Signature · 1 line
1.7.6.845.gc3c05
Re: [PATCH 4/5] branch: restructure -v vs. -vv
Quoted 3 lines · Michael J Gruber
ahead/behind info is expensive, upstream name info cheap. Therefore, make -v output the upstream branch name and -vv add the ahead/behind info.
While I do not care too much about the end result, and I even suspect that swapping the meaning might be better at the semantic level, I do not agree with the above line of reasoning. It is not based on what the end user wants at all, but is based on how easily you can produce results.
If a relatively expensive information is what is more often wanted and the users are willing to pay the price to compute it, it is very reasonable to use short-and-sweet -v for showing only that information, and have them type -vv to ask for a less common information.
I also suspect that "ahead/behind" and "who-is-upstream" may be orthogonal and we may not tie these to degree of verbosity. Jeff's suggestion to teach these to for-each-ref may be along a similar thought.
You however may be able to argue "When the user wants A/B, s/he always wants who-is-upstream, and asking for A/B and not wanting who-is-upstream is insane". If "A/B" does not make sense without seeing "who-is-upstream", but if seeing "who-is-upstream" alone makes sense without seeing "A/B", then you can argue that these two are indeed degrees of verbosity, and it may be justifiable to make -v give "who-is-upstream", and make -vv give "A/B and who-is-upstream".
But I suspect that much more people have more than one topics cooking on top of upstream (i.e. need for A/B) than people who work with these topics based on different upstreams (i.e. need for "who-is-upstream"). People who base their topics on only one upstream do not need "who-is-upstream" to understand A/B.
I am wondering if "branch -v=<comma separated tokens>", where currently available tokens are "sha1", "upstream", "ahead/behind", is the right way to keep these orthogonal and extensible (of course you would want a shorter mnemonic). Then existing -v and -vv can be understood as aliases to:
-v === -v=sha1,ahead/behind
-vv === -v=sha1,upstream,ahead/behindand you can naturally extend the vocabulary with "patchsame" to define your -vvv introduced in [5/5].
PATCH v2 5/5 branch: give patchsame count with -vvv
In reply to Michael J GruberThis results in output like such as
mjg/attr-filetype 9d2536e [origin/next: ahead 35,
behind 1430, same 46] attr: make attributes depend on file type
all on one line.
--- Documentation/git-branch.txt | 2 ++ builtin/branch.c | 24 ++++++++++++++++-------- remote.c | 12 +++++++++--- remote.h | 2 +- t/t6040-tracking-info.sh | 19 ++++++++++++++++++- wt-status.c | 2 +- 6 files changed, 47 insertions(+), 14 deletions(-)
Documentation/git-branch.txt +2 -0
@@ -117,6 +117,8 @@ OPTIONS Show sha1 and commit subject line for each head, along with the name of the upstream branch (if any). If given twice, print the relationship to the upstream branch (ahead/behind), as well. + If given three times, show ahead/behind/same information like + `git rev-list --count --cherry-mark`. `--list` is implied by all verbosity options. --abbrev=<length>::
builtin/branch.c +16 -8
@@ -361,7 +361,7 @@ static int ref_cmp(const void *r1, const void *r2)static void fill_tracking_info (struct strbuf *stat,const char *branch_name,int verbose) { -int ours, theirs; +int ours, theirs, patchsame =0 ;struct branch *branch =branch_get (branch_name);/* verbose >= 1 */
@@ -370,14 +370,22 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,strbuf_addch (stat,'[' );strbuf_addstr (stat,shorten_unambiguous_ref (branch->merge[0 ]->dst,0 )); -if (verbose >=2 &&stat_tracking_info (branch, &ours, &theirs)) { -strbuf_addstr (stat,": " ); -if (!ours) -strbuf_addf (stat,_ ("behind %d" ), theirs); -else if (!theirs) +if (verbose >=2 &&stat_tracking_info (branch, &ours, &theirs, (verbose >=3 ) ? &patchsame :NULL )) { +strbuf_addstr (stat,_ (": " )); +const char *sep ="" ; +if (ours) {strbuf_addf (stat,_ ("ahead %d" ), ours); -else -strbuf_addf (stat,_ ("ahead %d, behind %d" ), ours, theirs); + sep =_ (", " ); + } +if (theirs) { +strbuf_addstr (stat, sep); +strbuf_addf (stat,_ ("behind %d" ), theirs); + sep =_ (", " ); + } +if (patchsame) { +strbuf_addstr (stat, sep); +strbuf_addf (stat,_ ("same %d" ), patchsame); + } }strbuf_addstr (stat,"] " ); }
remote.c +9 -3
@@ -1510,7 +1510,7 @@ int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1)/* * Return true if there is anything to report, otherwise false. */ -int stat_tracking_info (struct branch *branch,int *num_ours,int *num_theirs) +int stat_tracking_info (struct branch *branch,int *num_ours,int *num_theirs,int *num_patchsame) {unsigned char sha1[20 ];struct commit *ours, *theirs;
@@ -1553,6 +1553,8 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs) rev_argv[rev_argc++] =NULL ; rev_argv[rev_argc++] ="--left-right" ; rev_argv[rev_argc++] = symmetric; +if (num_patchsame) + rev_argv[rev_argc++] ="--cherry-mark" ; rev_argv[rev_argc++] ="--" ; rev_argv[rev_argc] =NULL ;
@@ -1567,11 +1569,15 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)/* ... and count the commits on each side. */ *num_ours =0 ; *num_theirs =0 ; +if (num_patchsame) + *num_patchsame =0 ;while (1 ) {struct commit *c =get_revision (&revs);if (!c)break ; -if (c->object.flags &SYMMETRIC_LEFT ) +if (c->object.flags &PATCHSAME ) + (*num_patchsame)++; +else if (c->object.flags &SYMMETRIC_LEFT ) (*num_ours)++;else (*num_theirs)++;
@@ -1591,7 +1597,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb)int num_ours, num_theirs;const char *base; -if (!stat_tracking_info (branch, &num_ours, &num_theirs)) +if (!stat_tracking_info (branch, &num_ours, &num_theirs,NULL ))return 0 ; base = branch->merge[0 ]->dst;
remote.h +1 -1
@@ -149,7 +149,7 @@ enum match_refs_flags { };/* Reporting of tracking info */ -int stat_tracking_info (struct branch *branch,int *num_ours,int *num_theirs); +int stat_tracking_info (struct branch *branch,int *num_ours,int *num_theirs,int *num_patchsame);int format_tracking_info (struct branch *branch,struct strbuf *sb);struct ref *get_local_heads (void );
t/t6040-tracking-info.sh +18 -1
@@ -24,6 +24,7 @@ test_expect_success setup ' advance d && git checkout -b b2 origin && git reset --hard b1 && + git cherry-pick origin && git checkout -b b3 origin && git reset --hard HEAD^ && git checkout -b b4 origin &&
@@ -53,7 +54,7 @@ test_expect_success 'branch -v' ' cat >expect <<\EOF b1 origin/master: ahead 1, behind 1 -b2 origin/master: ahead 1, behind 1 +b2 origin/master: ahead 2, behind 1 b3 origin/master: behind 1 b4 origin/master: ahead 2 EOF
@@ -67,6 +68,22 @@ test_expect_success 'branch -vv' ' test_i18ncmp expect actual ' +cat >expect <<\EOF +b1 origin/master: ahead 1, behind 1 +b2 origin/master: ahead 1, same 2 +b3 origin/master: behind 1 +b4 origin/master: ahead 2 +EOF + +test_expect_success 'branch -vvv' ' + ( + cd test && + git branch -vvv + ) | + sed -n -e "$script" >actual && + test_i18ncmp expect actual +' + test_expect_success 'checkout' ' ( cd test && git checkout b1
wt-status.c +1 -1
@@ -890,7 +890,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s) branch =branch_get (s->branch +11 );if (s->is_initial)color_fprintf (s->fp, header_color,_ ("Initial commit on " )); -if (!stat_tracking_info (branch, &num_ours, &num_theirs)) { +if (!stat_tracking_info (branch, &num_ours, &num_theirs,NULL )) {color_fprintf_ln (s->fp, branch_color_local,"%s" , branch_name);return ;
Signature · 1 line
1.7.6.845.gc3c05
Quoted 7 lines · Junio C Hamano
[Footnote]
*1* It does not have to be a weekly _posting_ on the list but can be a well-known Wiki page or even a bug tracker. Whatever medium is used for this purpose, there _must_ be a built-in mechanism to expire entries away that are inactive for more than some reasonable limit (say two to three weeks).
Host the project on Google Code for bug tracking? Use rietveld for code reviews (ike codereview.chromium.org and codereview.appspot.com)?
Quoted 11 lines · Thiago Farina
Quoted 7 lines · Junio C Hamano
[Footnote]
*1* It does not have to be a weekly _posting_ on the list but can be a well-known Wiki page or even a bug tracker. Whatever medium is used for this purpose, there _must_ be a built-in mechanism to expire entries away that are inactive for more than some reasonable limit (say two to three weeks).
Host the project on Google Code for bug tracking? Use rietveld for code reviews (ike codereview.chromium.org and codereview.appspot.com)?
If any of the above expires entries by default unless explicit actions are taken, I am personally fine to go with it.
Quoted 16 lines · Michael J Gruber
Jeff King venit, vidit, dixit 04.08.2011 06:06:
Quoted 6 lines · Michael Schubert
Quoted 5 lines
builtin/branch.c +0
-0@@ -297,6 +298,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,if ((kind & ref_list->kinds) ==0 )return 0 ;Quoted 8 lines
builtin/branch.c static int append_ref(const char *refname, const unsigned char *sha1, int flags, · line 303
Quoted 3 lines
builtin/branch.c +3
-0+if (cb->remote &&strncmp (cb->remote, refname,strlen (cb->remote))) +return 0 ; +This isn't right. You are assuming that a remote called "foo" will have all of its branches in refs/remotes/foo. That's true under the default configuration, but technically speaking, the remote tracking branches of "foo" are defined by the right-hand side of foo's fetch refspecs.
Quoted 5 lines
You are 100% right here, but...
Quoted 1 line
So I think you want something more like this:
...the op still might want to filter simply by the remote name.
There's an interesting discussion related to the subject:
http://thread.gmane.org/gmane.comp.version-control.git/178960