diff mbox series

[RFC] sequencer: allow metadata to be saved if using cherry-pick --no-commit

Message ID 20201021062430.2029566-1-eantoranz@gmail.com (mailing list archive)
State New, archived
Headers show
Series [RFC] sequencer: allow metadata to be saved if using cherry-pick --no-commit | expand

Commit Message

Edmundo Carmona Antoranz Oct. 21, 2020, 6:24 a.m. UTC
Currently, if 'git cherry-pick --no-commit' is run _and the cherry-pick
operation is successful_, the metadata from the original revision is lost and
to git it's like a cherry-pick operation is not taking place at all. Hence,
we can't wrap up the cherry-pick operation by calling
'git cherry-pick --continue'.

With this patch, we allow sequencer to save the metadata from the original
cherry-pick operation so that 'git cherry-pick --continue' can be called.

Signed-off-by: Edmundo Carmona Antoranz <eantoranz@gmail.com>
---
 sequencer.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Comments

Edmundo Carmona Antoranz Oct. 21, 2020, 6:31 a.m. UTC | #1
On Wed, Oct 21, 2020 at 12:24 AM Edmundo Carmona Antoranz
<eantoranz@gmail.com> wrote:
>
>
> With this patch, we allow sequencer to save the metadata from the original
> cherry-pick operation so that 'git cherry-pick --continue' can be called.
>
I would expect 'git cherry-pick --no-commit' to save the metadata from
the revision cherry-picked if the operation is successful so to allow
running 'git cherry-pick --continue' afterwards, however that's not
the case. I was wondering if this is done on purpose. The patch in the
RFC is not in any way my final proposal (or even a real proposal) but
just a little first step so that I can gather information so that I
can adjust the code accordingly from all the feedback... _if_ an
adjustment is needed, of course. I don't know how --no-commit would
have to play out if multiple revisions are asked to be processed by
sequencer, for example.
Taylor Blau Oct. 21, 2020, 4:12 p.m. UTC | #2
Hi Edmundo,

On Wed, Oct 21, 2020 at 12:24:30AM -0600, Edmundo Carmona Antoranz wrote:
> Currently, if 'git cherry-pick --no-commit' is run _and the cherry-pick
> operation is successful_, the metadata from the original revision is lost and
> to git it's like a cherry-pick operation is not taking place at all. Hence,
> we can't wrap up the cherry-pick operation by calling
> 'git cherry-pick --continue'.

Interesting.

> diff --git a/sequencer.c b/sequencer.c
> index 00acb12496..c1ccbe0faf 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -2022,9 +2022,8 @@ static int do_pick_commit(struct repository *r,
>  	 * However, if the merge did not even start, then we don't want to
>  	 * write it at all.
>  	 */
> -	if ((command == TODO_PICK || command == TODO_REWORD ||
> -	     command == TODO_EDIT) && !opts->no_commit &&
> -	    (res == 0 || res == 1) &&
> +	if ((command == TODO_PICK || command == TODO_REWORD || command == TODO_EDIT)
> +		&& ((res == 0 && opts->no_commit) || (res == 1 && !opts->no_commit)) &&
>  	    update_ref(NULL, "CHERRY_PICK_HEAD", &commit->object.oid, NULL,
>  		       REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR))
>  		res = -1;
> --
> 2.28.0

Hmm. I'm a little confused after reading your patch below. Why does (res
== 0) change to (res == 0 && opts->no_commit)? Wouldn't we still want to
update our CHERRY_PICK_HEAD even if "res == 0 && !opts->no_commit"?

Even still, this patch as it is seems to fail a number of tests. You can
run the tests yourself by running "make && make test", and there is more
information about that in t/README.

Thanks,
Taylor
Edmundo Carmona Antoranz Oct. 21, 2020, 6:04 p.m. UTC | #3
I think my previous reply was rejected so let me try again (I
apologize if you get a duplicate):

On Wed, Oct 21, 2020 at 10:12 AM Taylor Blau <me@ttaylorr.com> wrote:
> Hmm. I'm a little confused after reading your patch below. Why does (res
> == 0) change to (res == 0 && opts->no_commit)? Wouldn't we still want to
> update our CHERRY_PICK_HEAD even if "res == 0 && !opts->no_commit"?

My _guess_ (haven't sat down to study the code that much) is that if
"res == 0 && !opts->no_commit", then commit will wrap up in a normal
fashion and then there's actually no need for this file to be updated.
You can see that the same thing is done when reverting (preexisting
code), a few lines after where the patch is applied (if I remember
correctly).

>
> Even still, this patch as it is seems to fail a number of tests. You can
> run the tests yourself by running "make && make test", and there is more
> information about that in t/README.

Will actually look at that just so that I can have a better idea of
what the _current_ behavior is expected from using the flag. Looking
forward to more comments

>
> Thanks,
> Taylor

Thank you!
Junio C Hamano Oct. 21, 2020, 7:46 p.m. UTC | #4
Edmundo Carmona Antoranz <eantoranz@gmail.com> writes:

> Currently, if 'git cherry-pick --no-commit' is run _and the cherry-pick
> operation is successful_, the metadata from the original revision is lost and
> to git it's like a cherry-pick operation is not taking place at all. Hence,
> we can't wrap up the cherry-pick operation by calling
> 'git cherry-pick --continue'.

This cuts both ways, though.

I often use the "--no-commit" form of the command as a better
version of the 'git show $that_commit | git apply --index' pipeline,
and what I'll do starting from the working tree that I prepare that
way is often *not* to commit it exactly or even use any data from
the original commit.

So a change like this would make the use of the command for my
usecase more cumbersome---now it leaves cruft behind, so I need to
clean it up later, but with what?  "cherry-pick --abort" would
try to muck with the index and the working tree, but that is not
definitely what I want.

So, personally, I am fairly negative on this line of change.  If the
user says upfront "--no-commit", then user does not want a commit,
so why should we even allow "--continue"?

Before dismissing the idea totally, let's see what potential use
cases this change _could_ benefit, and see if there are already ways
to satisfy these use cases without making this change.  For example,
if the user wants to examine the result before actually "committing"
to move the target branch forward with this change, keeping it an
option to back out if the result of cherry-picking turns out to be
bad, the "--no-commit first, examine, and --continue or --abort"
sequence may help such a workflow.

But the user can already do so without this change:

    $ git checkout target_branch^0 ;#detach
    $ git cherry-pick source_branch
    ... examine the result ...
    ... and if it is satisfactory ...
    $ git checkout -B target_branch
    ... or if it is not, then discard ...
    $ git checkout target_branch

> With this patch, we allow sequencer to save the metadata from the original
> cherry-pick operation so that 'git cherry-pick --continue' can be called.
Junio C Hamano Oct. 21, 2020, 8:41 p.m. UTC | #5
Junio C Hamano <gitster@pobox.com> writes:

> Before dismissing the idea totally, let's see what potential use
> cases this change _could_ benefit, and see if there are already ways
> to satisfy these use cases without making this change.  For example,
> if the user wants to examine the result before actually "committing"
> to move the target branch forward with this change, keeping it an
> option to back out if the result of cherry-picking turns out to be
> bad, the "--no-commit first, examine, and --continue or --abort"
> sequence may help such a workflow.
>
> But the user can already do so without this change:
>
>     $ git checkout target_branch^0 ;#detach
>     $ git cherry-pick source_branch
>     ... examine the result ...
>     ... and if it is satisfactory ...
>     $ git checkout -B target_branch
>     ... or if it is not, then discard ...
>     $ git checkout target_branch
>
>> With this patch, we allow sequencer to save the metadata from the original
>> cherry-pick operation so that 'git cherry-pick --continue' can be called.

And if the user wants to do the inspection while on the target
branch, "commit -c/-C" is the perfect choice.

    $ git cherry-pick --no-commit source_branch
    ... examine the result ...
    ... and if it is satisfactory ...
    $ git commit -c source_branch
    ... or if it is not, then discard ...
    $ git reset --hard
Edmundo Carmona Antoranz Oct. 21, 2020, 8:45 p.m. UTC | #6
On Wed, Oct 21, 2020 at 1:46 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> So, personally, I am fairly negative on this line of change.  If the
> user says upfront "--no-commit", then user does not want a commit,
> so why should we even allow "--continue"?

This is the way merge --no-commit works, actually. You run
--no-commit, then you run merge --continue to wrap it up and that's
why to me it had always felt a bit off in terms of consistency of the
UI.

>
> Before dismissing the idea totally, let's see what potential use
> cases this change _could_ benefit, and see if there are already ways
> to satisfy these use cases without making this change.  For example,
> if the user wants to examine the result before actually "committing"
> to move the target branch forward with this change, keeping it an
> option to back out if the result of cherry-picking turns out to be
> bad, the "--no-commit first, examine, and --continue or --abort"
> sequence may help such a workflow.

Case in point, I am working on a script that corrects EOL format of
files in a branch. When I started developing it, I was trusting that I
could run cherry-pick --no-commit so that I could then check the exit
code of git to see if there had been problems or not in the operation.
If there were, I would correct the EOL format of the files. Then,
successful cherry-pick or not, I would run cherry-pick --no-commit and
it would work.... but that was when I realized that cherry-pick
--no-commit is not keeping the information. Given that --no-commit
_forgets_ the information from the revision, I have to run a normal
cherry-pick. If it fails, I correct the EOL format and then I run
cherry-pick --continue. It is noty like a game changer, you know... I
can live with it.... how many people have complained about it, anyway?
I just find it inconsistent in terms of how cherry-pick/merge
--no-commit behave.

https://github.com/eantoranz/conflict_book/blob/0385d240dda962512b215781039ed42ec2f12ec2/scripts/correct_eol.sh#L197

Anyway, thanks for all your feedback and let's see if there are more comments.

BR


>
> But the user can already do so without this change:
>
>     $ git checkout target_branch^0 ;#detach
>     $ git cherry-pick source_branch
>     ... examine the result ...
>     ... and if it is satisfactory ...
>     $ git checkout -B target_branch
>     ... or if it is not, then discard ...
>     $ git checkout target_branch
>
> > With this patch, we allow sequencer to save the metadata from the original
> > cherry-pick operation so that 'git cherry-pick --continue' can be called.
>
Edmundo Carmona Antoranz Oct. 21, 2020, 8:53 p.m. UTC | #7
On Wed, Oct 21, 2020 at 2:45 PM Edmundo Carmona Antoranz
<eantoranz@gmail.com> wrote:
> If there were, I would correct the EOL format of the files. Then,
> successful cherry-pick or not, I would run cherry-pick --no-commit and
> it would work.... but that was when I realized that cherry-pick

I meant success cherry-pick or not, I would run cherry-pick --continue
diff mbox series

Patch

diff --git a/sequencer.c b/sequencer.c
index 00acb12496..c1ccbe0faf 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2022,9 +2022,8 @@  static int do_pick_commit(struct repository *r,
 	 * However, if the merge did not even start, then we don't want to
 	 * write it at all.
 	 */
-	if ((command == TODO_PICK || command == TODO_REWORD ||
-	     command == TODO_EDIT) && !opts->no_commit &&
-	    (res == 0 || res == 1) &&
+	if ((command == TODO_PICK || command == TODO_REWORD || command == TODO_EDIT)
+		&& ((res == 0 && opts->no_commit) || (res == 1 && !opts->no_commit)) &&
 	    update_ref(NULL, "CHERRY_PICK_HEAD", &commit->object.oid, NULL,
 		       REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR))
 		res = -1;