Elena' s AI Blog

Reverting Commits in GitHub

26 Aug 2022 (updated: 03 Jul 2026) / 12 minutes to read

Elena Daehnhardt


Reverting Commits in GitHub


TL;DR:
  • Revert Git commits: use 'git reset' for local changes, 'git revert' for shared commits (safer), 'git rebase -i' to rewrite history. Never rewrite public history—use revert instead.

Previous: Part 6 — Git Log

Next: Part 10 — Restoring deleted files in Git

How to Undo Git Commits with reset, revert, and rebase

In my previous posts “GIT in 10 minutes” and Collaboration in GitHub, I have covered the basics of Git setup, a few workflow commands to get started using Git (version control system), and collaborative work, including operations with forks and pull requests. As promised, I will go into more detail about working with Git repositories. Herein I will focus on reverting your changes. Sometimes it’s good to step back and think about something different, right?

Git Fork-and-Pull-Request Workflow Setup

I assume here the following setup:

  1. We work on a GitHub project with other team members working together on an “upstream” repository.
  2. We have forked this upstream repository and named our fork “origin.”
  3. We have a local copy of the origin repository (which we sync regularly with the upstream repository)
  4. This local copy of the origin repository (forked one) is changed with the next code contributions.
  5. We commit our local changes to the origin forked repository.
  6. In the forked repository, we create a Pull Request to the upstream repository.

The workflow can be described with the following example.

Cloning your forked repo locally

    git clone <tocken>@github.com/<user/<repo>
    cd repo

Add upstream

    git remote add upstream https://githubcom/<upstream_user>/<repo>

Working on your branch

    git checkout master
    git checkout -b your_branch_name
    git fetch upstream

Make changes

    git add .
    git commit -m' message'
    # use -u for your first push
    git push -u origin your_branch_name 

Possibly, we revert our changes

We might reconsider the changes at this step and try to revert the commit.

Pull Request

Next, we will go to your GitHub forked repository and click the “Compare & Review” green button beside the branch button. Or, on your fork page, press the “Pull Request” button.

We might want to do the changes after PR

At this stage, we cannot just revert commit so quickly. We will need to proceed with a new PR.

Update Frequently with git pull upstream master

It’s important to mention that when working with the remote repository, pulling the most recent changes from the master is essential. Before that, ensure that the upstream remote is set up (with git remote -v).

    git pull upstream master

git reset vs git revert: When to Use Each

Sometimes we do not want to keep changes that are already committed. Let’s consider the following cases of when and how we revert or disregard these changes.

git reset is a Git command that moves the current branch tip to an earlier commit, discarding the commits after it (history-rewriting). git revert is a Git command that creates a new commit which undoes the changes of a previous commit while preserving history (non-destructive). The two main ways to undo committed changes:

Command What it does History Safe on shared branches?
git reset [hash] Moves the branch tip back, dropping later commits Rewrites history No — only for local, unpushed commits
git revert [hash] Adds a new commit that cancels a previous one Preserves history Yes — preferred for pushed commits

Reverting a Commit with git revert [hash]

GitHub Docs “Reverting a commit” state that reverting a commit is a commit, and it is good practice reverting commits “order from newest to oldest.” Use “git log” to check the commit history and hashes of commits.

    git log

This output will include the hash strings you can use to revert a commit. The identifier string is located to the right of the word “commit.”

commit ec427b9199866d88dd67db744012264c3bfb4b62
Author: Elena Daehnhardt my@mail.com
Date:   Mon Jul 11 13:28:22 2022 +0200 

    +_posts/2022-07-11-tf-nlp.md

commit 3fb88a4c6aa122f9fdd0a38adec3bb46fd9f2d67
Author: Elena Daehnhardt my@mail.com
Date:   Mon Jul 11 13:27:52 2022 +0200

    +forks update, fetch upstream

A hash code identifies each commit and can be used to manage or see the related commit. With git checkout, we can analyze the commit with the defined hash.

    git checkout [hash]

With git revert, we revert to the previous commit with the defined hash code.

    git revert [hash]

Resetting a Commit with git reset [hash]

git reset sets a repository back to a specific commit.

    git reset [hash]

Interestingly, we can also undo the reset of a commit when we know the commit hash of the reset.

It is essential to mention that we should avoid changing the commit history when working on remote repositories, especially when collaborating with others. When the commit was not yet uploaded into a remote server, we can reset to a previous commit before any changes are made using the following options.

Option 1. cleans up all your changes which are lost. This option will altogether remove any changes from the local repository.

    git reset --hard [hash]

To update the remote repository after the hard reset, you can do a force push. Herein “origin” is the name of remote, and “main” is its branch name.

    git push -f origin main

Option 2. resets to the commit, and your changes are preserved with stashes (first saved, then hard reset, and finally with pop).

    git stash
    git reset --hard [hash]
    git stash pop

Option 3. resets the commit history but preserves your files.

    git reset --soft [hash]

Option 4. default option unstaging the changes. This option will reset back to the commit with the defined hash number.

    git reset --mixed [hash]

Option 5. resetting to the latest commit just before the HEAD.

    git reset --mixed HEAD~

Option 6. When things go totally wrong, we can use the hard reset option.

    git fetch origin
    git checkout main
    git reset --hard origin/main
    git clean -d --force

Reverting Pushed Changes on a Remote Repository

Prefer git revert when undoing changes already pushed to a remote repository. git revert keeps the history intact for other people working on the repository, whereas git reset followed by a force push rewrites shared history and can break their clones.

Rewriting History with git rebase –interactive

git rebase is a Git command that reapplies commits onto a new base, letting you edit, delete, reorder, or squash commits to rewrite branch history. Use git rebase with caution, because it rewrites history. The interactive form lets you work with the latest five commits in your current branch.

    git rebase --interactive HEAD~5
Rebase Example

Resolving “Updates were rejected because the tip of your current branch is behind”

After a git reset or git revert, a normal git push can fail with:

! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs
Updates were rejected because the tip of your current branch is behind its remote counterpart.

Cause: your local history no longer fast-forwards onto the remote, because you rewrote commits locally. Fix it by force-pushing your rewritten branch (only on branches you own):

    git push -f origin main

For a full walkthrough of this error, see Fix “Updates were rejected” non-fast-forward push errors.

Conclusion: reset vs revert vs rebase for Undoing Commits

In this post, I have covered fixing commit mistakes in Git. git revert is a non-destructive command that undoes a commit by adding a new one and is safer than git reset, which rewrites history. We have learned how to check the commit history with git log and get commit hashes. I also used git stash to keep changes while doing the reset. git rebase is another option to interactively cherry-pick, join, reorder, and delete commits. In my next post, I go into more detail about GitHub merge conflicts.

Git Reverting and Resetting Commits FAQ

What is the difference between git reset and git revert?

git reset moves the branch tip to an earlier commit and discards the later commits, rewriting history — use it only on local, unpushed commits. git revert creates a new commit that undoes a previous one while preserving history, so it is the safe choice for commits already pushed to a shared remote.

How do I undo a commit that I already pushed to a remote repository?

Use git revert [hash] to add a new commit that cancels the pushed commit while keeping history intact for collaborators. Avoid git reset --hard plus a force push on shared branches, because rewriting public history can break other people’s clones.

What is the difference between git reset –soft, –mixed, and –hard?

git reset --soft [hash] moves the branch tip but keeps your changes staged. git reset --mixed [hash] (the default) keeps the changes in your working directory but unstages them. git reset --hard [hash] discards all changes after the target commit permanently.

How do I keep my changes while resetting a commit?

Stash first, then reset, then restore: run git stash, git reset --hard [hash], and git stash pop. Alternatively, use git reset --soft [hash] to move the tip while leaving your changes staged.

How do I find the commit hash to revert or reset to?

Run git log to list the commit history. Each entry shows a 40-character hash to the right of the word commit; copy that hash and pass it to git revert [hash] or git reset [hash].

References

Reverting a commit.

Git Reset

About Git rebase

Did you like this post? Please let me know if you have any comments or suggestions.

Git posts that might be interesting for you



August 2022 Storks having a walk

Stork 'Teens' and Me

desktop bg dark

About Elena

Elena, a PhD in Computer Science, simplifies AI concepts and helps you use machine learning.

Citation
Elena Daehnhardt. (2022) 'Reverting Commits in GitHub', daehnhardt.com, 26 August 2022. Available at: https://daehnhardt.com/blog/2022/08/26/git-reverting-commits/
All Posts