Kuan Kuan - 11 months ago 57
Git Question

Why I get a strange conflit when doing git rebase


My commit log is like:

commit 1e17b836cce12d497ef86e5b2c45410c93caf3a2
add 4
commit cbf7e720313ef6c918a8d4117df007eabe2ef92b
add 3
commit 951f86964102e17cdf3e3c2978c1adf8d5cdfab7
add 2
commit a275ad4e6716b950d86ce8885d766bba803fc9e0
add 1
commit d14904ad7fa9142cbc38489d1d621d1a157aa0cd
init commit

Basically, init commit is a blank file, and each commit I add one line with according number. Now, say I want to remove that
add 2
operation but keep others, someone told me I should use
git rebase -i HEAD~3

The rebase shows me a history to modify, I change it to:

drop 951f869 add2
pick cbf7e72 add3
pick 1e17b83 add4

And save it. Then I got a conflict error:

error: could not apply cbf7e72... add3

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

Then I use git diff to check where is conflict, I got :

diff --cc test
index 56a6051,5f5fbe7..0000000
--- a/test
+++ b/test
@@@ -1,1 -1,3 +1,7 @@@
- 1
++<<<<<<< HEAD
+ 1
+ 2
++>>>>>>> cbf7e72... add3

My question here is:

How this conflict get calculated out? Where is my line of 4? This rebase conflict totally ruins the content and not indicates correct diff which I have no way to resolve the correct content out based on current conflict file.

So what is the correct way to this? A step by step example with result output will be more than appreciated.

Answer Source

It might be easier to explain if we use some text in the lines of code. I'll just create a file with each commit adding a new line with the corresponding commit. e.g.

final file looks like this:

First Line
Second Line
Third Line
Fourth Line

Then when I do the interactive rebase, I'll get this prompt:

<<<<<<< HEAD
First Line
First Line
Second Line
Third Line
>>>>>>> 8ba3272... Added Third Line

Everything above ============= is the original, and everything after was the state after the third commit. There is a merge conflict because it's trying to add a line to the third line, and there isn't one yet. So this is where you would need to resolve the conflict. If you want the output to be:

First Line
Third Line

You would just need to delete the <<<<<<< and >>>>>>>>>>>>>> markers and enter how you would want the file to look, then do a git add then git rebase --continue.

Then it would try to add the 4th commit, and you'd get another merge conflict because it's trying to add a fourth line. So you'd just need to resolve that conflict in the same way. Followed by another git rebase --continue to finish the interactive rebase.

The final file should look like this:

First Line
Third Line
Fourth Line

and the git log would show this (the commit adding the second line has been removed):

commit 9064bd9d9efece49c0cf2dacd41be98e8cb70d01
Author: Kief Kraken
Date:   Thu Sep 29 11:05:44 2016 -0700

    Added fourth Line

commit cdcd1a33fb7b41e583fdb8098b266b0fb6898aca
Author: Kief Kraken
Date:   Thu Sep 29 11:05:21 2016 -0700

    Added Third Line

commit 7744551b481d4c6f7f5da038c56f3044d8b000d2
Author: Kief Kraken
Date:   Thu Sep 29 10:52:20 2016 -0700

    Added first line

commit e8e76881002e361401bbaaa22140660ed026fd04
Author: Kief Kraken
Date:   Thu Sep 29 10:51:56 2016 -0700

    first commit

While this is good for an exercise learning about interactive rebasing, I would strongly recommend using a merge tool that makes managing these tasks much easier and give less room for error.