git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 4/7] revert: allow single-pick in the middle of cherry-pick sequence

From
Ramkumar Ramachandra <artagnon@gmail.com>
Date
Dec 14, 2011, 15:48 UTC
Message-ID
<CALkWK0mt03SSNT-svUO1wHdq5OpM=0xQO3FHkSGGEDuW-jUEXA@mail.gmail.com>
In-Reply-To
<20111210125948.GE22035@elie.hsd1.il.comcast.net>
Hi,
Jonathan Nieder wrote:
> When I messed up a difficult conflict in the middle of a cherry-pick
> sequence, it can be useful to be able to 'git checkout HEAD . && git
> cherry-pick that-one-commit' to restart the conflict resolution.

I was about to complain about the commit message until I noticed that Junio already fixed it in `next`:

    revert: allow single-pick in the middle of cherry-pick sequence
    After messing up a difficult conflict resolution in the middle of a
    cherry-pick sequence, it can be useful to be able to
        git checkout HEAD . && git cherry-pick that-one-commit
    to restart the conflict resolution. The current code however errors out
    saying that another cherry-pick is already in progress.
Interesting concept; let's see how it's implemented.
> Suggested-by: Johannes Sixt <j6t@kdbg.org>
Could you link to the corresponding thread with Johannes?
Show 13 quoted lines
> diff --git a/builtin/revert.c b/builtin/revert.c
> index 71570357..dcb69904 100644
> --- a/builtin/revert.c
> +++ b/builtin/revert.c
> @@ -1072,6 +1072,12 @@ static int sequencer_continue(struct replay_opts *opts)
>        return pick_commits(todo_list, opts);
>  }
>
> +static int single_pick(struct commit *cmit, struct replay_opts *opts)
> +{
> +       setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
> +       return do_pick_commit(cmit, opts);
> +}
single_pick as opposed to the continue_single_pick introduced in 2/7.
Show 13 quoted lines
>  static int pick_revisions(struct replay_opts *opts)
>  {
>        struct commit_list *todo_list = NULL;
> @@ -1097,6 +1103,26 @@ static int pick_revisions(struct replay_opts *opts)
>                return sequencer_continue(opts);
>
>        /*
> +        * If we were called as "git cherry-pick <commit>", just
> +        * cherry-pick/revert it, set CHERRY_PICK_HEAD /
> +        * REVERT_HEAD, and don't touch the sequencer state.
> +        * This means it is possible to cherry-pick in the middle
> +        * of a cherry-pick sequence.
> +        */

Conceptually all very good. What I'm really interested in seeing is how you persist opts for "cherry-pick --continue" when a single-commit pick fails: in other words, how you manage to get " --continue of single-pick respects -x" to pass.

> +       if (opts->revs->cmdline.nr == 1 &&
> +           opts->revs->cmdline.rev->whence == REV_CMD_REV &&
> +           opts->revs->no_walk &&
> +           !opts->revs->cmdline.rev->flags) {
Yuck, seriously.
1. I'd have expected you to check opts->revs->commits, not
opts->revs->cmdline.nr.  Okay, you're using the cmdline because the
revision walk hasn't happened yet.
2. Why are you using opts->revs->cmdline.rev->whence as opposed to
opts->action?  Why do you want to expose the underlying revision
walking mechanism?
3. When will the opts->revs->no_walk condition not be satisfied?  Only
when you explicitly set it to 0 or NULL, right -- where is this
happening in revert.c?
4. Why are you checking flags?  When is this condition not going to be
satisfied?

Since 3 and 4 indicate that you're being overly defensive, consistency requires you to guarantee that this code will work no matter what the rev_info struct is filled up with prior to this segment. Is this true?

Show 8 quoted lines
> +               struct commit *cmit;
> +               if (prepare_revision_walk(opts->revs))
> +                       die(_("revision walk setup failed"));
> +               cmit = get_revision(opts->revs);
> +               if (!cmit || get_revision(opts->revs))
> +                       die("BUG: expected exactly one commit from walk");
> +               return single_pick(cmit, opts);
> +       }
I'd have expected you to reuse prepare_revs().
> +       /*
>         * Start a new cherry-pick/ revert sequence; but
>         * first, make sure that an existing one isn't in
>         * progress

Since all your new code is a special case of "Start a new cherry-pick/ revert sequence", you don't check the sequencer state in the first place.

Show 19 quoted lines
> diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
> index 56c95ec1..98a27a23 100755
> --- a/t/t3510-cherry-pick-sequence.sh
> +++ b/t/t3510-cherry-pick-sequence.sh
> @@ -50,6 +50,18 @@ test_expect_success 'cherry-pick persists data on failure' '
>        test_path_is_file .git/sequencer/opts
>  '
>
> +test_expect_success 'cherry-pick mid-cherry-pick-sequence' '
> +       pristine_detach initial &&
> +       test_must_fail git cherry-pick base..anotherpick &&
> +       test_cmp_rev picked CHERRY_PICK_HEAD &&
> +       # "oops, I forgot that these patches rely on the change from base"
> +       git checkout HEAD foo &&
> +       git cherry-pick base &&
> +       git cherry-pick picked &&
> +       git cherry-pick --continue &&
> +       git diff --exit-code anotherpick
> +'

Cute feature, although I don't ever recall needing it personally. Why does this relatively esoteric "feature" belong along with the other "maintenance patches" in jn/maint-sequencer-fixes?

-- Ram
Previous: Jonathan NiederNext: Jonathan Nieder
Message 32 of 52 in “cherry-pick/revert error messages”
  1. Jonathan NiederNov 20, 2011
  2. Ramkumar RamachandraNov 20, 2011
  3. 0/3 Re: cherry-pick/revert error messagesJonathan Nieder, Nov 20, 2011
  4. 1/3 revert: rename --reset option to --quitJonathan Nieder, Nov 20, 2011
  5. Junio C HamanoNov 21, 2011
  6. Jakub NarebskiNov 21, 2011
  7. Jonathan NiederNov 21, 2011
  8. 2/3 revert: rearrange pick_revisions() for clarityJonathan Nieder, Nov 20, 2011
  9. 3/3 revert: improve error message for cherry-pick during cherry-pickJonathan Nieder, Nov 20, 2011
  10. 0/3 Re: cherry-pick/revert error messagesJonathan Nieder, Nov 22, 2011
  11. 1/3 revert: rename --reset option to --quitJonathan Nieder, Nov 22, 2011
  12. 2/3 revert: rearrange pick_revisions() for clarityJonathan Nieder, Nov 22, 2011
  13. 3/3 revert: improve error message for cherry-pick during cherry-pickJonathan Nieder, Nov 22, 2011
  14. 4/3 revert: write REVERT_HEAD pseudoref during conflicted revertJonathan Nieder, Nov 22, 2011
  15. Thiago FarinaNov 22, 2011
  16. Ramkumar RamachandraDec 1, 2011
  17. 5/3 revert: introduce --abort to cancel a failed cherry-pickJonathan Nieder, Nov 22, 2011
  18. Junio C HamanoNov 23, 2011
  19. Jonathan NiederNov 23, 2011
  20. Fix revert --abort on WindowsJohannes Sixt, Nov 23, 2011
  21. Jonathan NiederNov 23, 2011
  22. Johannes SixtNov 23, 2011
  23. 0/7 some sequencer loose ends (Re: Fix revert --abort on Windows)Jonathan Nieder, Dec 10, 2011
  24. 1/7 revert: give --continue handling its own functionJonathan Nieder, Dec 10, 2011
  25. Ramkumar RamachandraDec 14, 2011
  26. 2/7 revert: allow cherry-pick --continue to commit before resumingJonathan Nieder, Dec 10, 2011
  27. Ramkumar RamachandraDec 14, 2011
  28. Jonathan NiederDec 14, 2011
  29. 3/7 revert: pass around rev-list args in already-parsed formJonathan Nieder, Dec 10, 2011
  30. Ramkumar RamachandraDec 14, 2011
  31. 4/7 revert: allow single-pick in the middle of cherry-pick sequenceJonathan Nieder, Dec 10, 2011
  32. Ramkumar RamachandraDec 14, 2011
  33. Jonathan NiederDec 14, 2011
  34. Ævar Arnfjörð BjarmasonApr 5, 2012
  35. Jonathan NiederApr 5, 2012
  36. 5/7 revert: do not remove state until sequence is finishedJonathan Nieder, Dec 10, 2011
  37. Ramkumar RamachandraDec 14, 2011
  38. 6/7 Revert "reset: Make reset remove the sequencer state"Jonathan Nieder, Dec 10, 2011
  39. Ramkumar RamachandraDec 14, 2011
  40. 7/7 revert: stop creating and removing sequencer-old directoryJonathan Nieder, Dec 10, 2011
  41. Ramkumar RamachandraDec 14, 2011
  42. Jonathan NiederDec 11, 2011
  43. Junio C HamanoDec 12, 2011
  44. Junio C HamanoDec 12, 2011
  45. Jonathan NiederDec 14, 2011
  46. Alex RiesenNov 23, 2011
  47. Junio C HamanoNov 30, 2011
  48. 6/3 revert: remove --reset compatibility optionJonathan Nieder, Nov 22, 2011
  49. Junio C HamanoNov 22, 2011
  50. Jonathan NiederNov 22, 2011
  51. Junio C HamanoNov 22, 2011
  52. Jonathan NiederNov 22, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.