add --abbrev to 'git cherry'
PATCH v2 1/1 add --abbrev to 'git cherry'
Abbreviating ids makes 'git cherry -v' more useful, since you can see more of the commit message summary:
git cherry -v --abbrev | less -S
---
An earlier version of this patch added multiple different flags to 'git cherry', but --abbrev (was -a) is really the important one. Thanks to Jakub Narebski and Michael J Gruber for comments on the first patch.
Documentation/git-cherry.txt | 5 ++++- builtin-log.c | 24 +++++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-)
Documentation/git-cherry.txt +4 -1
@@ -7,7 +7,7 @@ git-cherry - Find commits not merged upstream SYNOPSIS -------- -'git cherry' [-v] [<upstream> [<head> [<limit>]]] +'git cherry' [-v] [--abbrev[=<n>]] [<upstream> [<head> [<limit>]]] DESCRIPTION -----------
@@ -49,6 +49,9 @@ OPTIONS -v:: Verbose. +--abbrev[=<n>]:: + Abbreviate commit ids to the given number of characters + <upstream>:: Upstream branch to compare against. Defaults to the first tracked remote branch, if available.
builtin-log.c +19 -5
@@ -1130,7 +1130,7 @@ static int add_pending_commit(const char *arg, struct rev_info *revs, int flags) }static const char cherry_usage[] = -"git cherry [-v] [<upstream> [<head> [<limit>]]]" ; +"git cherry [-v] [--abbrev[=<n>]] [<upstream> [<head> [<limit>]]]" ;int cmd_cherry (int argc,const char **argv,const char *prefix) {struct rev_info revs;
@@ -1142,9 +1142,23 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)const char *head ="HEAD" ;const char *limit =NULL ;int verbose =0 ; +int abbrev =40 ; + +while (argc >1 && argv[1 ][0 ] =='-' ) { +if (!strcmp (argv[1 ],"-v" )) { + verbose =1 ; + }else if (!strcmp (argv[1 ],"--abbrev" )) { + abbrev =DEFAULT_ABBREV ; + }else if (!prefixcmp (argv[1 ],"--abbrev=" )) { + abbrev =strtol (argv[1 ] +9 ,NULL ,10 ); +if (abbrev <MINIMUM_ABBREV ) + abbrev =MINIMUM_ABBREV ; +else if (abbrev >40 ) + abbrev =40 ; + }else { +die ("unrecognized argument: %s" , argv[1 ]); + } -if (argc >1 && !strcmp (argv[1 ],"-v" )) { - verbose =1 ; argc--; argv++; }
@@ -1218,12 +1232,12 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)struct strbuf buf =STRBUF_INIT ;pretty_print_commit (CMIT_FMT_ONELINE , commit, &buf,0 ,NULL ,NULL ,0 ,0 ); -printf ("%c %s %s\n" , sign, +printf ("%c %.*s %s\n" , sign, abbrev,sha1_to_hex (commit->object.sha1), buf.buf);strbuf_release (&buf); }else { -printf ("%c %s\n" , sign, +printf ("%c %.*s\n" , sign, abbrev,sha1_to_hex (commit->object.sha1)); }
Signature · 1 line
1.5.4.3
Jeff Epler, 30.05.2009:
Quoted 3 lines
Documentation/git-cherry.txt | 5 ++++- builtin-log.c | 24 +++++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-)
You could also add --abbrev= to the bash completion.
Documentation/git-cherry.txt OPTIONS · line 53
Quoted 10 lines
Documentation/git-cherry.txt +2
-0@@ -49,6 +49,9 @@ OPTIONS -v:: Verbose. +--abbrev[=<n>]:: + Abbreviate commit ids to the given number of characters
The full stop is missing :)
And you could add "The default value is 7." as in the git-branch docs. Or even copy the whole description from there for consistency, it also mentions that this sets the minimum length, the displayed SHA1 may be longer, but more about this below.
Quoted 8 lines
builtin-log.c +0
-0@@ -1218,12 +1232,12 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)struct strbuf buf =STRBUF_INIT ;pretty_print_commit (CMIT_FMT_ONELINE , commit, &buf,0 ,NULL ,NULL ,0 ,0 );
builtin-log.c int cmd_cherry(int argc, const char **argv, const char *prefix) · line 1242
Quoted 10 lines
builtin-log.c +2
-2-printf ("%c %s %s\n" , sign, +printf ("%c %.*s %s\n" , sign, abbrev,sha1_to_hex (commit->object.sha1), buf.buf);strbuf_release (&buf); }else { -printf ("%c %s\n" , sign, +printf ("%c %.*s\n" , sign, abbrev,sha1_to_hex (commit->object.sha1)); }
There is no test for unique ids. "git cherry --abbrev=4" always prints 4 chars per SHA1, so "git show" on these SHA1s mostly gives "error: short SHA1 xxxx is ambiguous." in git.git.
find_unique_abbrev() will help.
Markus
PATCH v3 1/1 add --abbrev to 'git cherry'
Abbreviating ids makes 'git cherry -v' more useful, since you can see more of the commit message summary:
git cherry -v --abbrev | less -S
---
Compared to the last patch, this adds to the bash completion, improves doc consistency, and uses find_unique_abbrev to shorten commit ids. Thanks to Markus Heidelberg for feedback.
Documentation/git-cherry.txt | 6 +++++- builtin-log.c | 24 +++++++++++++++++++----- contrib/completion/git-completion.bash | 10 +++++++++- 3 files changed, 33 insertions(+), 7 deletions(-)
Documentation/git-cherry.txt +5 -1
@@ -7,7 +7,7 @@ git-cherry - Find commits not merged upstream SYNOPSIS -------- -'git cherry' [-v] [<upstream> [<head> [<limit>]]] +'git cherry' [-v] [--abbrev[=<n>]] [<upstream> [<head> [<limit>]]] DESCRIPTION -----------
@@ -49,6 +49,10 @@ OPTIONS -v:: Verbose. +--abbrev[=<n>]:: + Alter the sha1's minimum display length in the output listing. + The default value is 7. + <upstream>:: Upstream branch to compare against. Defaults to the first tracked remote branch, if available.
builtin-log.c +19 -5
@@ -1130,7 +1130,7 @@ static int add_pending_commit(const char *arg, struct rev_info *revs, int flags) }static const char cherry_usage[] = -"git cherry [-v] [<upstream> [<head> [<limit>]]]" ; +"git cherry [-v] [--abbrev[=<n>]] [<upstream> [<head> [<limit>]]]" ;int cmd_cherry (int argc,const char **argv,const char *prefix) {struct rev_info revs;
@@ -1142,9 +1142,23 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)const char *head ="HEAD" ;const char *limit =NULL ;int verbose =0 ; +int abbrev =40 ; + +while (argc >1 && argv[1 ][0 ] =='-' ) { +if (!strcmp (argv[1 ],"-v" )) { + verbose =1 ; + }else if (!strcmp (argv[1 ],"--abbrev" )) { + abbrev =DEFAULT_ABBREV ; + }else if (!prefixcmp (argv[1 ],"--abbrev=" )) { + abbrev =strtol (argv[1 ] +9 ,NULL ,10 ); +if (abbrev <MINIMUM_ABBREV ) + abbrev =MINIMUM_ABBREV ; +else if (abbrev >40 ) + abbrev =40 ; + }else { +die ("unrecognized argument: %s" , argv[1 ]); + } -if (argc >1 && !strcmp (argv[1 ],"-v" )) { - verbose =1 ; argc--; argv++; }
@@ -1219,12 +1233,12 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)pretty_print_commit (CMIT_FMT_ONELINE , commit, &buf,0 ,NULL ,NULL ,0 ,0 );printf ("%c %s %s\n" , sign, -sha1_to_hex (commit->object.sha1), buf.buf); +find_unique_abbrev (commit->object.sha1, abbrev), buf.buf);strbuf_release (&buf); }else {printf ("%c %s\n" , sign, -sha1_to_hex (commit->object.sha1)); +find_unique_abbrev (commit->object.sha1, abbrev)); } list = list->next;
contrib/completion/git-completion.bash +9 -1
@@ -804,7 +804,15 @@ _git_checkout () _git_cherry () { - __gitcomp "$(__git_refs)" + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + -*) + __gitcomp "-v --abbrev --abbrev=" + ;; + *) + __gitcomp "$(__git_refs)" + ;; + esac } _git_cherry_pick ()
Signature · 1 line
1.5.4.3
Quoted 11 lines · Jeff Epler
builtin-log.c +7
-0@@ -1142,9 +1142,23 @@ int cmd_cherry(int argc, const char **argv, const char *prefix) const char *head = "HEAD"; const char *limit = NULL; int verbose = 0; + int abbrev = 40; + + while(argc > 1 && argv[1][0] == '-') { + if (!strcmp(argv[1], "-v")) { + verbose = 1; + } else if(!strcmp(argv[1], "--abbrev")) { + abbrev = DEFAULT_ABBREV;
builtin-log.c int cmd_cherry(int argc, const char **argv, const char *prefix) · line 1161
Quoted 10 lines
builtin-log.c +9
-0+ } else if(!prefixcmp(argv[1], "--abbrev=")) { + abbrev = strtol(argv[1] + 9, NULL, 10); + if(abbrev < MINIMUM_ABBREV) + abbrev = MINIMUM_ABBREV; + else if(abbrev > 40) + abbrev = 40; + } else { + die("unrecognized argument: %s", argv[1]); + }
You might want to look at using the parse options API. It has options for verbose and abbrev builtin, so you don't have to do any extra work. Plus you get a nice usage message for free. See Documentation/technical/api-parse-options.txt for more info.
Quoted 8 lines
contrib/completion/git-completion.bash +0
-0@@ -804,7 +804,15 @@ _git_checkout () _git_cherry () {
contrib/completion/git-completion.bash _git_checkout () · line 815
Quoted 10 lines
contrib/completion/git-completion.bash +9
-1- __gitcomp "$(__git_refs)" + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + -*) + __gitcomp "-v --abbrev --abbrev=" + ;; + *) + __gitcomp "$(__git_refs)" + ;; + esac
Completion doesn't include short options (-v). This also means that --* is used instead of -*
Finally, you'll want to Cc Shawn (Shawn O. Pearce
<[email protected]>) on bash completion.
Quoted 3 lines · Stephen Boyd
You might want to look at using the parse options API. It has options for verbose and abbrev builtin, so you don't have to do any extra work....
Why do people even think a change like this to a _plumbing_ command is desirable?
Admittedly, there already is "verbose" option that adds redundant information to the output of this particular plumbing, which might arguably be equally wrong as what this patch does, but I think it is excusable. At least it lets the Porcelain script that uses the command avoid calling 'git cat-file commit' to find out the title of the commit.
But --abbrev does not even add any information. If implemented correctly (which earlier iteration did not even do), it may not lose information by choping the output too short to make it ambiguous, but as others pointed out about using grep in the calling Porcelain to filter (or more likely, sift the lines into "+" and "-" bins) to shoot down -d/-D options, I do not see the point of adding --abbrev to this plumbing command very much.
Junio C Hamano, 31.05.2009:
Quoted 2 lines
Why do people even think a change like this to a _plumbing_ command is desirable?
git-cherry is plumbing? In git(1) it is listed as porcelain. And the plumbings show-ref, ls-files and ls-tree support --abbrev.
Markus
Quoted 5 lines · Markus Heidelberg
Junio C Hamano, 31.05.2009:
Quoted 2 lines
Why do people even think a change like this to a _plumbing_ command is desirable?
git-cherry is plumbing? In git(1) it is listed as porcelain.
I'd say it is a miscategorization, but I do not care too deeply, as I never use it myself (even though my Porcelain scripts would).
Quoted 3 lines · Junio C Hamano
Stopping here would be a good idea if "log --left-right --cherry-pick A...B" (perhaps with a custom --pretty option) covers what you originally wanted to do.
Yes, I now see that 'git log' can pretty much do what I want. Having learned of 'git cherry', it didn't cross my mind that 'git log' was set up to do all 'git cherry' did and more.
Quoted 4 lines
But if the reason why you wanted --abbrev was because you wanted to use it in your scripted Porcelain, and if the reason why you have your scripted Porcelain is because you wanted to add some _other_ information that "log" does not give you easily, perhaps it would be a good idea to share _that_.
No, this is all about displaying directly to the user (me) in a pager, specifically about getting as much of the change summary in the first 80 columns as possible.
Jeff
Quoted 14 lines · Junio C Hamano
Quoted 3 lines · Stephen Boyd
You might want to look at using the parse options API. It has options for verbose and abbrev builtin, so you don't have to do any extra work....
Why do people even think a change like this to a _plumbing_ command is desirable?
Admittedly, there already is "verbose" option that adds redundant information to the output of this particular plumbing, which might arguably be equally wrong as what this patch does, but I think it is excusable. At least it lets the Porcelain script that uses the command avoid calling 'git cat-file commit' to find out the title of the commit.
Quoted 6 lines
But --abbrev does not even add any information. If implemented correctly (which earlier iteration did not even do), it may not lose information by choping the output too short to make it ambiguous, but as others pointed out about using grep in the calling Porcelain to filter (or more likely, sift the lines into "+" and "-" bins) to shoot down -d/-D options, I do not see the point of adding --abbrev to this plumbing command very much.
I was tempted to say the same thing, but I decided to leave it up to the maintainer ;-) Maybe if there was a compelling use case it would make more sense?
Or, would it make more sense to just use git-log? Right now you can do git log --oneline --cherry-pick <head>..<upstream> and get close. Maybe we can add a "--cherry" option to git-log which will act like git-cherry by finding unmerged commits?