How to Remove Commits from A Git Commit History

Updated on 18 July, 2025
Learn how to remove, recover, or rewrite Git commits safely using reset, rebase, reflog, and filter-repo.
How to Remove Commits from A Git Commit History header image

Occasionally, you may push unwanted changes or sensitive data to a Git repository, whether local or remote. Git provides flexible tools to rewrite commit history, allowing you to remove sensitive information, undo mistakes, and clean up your commit log. This article demonstrates how to remove commits from your Git history using safe and effective techniques for both local and shared repositories.

The Short Answer Version

# View Git commit history (compact)
$ git log --oneline

# Remove the most recent commit (discard changes)
$ git reset --hard HEAD~1

# Remove a specific commit (interactive rebase)
$ git rebase -i HEAD~N

# Recover a removed commit using reflog
$ git reflog
$ git reset --hard HEAD@{n}

# Permanently remove a file or directory from all commits (recommended)
$ git filter-repo --path <path> --invert-paths

View Git Commit History

You can view the commit history in Git either in a compact single-line format or a detailed full log. This helps you inspect previous commits and decide which ones to remove or recover.

Command Syntax

git log [OPTIONS]
  • git log: Displays the full commit history with commit hashes, author, date, and commit message.
  • [OPTIONS]
    • --oneline: Condenses each commit to a single line showing the commit hash and commit message.

Command Demonstration

  • View compact commit history.

    console
    $ git log --oneline
    

    Output:

    e2369629 (HEAD -> main, origin/main, origin/HEAD) removed requirement.txt file
    2e39f29b Used Poetry for dependency management
    2f7490ae modularized my code
    de4c0fb8 Updated the ReadME file
    39b41a37 Concluded unit testing
    1acecd8c minor
    5a1f681e Added a dockerfile, updated the readme and added a requirements.txt file
    97c43fa3 remove comm.md
    1f20c89f first commit
  • View detailed commit history.

    console
    $ git log
    

    Output:

    commit e23696290557c029add5490d81bb305dc506f61c (HEAD -> main, origin/main, origin/HEAD)
    Author: johndoe <johndoe@gmail.com>
    Date:   Sun Sep 1 20:03:36 2024 +0100
    
        removed requirement.txt file
    
    commit 2e39f29b49447219bc32a7fbdd6e8a5834b83911
    Author: johndoe <johndoe@gmail.com>
    Date:   Sun Sep 1 20:00:50 2024 +0100
    
        Used Poetry for dependency management

    Use the arrow keys to scroll through the log and press q to quit the view.

Remove the Most Recent Commit

Use the git reset command to undo your most recent commit by moving HEAD backward. You can choose whether to keep, unstage, or discard your changes depending on the reset mode you use.

Command Syntax

git reset [--soft | --mixed | --hard] HEAD~N
  • --soft: Keep changes staged.
  • --mixed: Unstage changes, leave them in working directory (default).
  • --hard: Discard all changes (permanently resets working directory and index).
  • HEAD~N: Moves HEAD back by N commits (e.g., HEAD~1 targets the last commit).

Command Demonstration

  • Keep changes staged.

    console
    $ git reset --soft HEAD~1
    
  • Unstage changes.

    console
    $ git reset --mixed HEAD~1
    
  • Discard changes entirely.

    console
    $ git reset --hard HEAD~1
    

Remove a Specific Commit History

To remove a specific commit that is not the most recent one, use an interactive rebase. This allows you to review a range of recent commits and selectively remove (drop) individual ones.

Command Syntax

git rebase -i HEAD~N
  • git rebase -i: Starts an interactive rebase.
  • HEAD~N: Specifies how many commits before HEAD to display for editing (for example, HEAD~8 shows the last 8 commits).

Command Breakdown

  • The command opens an editor listing the commits in the range.
  • You can choose to drop any commit you want to remove.
  • Git will rewrite your history accordingly.

Command Demonstration

  1. Start an interactive rebase to edit the last 8 commits.

    console
    $ git rebase -i HEAD~8
    

    Output.

    pick 5fce205e Enhanced the ReadMe
    pick 8404786f minor
    pick f5879bb9 minor
    pick c26abc6b minor
    pick b1db91c2 minor
    pick f18e3944 minor
    pick ba58ebeb Used Poetry for dependency management
    pick 8169d159 removed requirement.txt file
  2. In the editor:

    • Press i to enter insert mode.
    • Change pick to drop for the commit you want to remove:
    drop 8169d159 removed requirement.txt file
  3. To save:

    • Press Esc to exit insert mode.
    • Type :wq and press Enter.

    Git will process the rebase:

    Successfully rebased and updated refs/heads/main.

Recover a Removed Commit

If you accidentally remove a commit using git reset or git rebase, you can often recover it using the git reflog command. The reflog records where your HEAD and branch pointers have been, even after destructive changes.

However, recovery depends on:

  • How soon you attempt to recover the commit (reflog entries eventually expire).
  • How the commit was removed (soft, mixed, or hard reset).

Recovery Guidelines

  • If you performed a hard reset, use:

    git reset --hard HEAD@{n}   # or git reset --hard <commit-hash>
  • If you performed a mixed reset, use:

    git reset --mixed HEAD@{n}  # or git reset HEAD@{n} or git reset --mixed <commit-hash>
  • If you performed a soft reset, use:

    git reset --soft HEAD@{n}   # or git reset --soft <commit-hash>

Command Demonstration

View the Reflog

First, display your reflog to locate the commit you want to recover.

console
$ git reflog

Output.

7a9a8b2f (HEAD -> main) HEAD@{0}: rebase (finish): returning to refs/heads/main
7a9a8b2f (HEAD -> main) HEAD@{1}: rebase (pick): Used Poetry for dependency management
59c2d68e HEAD@{2}: rebase (start): checkout HEAD~8
8dbe3b9a HEAD@{3}: reset: moving to HEAD~1
  • HEAD@{0}: Current HEAD.
  • HEAD@{1}, HEAD@{2}: Prior reflog entries.
  • HEAD@{3}: Entry representing the state before the hard reset.

You can also preview a reflog entry before recovering:

console
$ git show HEAD@{3}

Recover Using a Reflog Entry

To reset your branch to a prior reflog state:

console
$ git reset --hard HEAD@{3}

Output.

HEAD is now at 8dbe3b9a Used Poetry for dependency management

Recover Using a Commit Hash

Alternatively, you can reset using the exact commit hash.

console
$ git reset --hard 8dbe3b9a

You can preview it first:

console
$ git show 8dbe3b9a

Remove a File or Directory from Commit History

In Git, you can remove a file or directory from future commits using:

console
$ git rm --cached <path-to-file>
$ git rm -r --cached <path-to-directory>

However, this does not erase the file or directory from your commit history, it only prevents it from appearing in future commits. To permanently remove a file or directory from all commits in your repository history, you must rewrite your commit history.

Use git filter-repo

git filter-repo is the modern replacement for git filter-branch. It is faster, safer, and more reliable for permanently removing files or directories from commit history. It is not included with Git by default but can be installed as a plugin.

Command Demonstration

  1. Install git filter-repo.

    console
    $ pip3 install git-filter-repo
    
  2. Back up your repository.

    console
    $ cp -r <your-repository-name> <your-repository-name-backup>
    
  3. Remove a file from history.

    console
    $ git filter-repo --path <path-to-file> --invert-paths
    
  4. Verify the file is gone.

    console
    $ git log --all -- <path-to-file>
    

    No output indicates success.

  5. Remove a directory from history.

    console
    $ git filter-repo --path <path-to-directory> --invert-paths
    
  6. Verify the directory is gone.

    console
    $ git log --all -- <path-to-directory>
    

    No output indicates success.

Conclusion

In this article, you explored multiple ways to remove commits from a Git commit history. You learned how to safely undo recent commits with git reset, remove specific commits using interactive rebase, and permanently rewrite history with tools like git filter-repo. You also saw how to recover removed commits using git reflog.

When working with shared repositories, always prefer git revert to create a new commit that undoes changes without altering history. Rewriting commit history should be used with caution, especially on branches that have already been pushed and shared with others.

Tags:

Comments

No comments yet.