threads / discuss / 42477

error: Can't cherry-pick into empty head

Subject: error: Can't cherry-pick into empty head

## tl;dr

7 messages between May 28, 2016 and Jun 7, 2016.

replies: 6people: 4as markdown or json

Fabrizio Cucci· May 28, 2016, 17:54 UTC · lore
Hello everyone,
I'm trying to understand why I'm getting the error as per subject.

The scenario is the following: I'm on the master branch (which contains several commits) and I would like to create a new empty branch (let's call it new-orphan) and cherry-pick only the commits related to a specific folder (let's call it my-folder) from the master branch.

So, I tried the following command sequence:
  master $ git checkout --orphan new-orphan
  new-orphan $ git rm --cached -r .
  new-orphan $ git clean -df
After confirming that I'm in a clean state (with "$ git status") I tried:
  new-orphan $ git rev-list --reverse master -- my-folder/ | git
cherry-pick --stdin

as suggested https://git-scm.com/docs/git-cherry-pick, but what I get is "error: Can't cherry-pick into empty head".

What I don't really understand is:
1) if I cherry-pick a single commit instead of multiple commits,
everything works fine:
  new-orphan $ git cherry-pick <some-commit-id>
2) if I commit something before trying the above command, everything works fine:
  new-orphan $ touch README
  new-orphan $ git add README
  new-orphan $ git commit -m "added README"
  new-orphan $ git rev-list --reverse master -- my-folder/ | git
cherry-pick --stdin
Can someone please help me understand this?

Thanks, Fabrizio

Michael J Gruber· Jun 6, 2016, 13:21 UTC · re: Fabrizio Cucci · lore

Re: error: Can't cherry-pick into empty head

Fabrizio Cucci venit, vidit, dixit 28.05.2016 19:54:
Show 40 quoted lines
> Hello everyone,
> 
> I'm trying to understand why I'm getting the error as per subject.
> 
> The scenario is the following: I'm on the master branch (which
> contains several commits) and I would like to create a new empty
> branch (let's call it new-orphan) and cherry-pick only the commits
> related to a specific folder (let's call it my-folder) from the master
> branch.
> 
> So, I tried the following command sequence:
> 
>   master $ git checkout --orphan new-orphan
>   new-orphan $ git rm --cached -r .
>   new-orphan $ git clean -df
> 
> After confirming that I'm in a clean state (with "$ git status") I tried:
> 
>   new-orphan $ git rev-list --reverse master -- my-folder/ | git
> cherry-pick --stdin
> 
> as suggested https://git-scm.com/docs/git-cherry-pick, but what I get
> is "error: Can't cherry-pick into empty head".
> 
> What I don't really understand is:
> 
> 1) if I cherry-pick a single commit instead of multiple commits,
> everything works fine:
> 
>   new-orphan $ git cherry-pick <some-commit-id>
> 
> 2) if I commit something before trying the above command, everything works fine:
> 
>   new-orphan $ touch README
>   new-orphan $ git add README
>   new-orphan $ git commit -m "added README"
>   new-orphan $ git rev-list --reverse master -- my-folder/ | git
> cherry-pick --stdin
> 
> Can someone please help me understand this?

The implementation for the single commit and multiple commit cases is different (so that you can do a single cherry-pick from with a running cherry-pick sequence). As a side effect, the single commit pick does not care about an empty head.

I'll follow up with a patch which changes that.
Michael
Michael J Gruber· Jun 6, 2016, 13:23 UTC · re: Michael J Gruber · lore

[PATCH] cherry-pick: allow to pick to unborn branches

Currently, cherry-pick allows tp pick single commits to an empty HEAD but not multiple commits.

Allow the multiple commit case, too.
Reported-by: Fabrizio Cucci <fabrizio.cucci@gmail.com>
Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
 sequencer.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 4687ad4..c6362d6 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -888,6 +888,10 @@ static int sequencer_rollback(struct replay_opts *opts)
 			git_path_head_file());
 		goto fail;
 	}
+	if (is_null_sha1(sha1)) {
+		error(_("cannot abort from a branch yet to be born"));
+		goto fail;
+	}
 	if (reset_for_rollback(sha1))
 		goto fail;
 	remove_sequencer_state();
@@ -1086,11 +1090,8 @@ int sequencer_pick_revisions(struct replay_opts *opts)
 	walk_revs_populate_todo(&todo_list, opts);
 	if (create_seq_dir() < 0)
 		return -1;
-	if (get_sha1("HEAD", sha1)) {
-		if (opts->action == REPLAY_REVERT)
-			return error(_("Can't revert as initial commit"));
-		return error(_("Can't cherry-pick into empty head"));
-	}
+	if (get_sha1("HEAD", sha1) && (opts->action == REPLAY_REVERT))
+		return error(_("Can't revert as initial commit"));
 	save_head(sha1_to_hex(sha1));
 	save_opts(opts);
 	return pick_commits(todo_list, opts);
-- 
2.9.0.rc1.371.ge0ee742
Junio C Hamano· Jun 6, 2016, 20:06 UTC · re: Michael J Gruber · lore

Re: [PATCH] cherry-pick: allow to pick to unborn branches

Michael J Gruber <git@drmicha.warpmail.net> writes:
Show 10 quoted lines
> Currently, cherry-pick allows tp pick single commits to an empty HEAD
> but not multiple commits.
>
> Allow the multiple commit case, too.
>
> Reported-by: Fabrizio Cucci <fabrizio.cucci@gmail.com>
> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
> ---
>  sequencer.c | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)

Thanks; we'd probably want a few tests in somewhere near 3503 or 3505.

Show 12 quoted lines
> diff --git a/sequencer.c b/sequencer.c
> index 4687ad4..c6362d6 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -888,6 +888,10 @@ static int sequencer_rollback(struct replay_opts *opts)
>  			git_path_head_file());
>  		goto fail;
>  	}
> +	if (is_null_sha1(sha1)) {
> +		error(_("cannot abort from a branch yet to be born"));
> +		goto fail;
> +	}

Is this error-fail desirable? How do we get here? Did a user start a cherry-pick on an unborn branch and then told us to abort that? Shouldn't we be taking the user back to the "orphan" state if that is the case?

Show 14 quoted lines
>  	if (reset_for_rollback(sha1))
>  		goto fail;
>  	remove_sequencer_state();
> @@ -1086,11 +1090,8 @@ int sequencer_pick_revisions(struct replay_opts *opts)
>  	walk_revs_populate_todo(&todo_list, opts);
>  	if (create_seq_dir() < 0)
>  		return -1;
> -	if (get_sha1("HEAD", sha1)) {
> -		if (opts->action == REPLAY_REVERT)
> -			return error(_("Can't revert as initial commit"));
> -		return error(_("Can't cherry-pick into empty head"));
> -	}
> +	if (get_sha1("HEAD", sha1) && (opts->action == REPLAY_REVERT))
> +		return error(_("Can't revert as initial commit"));

Not a new issue, but I cannot quite fathom what this error message wants to say. "Can't revert an initial commit"?

>  	save_head(sha1_to_hex(sha1));
>  	save_opts(opts);
>  	return pick_commits(todo_list, opts);
Michael J Gruber· Jun 7, 2016, 06:37 UTC · re: Junio C Hamano · lore

Re: [PATCH] cherry-pick: allow to pick to unborn branches

Junio C Hamano venit, vidit, dixit 06.06.2016 22:06:
Show 15 quoted lines
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
>> Currently, cherry-pick allows tp pick single commits to an empty HEAD
>> but not multiple commits.
>>
>> Allow the multiple commit case, too.
>>
>> Reported-by: Fabrizio Cucci <fabrizio.cucci@gmail.com>
>> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
>> ---
>>  sequencer.c | 11 ++++++-----
>>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> Thanks; we'd probably want a few tests in somewhere near 3503 or
> 3505.
I'll try my best.
Show 17 quoted lines
>> diff --git a/sequencer.c b/sequencer.c
>> index 4687ad4..c6362d6 100644
>> --- a/sequencer.c
>> +++ b/sequencer.c
>> @@ -888,6 +888,10 @@ static int sequencer_rollback(struct replay_opts *opts)
>>  			git_path_head_file());
>>  		goto fail;
>>  	}
>> +	if (is_null_sha1(sha1)) {
>> +		error(_("cannot abort from a branch yet to be born"));
>> +		goto fail;
>> +	}
> 
> Is this error-fail desirable?  How do we get here?  Did a user start
> a cherry-pick on an unborn branch and then told us to abort that?
> Shouldn't we be taking the user back to the "orphan" state if that
> is the case?

Here and below, I'm mimicking/copying the behavior that we have right now already. I asked myself the same question - rolling back to orphan state shouldn't be that hard after all. But that would be a change in behavior that - if considered a fix/improvement - would be orthogonal to the multi-pick fix.

Show 17 quoted lines
>>  	if (reset_for_rollback(sha1))
>>  		goto fail;
>>  	remove_sequencer_state();
>> @@ -1086,11 +1090,8 @@ int sequencer_pick_revisions(struct replay_opts *opts)
>>  	walk_revs_populate_todo(&todo_list, opts);
>>  	if (create_seq_dir() < 0)
>>  		return -1;
>> -	if (get_sha1("HEAD", sha1)) {
>> -		if (opts->action == REPLAY_REVERT)
>> -			return error(_("Can't revert as initial commit"));
>> -		return error(_("Can't cherry-pick into empty head"));
>> -	}
>> +	if (get_sha1("HEAD", sha1) && (opts->action == REPLAY_REVERT))
>> +		return error(_("Can't revert as initial commit"));
> 
> Not a new issue, but I cannot quite fathom what this error message
> wants to say.  "Can't revert an initial commit"?

Cannot create a "revert commit" as the initial commit on a yet unborn branch. Maybe "nothing to revert" would be clearer, but then another user might ask: If I say "git revert deabeef" and there is a commit "deadbeef" then why is there "nothing to revert"?

Applying the reverse of a patch to an empty tree should result in an empty tree, and creating a commit with that empty tree as "This reverts commit deadbeef" is what we are refusing here, unless I'm confused.

>>  	save_head(sha1_to_hex(sha1));
>>  	save_opts(opts);
>>  	return pick_commits(todo_list, opts);
> 
Junio C Hamano· Jun 7, 2016, 07:03 UTC · re: Michael J Gruber · lore

Re: [PATCH] cherry-pick: allow to pick to unborn branches

Michael J Gruber <git@drmicha.warpmail.net> writes:
Show 5 quoted lines
> Here and below, I'm mimicking/copying the behavior that we have right
> now already. I asked myself the same question - rolling back to orphan
> state shouldn't be that hard after all. But that would be a change in
> behavior that - if considered a fix/improvement - would be orthogonal to
> the multi-pick fix.
Hmph, OK.
Show 23 quoted lines
>>> @@ -1086,11 +1090,8 @@ int sequencer_pick_revisions(struct replay_opts *opts)
>>>  	walk_revs_populate_todo(&todo_list, opts);
>>>  	if (create_seq_dir() < 0)
>>>  		return -1;
>>> -	if (get_sha1("HEAD", sha1)) {
>>> -		if (opts->action == REPLAY_REVERT)
>>> -			return error(_("Can't revert as initial commit"));
>>> -		return error(_("Can't cherry-pick into empty head"));
>>> -	}
>>> +	if (get_sha1("HEAD", sha1) && (opts->action == REPLAY_REVERT))
>>> +		return error(_("Can't revert as initial commit"));
>> 
>> Not a new issue, but I cannot quite fathom what this error message
>> wants to say.  "Can't revert an initial commit"?
>
> Cannot create a "revert commit" as the initial commit on a yet unborn
> branch. Maybe "nothing to revert" would be clearer, but then another
> user might ask: If I say "git revert deabeef" and there is a commit
> "deadbeef" then why is there "nothing to revert"?
>
> Applying the reverse of a patch to an empty tree should result in an
> empty tree, and creating a commit with that empty tree as "This reverts
> commit deadbeef" is what we are refusing here, unless I'm confused.

OK, so the message wants to say "a revert cannot be recorded as initial commit" (because the original change has to be one that results in an empty tree to be able to sanely be reversed its effect on top of an empty tree)? That interpretation is understandable.

But that still sounds like a fishy logic.

A root commit should be cherry-pickable as it is a change to whatever state from an empty tree, and we do allow it. The same reasoning suggests that if you find a change that makes the tree empty, such a change should be revert-able on top of an empty tree.

In fact, we do allow cherry-picking a non-root commit onto an empty tree, as long as the changes are all about creating new files. So perhaps a change that only removes files should be revert-able on top of an empty tree?

In any case, this topic is not about fixing that semantics of the revert and it is a tangent. I'll just leave the usual "low hanging fruit" mark so that people can list-archive-search for that string to find it as a possible mini-project to allow reverting such a change on top of an empty tree.

Thanks.

← back to recent threads