Reputation: 791
I'm trying to undo a commit in the middle while keeping the following ones unchanged. I have thought it might be impossible before finding these posts: Post 1 & Post 2. (The ultimate goal might be duplicated but I indeed didn't have it work. I apologise for that.)
Unfortunately, I'm still stuck in how to use git rebase -i
properly. I created a sample repo as following:
commit cc2576365a9716bb9f96e195e599190d3c70fba0
Author: zzy
Date: Sun Jul 17 14:30:53 2016 -0400
commit #3
commit 11d9f8fdc69be8b4530e4b70c9661b4e34287afe
Author: zzy
Date: Sun Jul 17 14:30:36 2016 -0400
commit #2
commit 4770e08eb54d0d582bd4b391f2361a328b417cdf
Author: zzy
Date: Sun Jul 17 14:29:58 2016 -0400
commit #1
Each commit adds a new line at a file called a
(see a
's content below):
After commit #1
1
After commit #2
1
2
After commit #3
1
2
3
Now I intend to remove commit #2, and the a
should look like:
1
3
I tried the command as git rebase -i 11d9f8fdc69be8^
and get the text file as:
pick 11d9f8f commit #2
pick cc25763 commit #3
I deleted the first line, only keeping commit #3 and exited the file. But I get the following error:
error: could not apply cc25763... commit #3
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".
Could not apply cc2576365a9716bb9f96e195e599190d3c70fba0... commit #3
And the file a
becomes:
1
<<<<<<< HEAD
=======
2
3
>>>>>>> cc25763... commit #3
I'm confused why 2 is still here and why there are conflicts. Could anyone help me to get the expected result? Thanks in advance!
Upvotes: 0
Views: 1338
Reputation: 48418
Basically, since both commit #2 and commit #3 changed lines that were very close to each other in the same file, git doesn't know quite how to "replay" the changes in commit #3 now that commit #2 is no longer present, so you're getting a conflict.
Within the file that contains the conflicts, you see this:
<<<<<<< HEAD
=======
2
3
>>>>>>> cc25763... commit #3
The space between <<<<<<< HEAD
and =======
shows what the file contained in that location at commit #1, before commit #2 or commit #3 were created. The space between =======
and >>>>>>> cc25763... commit #3
contains the contents of that section of the file in commit #3, after commit #2 and commit #3 were added. Git expects you to use this information to decide manually what content the new version of commit #3 should contain now that you're trying to replay it without commit #2.
Replace that whole section of the file with what you want the file to contain after commit #3 is replayed. In this case, you'd replace:
<<<<<<< HEAD
=======
2
3
>>>>>>> cc25763... commit #3
With:
3
Then, run git add a
to stage these changes, and git rebase --continue
to continue the rebase.
Note that you only have to do this during a rebase when conflicts are encountered. For commits which change unrelated things (e.g. if commits #2 and #3 were changing entirely different files, or completely different sections of the same file), git rebase
can usually determine what changes to make automatically, and you won't encounter conflicts.
Upvotes: 2