0

I am in the process of cleaning up a series of commits for pushing to the master branch.

In the process I am running into a recurring type of merge conflict, that appears when a deletion and an insertion are adjacent to each other.

Is there same way to handle such cases automatically, without error-prone manual conflict resolution?

Example

Let’s say I have the following sequence of commits:

           (master)                      (devel, HEAD)
History    A ------------- B ----------- C

File State : This          : This        : This
           :   is          :   is        :   is
           :   some        :   some      :   some
           :   versioned   :   official  :   official
           :   document.   :   versioned :   document.
           :               :   document. :

Diff       :               :   some      :   official
           :               :+  official  :-  versioned
           :               :   document. :   document.

Now, as part of the clean-up, I need to change the order of the insertion and deletion. The target is the following:

           (master)                      (devel, HEAD)
History    A ------------- B’ ---------- C’

File State : This          : This        : This
           :   is          :   is        :   is
           :   some        :   some      :   some
           :   versioned   :   document. :   official
           :   document.   :             :   document.

Diff       :               :   some      :   some
           :               :-  versioned :+  official
           :               :   document. :   document.

I am trying to achieve this by

>> git checkout devel
>> git rebase -i master

with the rebase-todo set to

pick C
pick B

After pick C this gives a merge conflict.

@@@ -1,5 -1,5 +1,9 @@@
  This
    is
    some
++<<<<<<< HEAD
 +  versioned
++=======
+   official
++>>>>>>> 9a2f008... Remove word 'versioned'
    document

If I resolve the conflict by hand. After pick B, another conflict occurs:

@@@ -1,4 -1,6 +1,9 @@@
  This
    is
    some
++<<<<<<< HEAD
++=======
+   official
+   versioned
++>>>>>>> 6a39609... Add word 'official'
    document

In this simple example, it is viable, because I can remember for each step the exact state I want. In real-world applications, this is by far not that easy, and there is a high chance of mixing things up.

Is there some better way to do this?

Real world use-case

While working on a ticket, I created a mixture of maintenance changes, addition of debug statements, and changes actually fixing the ticket. In order to clean up the resulting mess, I did

git reset master

and then committed with git gui, change-by-change, categorizing each change as "debug", "maintenance", "ticket". So the commit history looks roughly like this:

>> git log --oneline
1442b73 (HEAD -> devel) ticket
6d61223 ticket
011703b debug
a19067d ticket
0392f8f maintenance
af8891e ticket
b96022f maintenance
4cd9222 debug
1626927 maintenance
bda00f0 debug
971ad39 ticket
944dfde (master) bla

One of the "debug" commits adds debug statements, directly adjacent to dead code that is removed in a subsequent "maintenance" commit. The debug commits are not meant to be pushed to master, but I still need them locally, so I am trying to reorder this to

011703b (HEAD -> devel) debug
4cd9222 debug
bda00f0 debug
0392f8f maintenance
b96022f maintenance
1626927 maintenance
1442b73 ticket
6d61223 ticket
a19067d ticket
af8891e ticket
971ad39 ticket
944dfde (master) bla

before squashing together commits of the same topic.

9d76a5e (devel) debug
fd82ab3 (HEAD) ticket    <-- push up to here
b22a6f0 maintenance
f68131e (master) bla

During this reordering, the conflict occurs.

kdb
  • 4,098
  • 26
  • 49
  • This is indeed normal (and annoying): adjacency counts as a conflict. [Maciej Pokrzywiński's suggestion of using `git rerere`](https://stackoverflow.com/a/65234319/1256452) is probably the way to go here. I just wanted to add that I find setting `merge.conflictStyle` to `diff3` also to be helpful. – torek Dec 10 '20 at 23:53

1 Answers1

2

Do you know git rerere? When you enable It, he will be remember your conflict results. It can be helpful in this situation.

Good description how rerere works:

You can try it in your cases and check results.