Do a git reset and push to undo previous local git commits example
I published an article recently on how to perform a hard git reset, but one of the questions that I was repeatedly asked on social media was what happens after you do a hard git reset on local commits and then publish the changes to your remote GitHub or GitLab repository? When you do a git reset and push, does the entire commit history get published, including the commits that happened subsequent to the reset point, or are the commits that Git rolled back ignored?
How to git reset hard and push
When working locally, it’s not exactly clear what happens when you git reset to a previous commit and push those commits to a remote repository. So to demonstrate exactly what happens when you git reset and push, I’m first going to create an empty, remote GitHub repository named git-reset-explained. It will contain nothing but a readme.md file, an MIT licence, a .gitignore file and a single commit.
Cloning the git-reset-explained repo
With the remote GitHub repository created, I will locally clone the repo and begin working inside of it.
/c/ git reset hard and push / $ git clone https://github.com/cameronmcnz/git-reset-explained.git Cloning into 'git-reset-explained'... $ cd git* /c/ git reset hard and push / git reset explained
Creating a local commit history
From within the cloned repo, I will create five new files, adding a new commit each time.
/c/ git reset hard and push / git reset explained $ touch alpha.html $ git add . & git commit -m "Local commit #1" $ touch beta.html $ git add . & git commit -m "Local commit #2" $ touch charlie.html $ git add . & git commit -m "Local commit #3" $ touch depeche.html $ git add . & git commit -m "Local commit #4" $ touch enid.html $ git add . & git commit -m "Local commit #5"
A call to the reflog shows the history of HEAD as the git commit commands were issued:
/c/ git reset hard and push / git reset explained $ git reflog 014df6a (HEAD -> master) HEAD@{0}: commit: Local commit #5 6237772 HEAD@{1}: commit: Local commit #4 593794d HEAD@{2}: commit: Local commit #3 b1a6865 HEAD@{3}: commit: Local commit #2 8a3358e HEAD@{4}: commit: Local commit #1 d072c0a (origin/master, origin/HEAD) HEAD@{5}: clone
git reset to a previous commit
Now if I was to perform a hard git reset and shift HEAD to the third local commit, commits 4 and 5 should disappear, right? The git reset should remove those commits from my commit history and take me right back to the reset point, right? Let’s see what actually happens when we issue the command to git reset local commits.
/c/ git reset hard and push / git reset explained $ git reset --hard 593794d HEAD is now at 593794d Local commit #3
Now let’s see what the reflog looks like:
/c/ git reset hard and push / git reset explained $ git reflog 593794d (HEAD -> master) HEAD@{0} reset to 593794d 014df6a HEAD@{1}: commit: Local commit #5 6237772 HEAD@{2}: commit: Local commit #4 593794d (HEAD -> master) HEAD@{3}: commit: Local commit #3 b1a6865 HEAD@{4}: commit: Local commit #2 8a3358e HEAD@{5}: commit: Local commit #1 d072c0a (origin/master, origin/HEAD) HEAD@{6} clone
git reset hard and push
As you can see from the git reflog command, commits 014df6a and 6237772 are still hanging around. When you git reset local commits, those commits don’t disappear.
Knowing Git’s propensity to store everything, this isn’t a particularly unexpected result. The real question is, what would happen if you were to git reset to a previous commit and push to a remote repository? Would the two local commits git leapfrogged over get pushed as well, or would they remain isolated locally? To find out, we simply push to the remote origin:
/c/ git reset hard and push / git reset explained $ git push origin Counting objects: 7, done. To github.com/cameronmcnz/git-reset-explained.git d072c0a..593794d master -> master
After the push, when we look at the commit history on GitHub, we notice there are only four commits, the server-side commit that created the GitHub repository, and the three local commits that we published. When the git reset and push happened, the fourth and fifth local commits were not pushed to the server, essentially deleting any history of them ever existing.
git reset vs revert
So what did we learn? Well, that when we git reset to a previous commit and push to a remote repository, no trace of the undone commits are published. That’s in stark contrast to a git revert in which the revert command itself creates a new commit, and none of the past commit history is lost. So if you ever want to undo a previous commit with Git, reset is the right Git command to use, not revert.
-
Become a Git power user
Want to become a Git power user? Take a look at the following Git articles and tutorials
- How to do a Git clean up of branches and commits
- Learn to rebase onto master and rebase from the master branch
- Squash all Git commits on a branch down to one
- Shelve your changes with Git stash pop and apply
- Easily explain the Git vs GitHub difference
- Add a shallow git clone of depth 1 do your Jenkins jobs
- Set up a local Git server with a bare Git repo
- The Git fork command explained