Git is an awesome piece of software, but it can be as complex as you want it to be.
There are plenty of ways one can undo changes with git.
Weâll review a couple of them.
This command shows the hashes of the last 10 commits, youâll probably need it!
Undo one or more commits
For this we use git reset <HASH>
.
This puts us back to the commit we give it.
It can do it in one of three ways:
--hard
: Destroys everything in its path. No changes are kept (staged or not).--soft
: Keeps all uncommitted changes, both staged and unstaged.--mixed
(Default option): Keeps all uncommitted changes, but unstages everything.
As a bonus, we can go back n
number of commits by using the HEAD
position instead of the commit hash:
Where n
is the number of commits we want to go back
To undo the last commit and keep uncommitted changes:
To undo the last commit and remove uncommitted changes:
Undo a merge
Merges seem scary and messy (and in some cases they are) but in the end itâs just a fancy commit.
As such, a git reset --hard HEAD~1
is more than enough to undo it!
If something goes wrong during a merge conflict you might consider using git merge --abort
and trying again from scratch.
Undo an add
If we donât pass a hash or HEAD
position to git reset
, it will default to the current HEAD
position.
Knowing this and that the default flag it uses is --mixed
, you can infer that to undo a git add .
the solution is:
As explained before, no commits will be touched, but all staged changes will end up in the working tree.
Undo a push
You canât.
What you can do is undo the breaking commit and push again.
There are two ways to go about this:
You work alone -> reset
Donât worry about it, just use git reset --hard HEAD~1
as we saw before and use the -f
flag when doing the next push.
This way, you are changing the commit history and forcing your local repository onto the remote one.
After you push this second time, youâll see the last commit disappear from the remote repo.
You work in a team -> revert
That wonât work if you are not the only one working on that repo (or on that branch).
Well it would work, you just shouldnât do it.
Someone else might depend on what you just removed and even if they donât, you are likely to cause conflicts with that method.
In this case, we do a git revert HEAD --no-edit
.
This will create a separate commit that only includes the changes necessary to undo (revert) the commit it receives (in this case, HEAD
).
Now, after a normal git push
youâll see a new commit with the same message as the one that broke stuff, prepended by âRevert âŚâ.
This is the safe approach.
The Nuclear option
Sometimes, you just have no clue what the heck you did to your local repository.
Itâs a mess you can only untangle by resetting it to whatever is working on the remote.
To get your local repo back in sync with the remote one:
We sync our repo refs to the remote ones, use it to do a hard reset and clean all untracked files recursively, just in case.
Hopefully you can work calmly now, knowing that git has your back!