How can I remove a commit on GitHub?
Categories:
How to Remove a Commit from Your GitHub Repository

Learn various methods to effectively remove unwanted commits from your GitHub repository, whether locally or remotely, using Git commands.
Accidentally committed sensitive information, a large file, or simply an incorrect change? Removing a commit from your GitHub repository is a common task in version control. This guide will walk you through different scenarios and the appropriate Git commands to safely remove or undo commits, both from your local history and the remote GitHub repository. Understanding these methods is crucial for maintaining a clean and secure project history.
Understanding Git History and Immutability
Before diving into removal techniques, it's important to grasp how Git history works. Git commits are snapshots of your project at a specific point in time. Each commit has a unique SHA-1 hash and points to its parent commit(s), forming a directed acyclic graph. This structure makes Git history generally immutable. When you 'remove' a commit, you're typically not deleting it from existence, but rather creating new commits that undo its changes or rewriting history to exclude it. Rewriting history can be destructive, especially on shared branches, so proceed with caution.
graph TD A[Initial Commit] --> B[Feature A Commit] B --> C[Bugfix Commit] C --> D[Accidental Commit] D --> E[Further Work Commit] subgraph Rewriting History D -- X[Remove D] --> C C --> E_new[Further Work Commit (rebased)] end subgraph Reverting D -- R[Revert D] --> D_reverted[Revert 'Accidental Commit'] D_reverted --> E[Further Work Commit] end
Conceptual diagram of Git history with options for removing or reverting a commit.
Method 1: Reverting a Commit (Safest for Shared History)
Reverting a commit creates a new commit that undoes the changes introduced by the target commit. This is the safest method, especially if the commit has already been pushed to a shared remote repository, as it doesn't rewrite history. It preserves the original commit in the history, along with the revert commit.
1. Identify the Commit
First, find the SHA-1 hash of the commit you want to revert. You can use git log
to view your commit history.
2. Revert the Commit
Execute the git revert
command with the commit hash. Git will create a new commit that undoes the changes. You'll be prompted to edit the commit message.
3. Push the Revert Commit
Once the revert commit is created locally, push it to your remote GitHub repository.
git log --oneline
# Pick the commit hash, e.g., 1a2b3c4
git revert 1a2b3c4
# A text editor will open for the commit message. Save and close.
git push origin <branch-name>
Commands to revert a commit and push the changes.
git revert HEAD
to revert the very last commit. For multiple commits, you can revert a range: git revert <commit-hash-old>..<commit-hash-new>
(note the order).Method 2: Resetting a Commit (Rewriting Local History)
Resetting a commit rewrites history by moving the branch pointer to an earlier commit, effectively making it as if the later commits never happened. This method is suitable for commits that have not yet been pushed to a shared remote repository, or if you are absolutely sure you are the only one working on that branch. There are three main types of resets: --soft
, --mixed
(default), and --hard
.
git reset --hard
on commits that have been pushed to a shared branch is highly discouraged. It will cause discrepancies with other developers' histories and require a force push (git push --force
), which can overwrite their work.git reset --soft
Moves the HEAD pointer to the specified commit, but keeps all changes from the 'removed' commits in your staging area (index). You can then commit them again as a single, new commit or discard them.
git reset --mixed (Default)
Moves the HEAD pointer and unstages the changes from the 'removed' commits. The changes remain in your working directory, allowing you to modify them before staging and committing again.
git reset --hard
Moves the HEAD pointer, unstages changes, and discards all changes from the 'removed' commits from your working directory. This is the most destructive option, as it permanently deletes uncommitted changes and the content of the 'removed' commits from your local machine.
1. Identify the Target Commit
Find the SHA-1 hash of the commit before the one(s) you want to remove. For example, if you want to remove the last two commits, you'd reset to the commit before those two.
2. Perform the Reset
Execute the git reset
command with the appropriate option (--soft
, --mixed
, or --hard
) and the target commit hash. For example, git reset --hard HEAD~1
removes the last commit.
3. Force Push (if already pushed)
If the commits you reset have already been pushed to GitHub, you will need to force push to update the remote history. Use git push --force-with-lease
for a safer force push.
# To remove the last commit (locally, keeping changes in working directory):
git reset HEAD~1
# To remove the last commit (locally, discarding all changes):
git reset --hard HEAD~1
# To remove a specific commit (and all subsequent commits) locally:
git reset --hard <commit-hash-before-unwanted-commits>
# If you need to update the remote after a reset (use with caution!):
git push --force-with-lease origin <branch-name>
Examples of git reset
commands and force pushing.
Method 3: Interactive Rebase (Removing Commits from History)
Interactive rebase (git rebase -i
) allows you to rewrite a series of commits. You can reorder, squash, edit, or delete commits. This is a powerful tool for cleaning up your commit history before pushing to a remote, or for removing specific commits from a local branch. Like git reset
, it rewrites history, so use it carefully on shared branches.
1. Start Interactive Rebase
Run git rebase -i <commit-hash-before-range>
where <commit-hash-before-range>
is the hash of the commit just before the first commit you want to modify. For example, git rebase -i HEAD~3
will let you modify the last three commits.
2. Edit the To-Do List
A text editor will open with a list of commits. Change pick
to drop
(or d
) next to the commit(s) you want to remove. Save and close the editor.
3. Resolve Conflicts (if any)
Git will apply the changes. If conflicts arise, resolve them manually, then git add .
and git rebase --continue
. If you get stuck, git rebase --abort
will exit the rebase.
4. Force Push (if already pushed)
If the rebased commits were already pushed, you'll need to force push to update the remote. Again, git push --force-with-lease
is recommended.
git log --oneline # Identify the commit before the range you want to modify
git rebase -i <commit-hash-before-range>
# Example of the interactive rebase editor:
# pick 1a2b3c4 Commit A
# pick 5d6e7f8 Commit B (unwanted)
# pick 9h0i1j2 Commit C
# Change 'pick' to 'drop' for unwanted commits:
# pick 1a2b3c4 Commit A
# drop 5d6e7f8 Commit B (unwanted)
# pick 9h0i1j2 Commit C
# After saving and closing the editor:
git push --force-with-lease origin <branch-name>
Using git rebase -i
to drop a commit and force push.
drop
, you can use squash
to combine commits, edit
to modify a commit, or reword
to change a commit message.