Undoing an errant 'git commit --amend
'
Suppose, not entirely hypothetically, that late some evening you
commit a change and somewhat later that evening notice that you
left something out of it. Sleepily confident that you haven't pushed
your first commit you fix the omission with 'git commit --amend
',
start updating your copy of the repo at work only to have it throw
you into a merge, and discover that not only did you propagate the
first commit, you pushed it to the public Github repo. Oops. Now you need to
reverse or undo the 'git commit --amend
' (and discard the update
that you pulled into your repo copy at work).
I don't know if the procedure I followed to fix my oops is the completely right one, but it worked and repaired things. Here is what I did:
- Use '
git reflog
' to look at recent changes in your repo (cf). If you literally committed and then amended, the top two commits are the relevant ones. For me, I saw:ae22c04 HEAD@{0}: commit (amend): ....
9cae7d1 HEAD@{1}: commit: ...
This is the amended commit and then the original one. We want to get back to the original commit (which is currently orphaned, cf).
- Get your repo back to the original commit. For me:
git reset "HEAD@{1}"
Various Internet sources suggest using '
git reset --soft
' instead. If I understand Git right, this will leave your amended version of the commit sitting in the git index ready to be immediately committed again. I personally would rather roll all the way back to the stage where I have to 'git add
' things again, which is what the command here did. - Inspect the output of '
git diff
', then make a real (non-amended) commit with 'git add
' and 'git commit
' as usual. - Push the new commit to Github et al.
(There is probably some way to get Github and your other repos to accept your new amended commit and forget the old one, but I don't know it offhand, I didn't feel like working it out at the time, and I shouldn't assume that no one has pulled a copy from my Github repo.)
To clean up my work repo, I aborted the in-flight merge with 'git
merge --abort
' and then re-pulled the master with 'git pull
'.
Presumably the work repo now has an orphaned copy of the amended
commit just as my home repo does, but I don't really care. If I was
really curious I could probably find it with some git command,
especially as I know (part of) its hash.
(The work and home repos are exact mirrors of each other and I'm
only making changes in one at any given point, in this case in the
home repo. I have to say that git handily beats rsync
for this,
although I have to overcome my twitch about possibly committing
incomplete work.)
PS: The right search terms to find this stuff on the Internet are
apparently [undo git commit amend]. Searching for [reverse git
commit amend] mostly got me discussions about how to use git
commit -amend
.
PPS: There may well be better ways to do this in Git (and if so, feel free to mention them in the comments). I'm not entirely hep to Git yet, partly because I want my repos to have a straight linear history if at all possible. Someday I may start doing rebases off private branches to get this, but not so far.
(This is the kind of entry that I write because someday I'm going to make this mistake again someday.)
|
|