Deleting a commit in Git is a common task, but it is also one of the operations that can cause confusion if the wrong command is used. If you want to learn how to delete commit in Git, the most important thing to understand is that Git does not always “remove” a commit in the same way a file manager deletes a file. Which means instead, Git moves references, rewrites history, or creates a new commit that cancels the previous one. The correct method depends on whether the commit is still only on your local machine, whether it has already been pushed to a remote repository, and whether other people are working on the same branch.
Introduction
In Git, a commit is a snapshot of your project at a specific point in time. Each commit has its own unique identifier, usually called a SHA-1 hash, and it points to the previous commit in the history. This chain of commits is what makes Git powerful. It allows developers to track changes, branch freely, and restore previous states.
On the flip side, mistakes happen. In those cases, you may need to delete a commit. The good news is that Git gives you several safe and powerful options. Now, you may commit too early, include a file that should not be in the repository, write a bad commit message, or accidentally push work that was not ready. The challenge is knowing which one to use.
Before You Delete a Commit
Before running any command, ask yourself three questions:
- Has the commit been pushed to a remote repository?
- Are other developers working on the same branch?
- Do you want to keep the file changes from that commit?
These questions matter because deleting a commit that has already been shared can rewrite history for everyone. That can break other people’s work if they have already based their commits on yours.
If the commit is local only, you usually have more freedom. If the commit has been pushed to a shared branch, you should usually use a safer method that does not rewrite history.
How to Delete a Commit That Has Not Been Pushed
If the commit exists only on your local branch, you can usually remove it with git reset or git rebase. The command you choose depends on what you want to do with the changes Took long enough..
Undo the Last Commit and Keep the Changes
If you made a commit but want to keep the changes in your working directory or staging area, use:
git reset --soft
HEAD~1
This command moves the branch pointer back one commit while leaving the index and working tree untouched. The changes from the undone commit stay staged, so you can edit them, amend the commit message, or recommit them later.
### Undo the Last Commit and Unstage the Changes
If you prefer the modifications to appear as unstaged changes in your working directory, use the mixed reset (the default mode):
```bash
git reset HEAD~1
or explicitly:
git reset --mixed HEAD~1
Now the commit is removed from history, the index is cleared, but the file edits remain in your working tree. You can review, modify, or discard them as needed.
Undo the Last Commit and Discard the Changes
When you are certain that the commit’s changes are no longer wanted, a hard reset will erase both the commit and its modifications:
git reset --hard HEAD~1
Caution: This operation is destructive; any uncommitted work will be lost. Use it only when you are sure the changes can be safely discarded.
Removing Multiple Recent Commits
To drop several commits at once, specify a larger offset:
git reset --hard HEAD~3 # removes the last three commits
Replace --hard with --soft or --mixed depending on whether you want to keep the changes staged, unstaged, or discarded.
Interactive Rebase for Selective Deletion
If you need to delete a commit that is not the most recent one, or you want to edit, squash, or reorder commits, an interactive rebase offers fine‑grained control:
git rebase -i HEAD~n # replace n with the number of commits to inspect
In the editor that opens, change the word pick to drop (or simply delete the line) for each commit you wish to eliminate. On top of that, save and close the file; Git will rewrite the history, omitting the selected commits. After the rebase finishes, you may need to force‑push if the branch has already been shared (see the next section) Less friction, more output..
How to Delete a Commit That Has Already Been Pushed
When a commit exists on a remote repository, rewriting history can affect collaborators. The safest approach is to add a new commit that reverses the unwanted changes, preserving the existing history for everyone else.
Using git revert
git revert creates a new commit that undoes the effects of a specified commit without altering existing history:
git git revert
If you want to revert the most recent commit:
git git revert HEAD
Git will open an editor for you to craft a revert message; save and close to complete the operation. The resulting commit appears as a normal commit in the log, and anyone who pulls will see the reversal applied cleanly Worth keeping that in mind..
Reverting a Merge Commit
Reverting a merge requires specifying the parent branch you want to keep:
git git revert -m 1
The -m 1 flag tells Git to treat the first parent (usually the branch you merged into) as the main line and to undo the changes introduced by the second parent It's one of those things that adds up..
When You Must Rewrite History
In rare cases—such as removing sensitive data or correcting a mistake that would otherwise pollute the project—you may need to rewrite pushed history. This should be done only after coordinating with all team members and ensuring nobody has based work on the commits you intend to delete That's the whole idea..
- Notify collaborators that you will force‑push the branch.
- Perform the rewrite locally using
git reset,git rebase -i, orgit filter‑repo(for large‑scale history changes). - Force‑push with a lease to avoid overwriting new work that others may have pushed in the meantime:
git push --force-with-lease origin
The --force-with-lease option aborts the push if the remote has moved since you last fetched, providing a safety net against accidental overwrites And it works..
Conclusion
Deleting a commit in Git is not a single‑command operation; the right technique hinges on whether the commit is local only, whether it has been shared, and what you intend to do with its changes. Which means for local work, git reset (soft, mixed, or hard) or an interactive rebase lets you erase or modify commits with full control over the file states. Consider this: for commits that have already been pushed, git revert is the preferred, history‑preserving method, while a force‑push should be reserved for exceptional circumstances and executed only after clear communication with the team. By assessing the situation beforehand and choosing the appropriate command, you can keep your repository clean without jeopardizing collaboration.
Additional Considerations and Best Practices
Recovering Lost Commits with git reflog
Even if you accidentally delete a commit or reset too aggressively, Git keeps a record of recent actions in the reflog. You can use this to recover lost commits:
git reflog
This lists recent changes to the HEAD pointer. Identify the commit hash you want to restore, then create a new branch or reset to it:
git checkout -b recovery-branch
Splitting or Squashing Commits with Interactive Rebase
If you need to split a commit into smaller logical units or combine several commits into one, use an interactive rebase:
git rebase -i HEAD~n
Replace n with the number of commits you want to modify. In practice, in the editor, mark commits with split or squash as needed. This allows granular control over your commit history without rewriting shared commits Less friction, more output..
Cherry-Picking for Selective Changes
When you want to apply a specific commit from another branch without merging the entire branch, use cherry-pick:
git cherry-pick
This creates a new commit with the same changes, preserving the original commit’s integrity in the source branch.
Best Practices for Team Collaboration
- Use Feature Branches: Always work on isolated branches for features or fixes. This minimizes disruptions to the main branch and simplifies reverting or rebasing.
- Avoid Force-Pushing Shared Branches: Never force-push to branches others are using. Instead, communicate with your team before making history changes.
- Review Changes Before Reverting: Use
git showor a diff tool to verify the impact of a commit before reverting or resetting. - put to work Pull Requests for Reverts: When reverting a shared commit (e.g., via a pull request), document the reason for the revert to maintain transparency.
Handling Large-Scale History Changes
For scenarios like removing sensitive data (e.g., passwords, API keys) from all commits, use git filter-repo (recommended over the older git filter-branch):
git filter-repo --replace-text
This tool safely rewrites history and removes specified content. That said, this operation is irreversible and requires all collaborators to re-clone or re-base their work.
Final Thoughts
Git’s flexibility in managing commit history is both a strength and a responsibility. By understanding the distinction between local and shared commits, and by choosing the right tool for the job—whether it’s reset, revert, or rebase—you can maintain a clean, logical project history. Always prioritize collaboration and communication, especially when history rewrites are necessary. With practice, these workflows become second nature, empowering you to manage Git’s complexities with confidence and precision.
Remember: Git is a tool to serve your team’s goals, not a hurdle. Use it wisely, and it will keep your codebase organized and your workflow smooth.