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

Re: [PATCH v4 3/7] merge: do not abort early if one strategy fails to handle the merge

From
Elijah Newren <newren@gmail.com>
Date
Jul 23, 2022, 00:36 UTC
Message-ID
<CABPp-BFeo2nxH38D1Cvd6RLRRt8PLOH+BLsoikchWv81rbvbFg@mail.gmail.com>
In-Reply-To
<220722.86o7xhs9qg.gmgdl@evledraar.gmail.com>

On Fri, Jul 22, 2022 at 3:49 AM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:

Show 80 quoted lines
>
> On Fri, Jul 22 2022, Elijah Newren via GitGitGadget wrote:
>
> > From: Elijah Newren <newren@gmail.com>
> >
> > builtin/merge is setup to allow multiple strategies to be specified,
> > and it will find the "best" result and use it.  This is defeated if
> > some of the merge strategies abort early when they cannot handle the
> > merge.  Fix the logic that calls recursive and ort to not do such an
> > early abort, but instead return "2" or "unhandled" so that the next
> > strategy can try to handle the merge.
> >
> > Coming up with a testcase for this is somewhat difficult, since
> > recursive and ort both handle nearly any two-headed merge (there is
> > a separate code path that checks for non-two-headed merges and
> > already returns "2" for them).  So use a somewhat synthetic testcase
> > of having the index not match HEAD before the merge starts, since all
> > merge strategies will abort for that.
> >
> > Signed-off-by: Elijah Newren <newren@gmail.com>
> > ---
> >  builtin/merge.c                          |  6 ++++--
> >  t/t6402-merge-rename.sh                  |  2 +-
> >  t/t6424-merge-unrelated-index-changes.sh | 16 ++++++++++++++++
> >  t/t6439-merge-co-error-msgs.sh           |  1 +
> >  4 files changed, 22 insertions(+), 3 deletions(-)
> >
> > diff --git a/builtin/merge.c b/builtin/merge.c
> > index 13884b8e836..dec7375bf2a 100644
> > --- a/builtin/merge.c
> > +++ b/builtin/merge.c
> > @@ -754,8 +754,10 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
> >               else
> >                       clean = merge_recursive(&o, head, remoteheads->item,
> >                                               reversed, &result);
> > -             if (clean < 0)
> > -                     exit(128);
> > +             if (clean < 0) {
> > +                     rollback_lock_file(&lock);
> > +                     return 2;
> > +             }
> >               if (write_locked_index(&the_index, &lock,
> >                                      COMMIT_LOCK | SKIP_IF_UNCHANGED))
> >                       die(_("unable to write %s"), get_index_file());
> > diff --git a/t/t6402-merge-rename.sh b/t/t6402-merge-rename.sh
> > index 3a32b1a45cf..772238e582c 100755
> > --- a/t/t6402-merge-rename.sh
> > +++ b/t/t6402-merge-rename.sh
> > @@ -210,7 +210,7 @@ test_expect_success 'updated working tree file should prevent the merge' '
> >       echo >>M one line addition &&
> >       cat M >M.saved &&
> >       git update-index M &&
> > -     test_expect_code 128 git pull --no-rebase . yellow &&
> > +     test_expect_code 2 git pull --no-rebase . yellow &&
> >       test_cmp M M.saved &&
> >       rm -f M.saved
> >  '
> > diff --git a/t/t6424-merge-unrelated-index-changes.sh b/t/t6424-merge-unrelated-index-changes.sh
> > index f35d3182b86..8b749e19083 100755
> > --- a/t/t6424-merge-unrelated-index-changes.sh
> > +++ b/t/t6424-merge-unrelated-index-changes.sh
> > @@ -268,4 +268,20 @@ test_expect_success 'subtree' '
> >       test_path_is_missing .git/MERGE_HEAD
> >  '
> >
> > +test_expect_success 'resolve && recursive && ort' '
> > +     git reset --hard &&
> > +     git checkout B^0 &&
> > +
> > +     test_seq 0 10 >a &&
> > +     git add a &&
> > +
> > +     sane_unset GIT_TEST_MERGE_ALGORITHM &&
> > +     test_must_fail git merge -s resolve -s recursive -s ort C^0 >output 2>&1 &&
> > +
> > +     grep "Trying merge strategy resolve..." output &&
> > +     grep "Trying merge strategy recursive..." output &&
> > +     grep "Trying merge strategy ort..." output &&
> > +     grep "No merge strategy handled the merge." output
> > +'

Oops, 'resolve' should really be at the end of the list rather than at the beginning. And the test description should be better.

Show 8 quoted lines
> Ah, re my feedback on 2/7 I hadn't read ahead. This is the test I
> mentioned as failing with the code added in 2/7 if it's tweaked to be
> s/exit 2/exit 0/.
>
> So it's a bit odd to have code added in 2/7 that's tested in 3/7. I
> think this would be much easier to understand if these tests came before
> all these code changes, so then as the changes are made we can see how
> the behavior changes.

This testcase belongs in this patch. The use of "resolve" here was totally incidental to the testcase in question; I could have used "octopus" or "ours" or created a new strategy and used it.

(Actually, using 'ours' here runs into the problem we fix in the final patch. So maybe just like 'resolve', using 'ours' might be confusing to readers of the series as they think issues from other patches are involved.)

> But short of that at least having the relevant part of this for 2/7 in
> that commit would be better, i.e. the thing that tests that new
> "diff-index" check in some way...

I'll switch this test to using 'octopus' instead of 'resolve' just so it doesn't get confused in this way.

Previous: Ævar Arnfjörð BjarmasonNext: Elijah Newren via GitGitGadget
Message 69 of 87 in “Fix merge restore state”
  1. 0/2 Fix merge restore stateElijah Newren via GitGitGadget, May 19, 2022
  2. 1/2 merge: remove unused variableElijah Newren via GitGitGadget, May 19, 2022
  3. Junio C HamanoMay 19, 2022
  4. 2/2 merge: make restore_state() do as its name saysElijah Newren via GitGitGadget, May 19, 2022
  5. Junio C HamanoMay 19, 2022
  6. Junio C HamanoMay 19, 2022
  7. Elijah NewrenJun 12, 2022
  8. ZheNing HuJun 12, 2022
  9. 0/6 Fix merge restore stateElijah Newren via GitGitGadget, Jun 19, 2022
  10. 1/6 t6424: make sure a failed merge preserves local changesJunio C Hamano via GitGitGadget, Jun 19, 2022
  11. 2/6 merge: remove unused variableElijah Newren via GitGitGadget, Jun 19, 2022
  12. Junio C HamanoJul 19, 2022
  13. 4/6 merge: make restore_state() restore staged state tooElijah Newren via GitGitGadget, Jun 19, 2022
  14. ZheNing HuJul 17, 2022
  15. Junio C HamanoJul 19, 2022
  16. Junio C HamanoJul 19, 2022
  17. Elijah NewrenJul 21, 2022
  18. 3/6 merge: fix save_state() to work when there are racy-dirty filesElijah Newren via GitGitGadget, Jun 19, 2022
  19. ZheNing HuJul 17, 2022
  20. Junio C HamanoJul 19, 2022
  21. Elijah NewrenJul 21, 2022
  22. Junio C HamanoJul 19, 2022
  23. 6/6 merge: do not exit restore_state() prematurelyElijah Newren via GitGitGadget, Jun 19, 2022
  24. ZheNing HuJul 17, 2022
  25. Junio C HamanoJul 19, 2022
  26. Eric SunshineJul 20, 2022
  27. Elijah NewrenJul 21, 2022
  28. Elijah NewrenJul 21, 2022
  29. 5/6 merge: ensure we can actually restore pre-merge stateElijah Newren via GitGitGadget, Jun 19, 2022
  30. ZheNing HuJul 17, 2022
  31. Junio C HamanoJul 19, 2022
  32. Elijah NewrenJul 21, 2022
  33. 0/7 Fix merge restore stateElijah Newren via GitGitGadget, Jul 21, 2022
  34. 1/7 merge-ort-wrappers: make printed message match the one from recursiveElijah Newren via GitGitGadget, Jul 21, 2022
  35. Junio C HamanoJul 21, 2022
  36. Elijah NewrenJul 21, 2022
  37. Junio C HamanoJul 21, 2022
  38. Elijah NewrenJul 21, 2022
  39. 2/7 merge-resolve: abort if index does not match HEADElijah Newren via GitGitGadget, Jul 21, 2022
  40. 3/7 merge: do not abort early if one strategy fails to handle the mergeElijah Newren via GitGitGadget, Jul 21, 2022
  41. Junio C HamanoJul 21, 2022
  42. Ævar Arnfjörð BjarmasonJul 25, 2022
  43. Elijah NewrenJul 26, 2022
  44. Ævar Arnfjörð BjarmasonJul 26, 2022
  45. 4/7 merge: fix save_state() to work when there are stat-dirty filesElijah Newren via GitGitGadget, Jul 21, 2022
  46. 6/7 merge: ensure we can actually restore pre-merge stateElijah Newren via GitGitGadget, Jul 21, 2022
  47. Junio C HamanoJul 21, 2022
  48. Ben HumphreysMar 2, 2023
  49. Elijah NewrenMar 2, 2023
  50. Junio C HamanoMar 2, 2023
  51. Rudy RigotMar 4, 2023
  52. Ben HumphreysMar 6, 2023
  53. 5/7 merge: make restore_state() restore staged state tooElijah Newren via GitGitGadget, Jul 21, 2022
  54. Junio C HamanoJul 21, 2022
  55. Junio C HamanoJul 21, 2022
  56. Elijah NewrenJul 21, 2022
  57. 7/7 merge: do not exit restore_state() prematurelyElijah Newren via GitGitGadget, Jul 21, 2022
  58. Junio C HamanoJul 21, 2022
  59. 0/7 Fix merge restore stateElijah Newren via GitGitGadget, Jul 22, 2022
  60. 1/7 merge-ort-wrappers: make printed message match the one from recursiveElijah Newren via GitGitGadget, Jul 22, 2022
  61. 2/7 merge-resolve: abort if index does not match HEADElijah Newren via GitGitGadget, Jul 22, 2022
  62. Ævar Arnfjörð BjarmasonJul 22, 2022
  63. Elijah NewrenJul 23, 2022
  64. Ævar Arnfjörð BjarmasonJul 23, 2022
  65. Elijah NewrenJul 26, 2022
  66. Ævar Arnfjörð BjarmasonJul 26, 2022
  67. 3/7 merge: do not abort early if one strategy fails to handle the mergeElijah Newren via GitGitGadget, Jul 22, 2022
  68. Ævar Arnfjörð BjarmasonJul 22, 2022
  69. Elijah NewrenJul 23, 2022
  70. 4/7 merge: fix save_state() to work when there are stat-dirty filesElijah Newren via GitGitGadget, Jul 22, 2022
  71. 5/7 merge: make restore_state() restore staged state tooElijah Newren via GitGitGadget, Jul 22, 2022
  72. Ævar Arnfjörð BjarmasonJul 22, 2022
  73. Elijah NewrenJul 23, 2022
  74. 6/7 merge: ensure we can actually restore pre-merge stateElijah Newren via GitGitGadget, Jul 22, 2022
  75. 7/7 merge: do not exit restore_state() prematurelyElijah Newren via GitGitGadget, Jul 22, 2022
  76. 0/8 Fix merge restore stateElijah Newren via GitGitGadget, Jul 23, 2022
  77. 2/8 merge-resolve: abort if index does not match HEADElijah Newren via GitGitGadget, Jul 23, 2022
  78. 1/8 merge-ort-wrappers: make printed message match the one from recursiveElijah Newren via GitGitGadget, Jul 23, 2022
  79. 4/8 merge: do not abort early if one strategy fails to handle the mergeElijah Newren via GitGitGadget, Jul 23, 2022
  80. 3/8 merge: abort if index does not match HEAD for trivial mergesElijah Newren via GitGitGadget, Jul 23, 2022
  81. 5/8 merge: fix save_state() to work when there are stat-dirty filesElijah Newren via GitGitGadget, Jul 23, 2022
  82. 6/8 merge: make restore_state() restore staged state tooElijah Newren via GitGitGadget, Jul 23, 2022
  83. 7/8 merge: ensure we can actually restore pre-merge stateElijah Newren via GitGitGadget, Jul 23, 2022
  84. 8/8 merge: do not exit restore_state() prematurelyElijah Newren via GitGitGadget, Jul 23, 2022
  85. Junio C HamanoJul 25, 2022
  86. Elijah NewrenJul 26, 2022
  87. ZheNing HuJul 26, 2022

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.