From: Junio C Hamano <hidden> Date: 2016-06-15 22:56:44
Miklos Vajna [off-list ref] writes:
When copy&paste goes wrong, and the user e.g. tries to cherry-pick a
blob, the error message used to be:
It is the other way around. When the user tries to cherry-pick a
non-commit we say a correct but nonspecific "expected one commit",
and it does not matter how the user threw a non-commit at us. One
possibility could be copy&paste going wrong.
fatal: BUG: expected exactly one commit from walk
Instead, now it is:
fatal: Can't cherry-pick a blob
I wonder what we would do when "git cherry-pick master: next"
is given. That is not "single commit input" case and not covered by
this patch, but perhaps something we may want to diagnose?
In other words, perhaps we would want to inspect pending objects
before running prepare_revision_walk and make sure everybody is
commit-ish or something?
@@ -1082,8 +1082,15 @@ int sequencer_pick_revisions(struct replay_opts *opts)if(prepare_revision_walk(opts->revs))die(_("revision walk setup failed"));cmit=get_revision(opts->revs);-if(!cmit||get_revision(opts->revs))+if(!cmit||get_revision(opts->revs)){+unsignedcharsha1[20];+if(!get_sha1(opts->revs->cmdline.rev->name,sha1)){+enumobject_typetype=sha1_object_info(sha1,NULL);+if(type>0&&type!=OBJ_COMMIT)+die(_("Can't cherry-pick a %s"),typename(type));+}die("BUG: expected exactly one commit from walk");+}returnsingle_pick(cmit,opts);}
When a single argument was a non-commit, the error message used to be:
fatal: BUG: expected exactly one commit from walk
For multiple arguments, when none of the arguments was a commit, the error was:
fatal: empty commit set passed
Finally, when some of the arguments were non-commits, we ignored those
arguments. Instead, now make sure all arguments are commits, and for
the first non-commit, error out with:
fatal: <name>: Can't cherry-pick a <type>
Signed-off-by: Miklos Vajna <redacted>
---
On Mon, Apr 08, 2013 at 09:56:55AM -0700, Junio C Hamano [off-list ref] wrote:
In other words, perhaps we would want to inspect pending objects
before running prepare_revision_walk and make sure everybody is
commit-ish or something?
Sure, that makes sense to me.
sequencer.c | 13 +++++++++++++
t/t3508-cherry-pick-many-commits.sh | 6 ++++++
2 files changed, 19 insertions(+)
@@ -55,6 +55,12 @@ one two"'+test_expect_success'cherry-pick three one two: fails''+gitcheckout-fmaster&&+gitreset--hardfirst&&+test_must_failgitcherry-pickthreeonetwo:+'+ test_expect_success'output to keep user entertained during multi-pick''cat<<-\EOF>expected&&[masterOBJID]second
When a single argument was a non-commit, the error message used to be:
fatal: BUG: expected exactly one commit from walk
For multiple arguments, when none of the arguments was a commit, the error was:
fatal: empty commit set passed
Finally, when some of the arguments were non-commits, we ignored those
arguments. Instead, now make sure all arguments are commits, and for
the first non-commit, error out with:
fatal: <name>: Can't cherry-pick a <type>
@@ -55,6 +55,12 @@ one two"'+test_expect_success'cherry-pick three one two: fails''+gitcheckout-fmaster&&+gitreset--hardfirst&&+test_must_failgitcherry-pickthreeonetwo:+'
So you're testing just the third case (where commit objects are mixed
with non-commit objects), which is arguably a bug. Okay.
On Thu, Apr 11, 2013 at 03:52:44PM +0530, Ramkumar Ramachandra [off-list ref] wrote:
quoted
+ for (i = 0; i < opts->revs->pending.nr; i++) {
+ unsigned char sha1[20];
+ const char *name = opts->revs->pending.objects[i].name;
+
+ if (!get_sha1(name, sha1)) {
+ enum object_type type = sha1_object_info(sha1, NULL);
+
+ if (type > 0 && type != OBJ_COMMIT)
+ die(_("%s: can't cherry-pick a %s"), name, typename(type));
+ }
else? What happens if get_sha1() fails?
I guess that is a should-not-happen category. parse_args() calls
setup_revisions(), and that will already die() if the argument is not a
valid object at all.
@@ -55,6 +55,12 @@ one two"'+test_expect_success'cherry-pick three one two: fails''+gitcheckout-fmaster&&+gitreset--hardfirst&&+test_must_failgitcherry-pickthreeonetwo:+'
So you're testing just the third case (where commit objects are mixed
with non-commit objects), which is arguably a bug. Okay.
Yes. If you would want, I could of course add test cases for two other
cases when we already errored out and now the error message is just
changed, but I don't think duplicating the error message strings from
the code to the testsuite is really wanted. :-)
I guess that is a should-not-happen category. parse_args() calls
setup_revisions(), and that will already die() if the argument is not a
valid object at all.
Then why do you have an if() guarding the code? In my opinion, you
should have an else-clause that die()s with an appropriate message.
Yes. If you would want, I could of course add test cases for two other
cases when we already errored out and now the error message is just
changed, but I don't think duplicating the error message strings from
the code to the testsuite is really wanted. :-)
Nope, I'd never suggest that: this is fine. What I meant is: you
should clarify that you're fixing a bug and adding a test to guard it,
in the commit message.
When a single argument was a non-commit, the error message used to be:
fatal: BUG: expected exactly one commit from walk
For multiple arguments, when none of the arguments was a commit, the error was:
fatal: empty commit set passed
Finally, when some of the arguments were non-commits, we ignored those
arguments. Fix this bug and make sure all arguments are commits, and
for the first non-commit, error out with:
fatal: <name>: Can't cherry-pick a <type>
Signed-off-by: Miklos Vajna <redacted>
---
On Thu, Apr 11, 2013 at 05:12:06PM +0530, Ramkumar Ramachandra [off-list ref] wrote:
Then why do you have an if() guarding the code? In my opinion, you
should have an else-clause that die()s with an appropriate message.
And you were right -- I actually forgot about --stdin, where the
else-clause is hit. Added that for now, excluding --stdin.
Nope, I'd never suggest that: this is fine. What I meant is: you
should clarify that you're fixing a bug and adding a test to guard it,
in the commit message.
@@ -1047,6 +1047,7 @@ int sequencer_pick_revisions(struct replay_opts *opts){structcommit_list*todo_list=NULL;unsignedcharsha1[20];+inti;if(opts->subcommand==REPLAY_NONE)assert(opts->revs);
@@ -1067,6 +1068,23 @@ int sequencer_pick_revisions(struct replay_opts *opts)if(opts->subcommand==REPLAY_CONTINUE)returnsequencer_continue(opts);+for(i=0;i<opts->revs->pending.nr;i++){+unsignedcharsha1[20];+constchar*name=opts->revs->pending.objects[i].name;++/* This happens when using --stdin. */+if(!strlen(name))+continue;++if(!get_sha1(name,sha1)){+enumobject_typetype=sha1_object_info(sha1,NULL);++if(type>0&&type!=OBJ_COMMIT)+die(_("%s: can't cherry-pick a %s"),name,typename(type));+}else+die(_("%s: bad revision"),name);+}+/**Ifwewerecalledas"git cherry-pick <commit>",just*cherry-pick/revertit,setCHERRY_PICK_HEAD/
@@ -55,6 +55,12 @@ one two"'+test_expect_success'cherry-pick three one two: fails''+gitcheckout-fmaster&&+gitreset--hardfirst&&+test_must_failgitcherry-pickthreeonetwo:+'+ test_expect_success'output to keep user entertained during multi-pick''cat<<-\EOF>expected&&[masterOBJID]second