The process of deleting a Git commit varies depending on whether the commit only exists locally, or has already been pushed to the remote repository.
There are also special considerations to be taken when deleting sensitive data, like an API key or some other credential. This guide only covers standard cases where the commits do not contain sensitive data. For further reading on deleting sensitive info, see this guide on deleting credentials from Git.
In this guide we’ll walk through these various scenarios and examine how Git manages commit history.
Deleting a local commit
Deleting a local commit can be done in a few separate ways, depending on whether or not you want to fully erase the changes themselves, or just undo the commit.
Deleting the most recent commit without losing changes
If you want to undo changes that you’ve committed, but haven't pushed yet, and also want to keep those changes locally, you can run:
git reset --soft HEAD~1
This command moves the current branch's HEAD back one commit, while keeping the changes locally. You can then make adjustments to the code as needed, then when you’re ready, add and commit as normal.
Deleting old or specific commits
To delete a specific commit from your history, you can perform a rebase, allowing you to edit, delete, combine, or change the order of commits in your project's history. We can use this command to drop an older commit and rebuild all of our subsequent commits on the commit right before the one targeted for deletion.
Step 1: Identify the commit
First, you need to identify the commit you want to delete. You can use the git log
command to list recent commits. Suppose you want to delete a commit with the hash abc1234
. Note the hash of the commit just before the one you want to delete, as you'll start the rebase from that point. If the commit you want to delete is abc1234
, find the commit just before it, for example xyz5678
.
Step 2: Start interactive rebase
To start an interactive rebase, use the git rebase -i
command followed by the commit hash of the commit just before the one you wish to delete. If you want additional context around the commit, you can also view a range of commits by passing in HEAD~N
, where N
is the number of commits back. Assuming you wanted to view the last 4 commits:
git rebase -i HEAD~4
This command will open an editor with a list of the last 4 commits, showing something like this:
pick xyz5678 The commit just before the one you want to deletepick abc1234 The commit you want to deletepick 678efgh A commit after the one you want to deletepick 89ijklm The most recent commit
Step 3: Delete the commit
In the editor, you'll see each commit from the specified range listed on its own line, starting with the word pick
. To delete the commit abc1234
, simply remove the entire line that contains this commit, or replace pick
with drop
for the specific commit you wish to remove:
pick xyz5678 The commit just before the one you want to deletedrop abc1234 The commit you want to deletepick 678efgh A commit after the one you want to deletepick 89ijklm The most recent commit
Then save and close the editor. Git will now reapply the commits from the current branch onto the branches below, skipping the commit that you specified.
Step 3a: Consider using the Graphite CLI for rebasing (optional)
While Git is an incredibly useful tool, it has many shortcomings, particularly with rebasing, and managing stacked pull requests.
The Graphite CLI simplifies git
, handles rebasing automatically, and allows you to create, submit, and stack pull requests right from the command line.
Under the hood, the CLI runs Git to create branches, commits, and metadata, which means you can still use Git in your scripts, tooling, or whenever you feel like it. Read more about installing the Graphite CLI in our docs.
Step 4: Resolve any conflicts
If there are conflicts during the rebase, Git will pause and allow you to resolve them.
For more information on this step, see this in-depth guide on how to resolve merge conflicts.
Once the conflicts have been resolved, you can continue the rebase process with:
git rebase --continue
Repeat this process of resolving conflicts and continuing for every branch, until the rebase is complete.
Step 5: Force push (if necessary)
If you've already pushed the commit you're deleting to a remote repository, you'll need to force push your changes:
git push --force
Caution: Force pushing can overwrite history on the remote and potentially cause issues for others who have cloned the repository. Always communicate with your team when performing operations like this on shared branches.
By following these steps, you can delete a specific commit from your Git history using interactive rebase. Remember, editing published history should be done with caution, especially in collaborative environments.
Deleting a Commit from a Remote Repository
Deleting a commit from a remote repository can be dangerous, as it always requires rewriting the Git history of the target branch. Proceed with caution and communicate with your other collaborators prior to running any destructive commands.
Deleting the most recent commit
If you've pushed a commit to a remote repository and want to remove it:
First delete the commit locally by running:
git reset --hard HEAD~1
This command deletes the most recent commit from your local repository, and discards the changes from that commit.
Force push to remote:
git push origin <branch-name> --force
Replace
<branch-name>
with your current branch. This overwrites the remote branch with your local branch, effectively removing the last commit.
Deleting old or specific commits from a remote repo
To remove an older or specific commit that has already been pushed:
Follow the Interactive rebase steps mentioned above to remove the commit locally.
Force push the changes:
git push origin <branch-name> --force
Deleting all unpushed commits
To delete all commits that haven't been pushed to the remote yet, essentially resetting your branch to match the remote, you can run:
git reset --hard origin/<branch-name>
This is useful if you have multiple local commits you would like to remove. Keep in mind this command is destructive and will discard the changes from these commits.
For further reading on deleting commits and the git reset
command, see the official Git documentation.