So I have this weird situation.
I was doing an interactive rebase on 4 commits. I tried to squash, but I did it the wrong way around, I got the following error:
error: cannot 'squash' without a previous commit You can fix this with
'git rebase --edit-todo' and then run 'git rebase --continue'. Or you
can abort the rebase with 'git rebase --abort'.
I decided to run git rebase --edit-todo
and when I did so, only the last commit appeared. I changed it from squash
to pick
, and ran git rebase --continue
but now it appears that the other 3 commits I was trying to squash are not there any more.
So my mornings work appears to be lost.
There must be a way to recover those, right?
How can I do it?
CodePudding user response:
This is Git. Nothing is ever lost. The entire rebase is undoable!
Just use git reflog
to locate the place where you were just before the rebase. It will be obvious which one it is, because the first ones will describe the rebase.
Now just reset hard to that commit. Presto, you've undone the rebase.
Now just perform the rebase correctly the next time.
Example. I start with this situation:
* 18c9859 (HEAD -> what) zz
* e1af86b yy
* 47853b7 xx
* 45ebca0 (origin/main, origin/HEAD, main) zzz
I interactive rebase, wiping out yy
and xx
.
% git rebase -i main
Successfully rebased and updated refs/heads/what.
The situation is now:
* e2d37cd (HEAD -> what) zz
* 45ebca0 (origin/main, origin/HEAD, main) zzz
But this is not what I meant to do! xx
and yy
are gone! Oh noze!
But wait. No problem. We can undo. First, look in the reflog:
% git reflog
e2d37cd (HEAD -> what) HEAD@{0}: rebase (finish): returning to refs/heads/what
e2d37cd (HEAD -> what) HEAD@{1}: rebase (pick): zz
45ebca0 (origin/main, origin/HEAD, main) HEAD@{2}: rebase (start): checkout main
18c9859 HEAD@{3}: commit: zz [this is it]
...
Okay, undo:
% git reset --hard HEAD@{3}
All fixed! I'm back exactly where I was before the rebase:
* 18c9859 (HEAD -> what) zz
* e1af86b yy
* 47853b7 xx
* 45ebca0 (origin/main, origin/HEAD, main) zzz
Party on!
CodePudding user response:
You should:
git reflog
# Write down the lost commit hash
git cherry-pick <LOST_COMMIT_HASH>