Matthieu Vergne's Homepage

Last update: 06/01/2022 17:50:20

How to Delete a Git Commit with Its Content?

Context

Your branch contains a commit which applies changes that you don't want. It might be some obsolete or irrelevant changes for your branch, and you don't want to build on them anymore.

If instead you want to remove a commit without removing its changes, then you need to squash it with another one.

Question

How to delete a Git commit with its content?

Method

Rewriting a Git history can be done in plenty of ways. Unfortunately, messing it up can be done as well. If you feel unsafe about rewriting the history, give a look here first. Better feel safe than sorry.

If your commit contains changes that you want to keep, first split it to extract those changes into a dedicated commit. You need to ensure that the commit you want to remove contains only changes that you want to remove.

Before to remove the commit, you need to understand that removing some changes modifies the state of your code. Consequently, removing a commit may conflict with the next commits. If you are sure that removing this commit will not produce any conflict, then you can do so in one go:


COMMIT_LAST=$(git rev-parse HEAD)          # Identify the last commit
COMMIT=<commit SHA-1>                      # Identify the commit to remove
git reset --hard ${COMMIT}~1               # Place the branch on the commit before the one to remove
git cherry-pick ${COMMIT}..${COMMIT_LAST}  # Apply the commits after the removed one

If the conflicts do not scare you, you can use the same procedure and resolve the conflicts during the cherry-pick.

If you feel unsafe regarding the conflicts, prefer first to move the commit at the last position. Any conflict will be dealt with during this phase, one at a time. Once your commit is the last one, it is nothing more than a single change on which nothing builds on. Just cut the head of your banch to remove it:


git reset --hard HEAD~1

Answer

Deleting a commit with its content is done by forgetting the history with git reset --hard and reproducing the commits to keep with git cherry-pick. However, conflicts may occur during the picking. To go more iteratively, one can first move the commit at the last position. In this case, git reset --hard suffices to delete the last commit.

Bibliography