Git reset and friends
April 16, 2020
There are several scenarios where you’d want to undo changes when working with Git
. Let’s discuss some of those and possible solutions:
You did git commit locally but want to undo it
Option 1: You want to keep the staged changes after undoing the commit
git reset --soft HEAD~1
To unstage the changes but keep them locally
git reset HEAD
Option 2: You want to drop the staged changes after undoing the commit
git reset --hard HEAD~1
You did git push to remote but want to remove it and erase history in remote but keep local changes unstaged
This happened to me when I accidentally pushed a commit to wrong branch. I want to remove the commit from that branch immediately without keeping it in history but have it staged locally and ready to be committed and pushed to a correct branch.
git reset --soft HEAD~1 git push --force
If you wanted to keep the history of removing the commit in remote, use reset
instead
git revert HEAD
You will then need to supply a commit message for the commit that removes previous commit
You did git pull from remote but got “Pulling is not possible because you have unmerged files”
If you don't care about your local staged changes and just want to get updates from remote, then run the following to set your local with HEAD and pull your remote using git pull.
If you do care about your local changes (staged modifications i.e. modifications present in the local index but not yet committed), just stash
them first and then remove any local indexed non-committed modifications:
git reset --hard HEAD
You are getting “Your branch and remote have diverged”
If your local changes are already committed (not just staged), you need to do merge or rebase to bring the two sets of commits (the local one and the remote one) together.
You can fetch from origin and rebase local work on it like so:
git pull --rebase
You want to remove a commit from local and remote
And you don’t care about the history—execute the following in a given branch:
git reset HEAD^ # remove commit locally git push origin +HEAD # force-push the new HEAD commit
By the way, origin is just a a standard remote destination. You can have multiple remotes for your git repository.
Rebase from branch that was rebased
Another scenario:
You have a feature branch A and you branched off of it to create feature branch B
You use interactive rebase (or any other way to rebase)
rebase -i commit-sha
to squash commits in branch ATo rebase branch A onto branch B run:
git rebase --onto A B~ A
Checkout another branch with untracked changes present
Sometimes you make changes in a local branch and before committing them decide to switch to another branch (and drop the local changes). Depending on the changes you are trying to drop, you may get this message:
error: The following untracked working tree files would be overwritten by checkout: somefile.json Please move or remove them before you switch branches. Aborting
You can force the checkout and drop the changes by using -f (note that this will delete the local files that are not indexed)
git checkout -f develop