I was doing a big interactive rebase where I was editing something like 8 commits. This is done with git commit --amend
. My issue is that at one point I got a merge conflict which I did not notice, so I kept on naively amending and git rebase --continue
-ing. Apparently I now have amended multiple commits into one, and about 4 of my commits are gone after finishing the rebase. The changes has been amended into other commits.
Is there any way for me to undo these amends, or maybe reapply the commits that are gone?
Of course; one solution is to go back and do the rebase again, but I did quite a lot of edits in the rebase, so I would love to not have to re-do all my work. How I got into this predicament is another story.
Git tree example:
Before rebase: A-B-C-D-E-F
After rebase: A-B-C-F
(C now has changes from D and E amended)
Yes, you can.
Normally, I would go right back and redo everything, but I can understand the problem - it sounds like you have invested a lot of time into the rebase already, so it does not seem inviting to do all of it again.
I assume that the contents of F
in your example are exactly what you want your end result to be, you are just missing the D
and E
commits.
What you can do is this:
git checkout C # "git status" should be empty right now
git checkout F .
git reset .
git add only-changes-from-D ; git commit -m D
git add only-changes-from-E ; git commit -m E
git add -A ; git commit -m F
The git checkout F . ; git reset .
makes it so that your working directory contains F
, but your HEAD is still pointed at C
, and nothing is in the index. git status
will now show you the complete diff between C
and F
.
Now you take your favourite add/commit tool (I like git gui
) and pick out every change that belonged to D
originally, and commmit. Repeat for E
. After that, only the changes from F
are there; you can add and commit them in one go. Of course, if there are more between E
and F
you will have to rinse and repeat.
This has the benefit that you do not actually need to change anything. The end result will be exactly F
, but you will get a few intermediate commits as needed.