Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Completely remove commit from git database [duplicate]

Tags:

git

I need a commit to no longer be in the git database of commits. I need to be able to remove commit abc123... such that git checkout abc123... returns error: pathspec 'abc123...' did not match any file(s) known to git.

The QA Delete commits from a branch in Git answers this partially, as in how to remove references to a commit from the HEAD, but it doesn't cover finding all of the branches a commit is present in nor does it cover expiring and purging the commit once it has been made a dangling commit.

How would I achieve this?

like image 885
Ethan Reesor Avatar asked Jun 30 '12 03:06

Ethan Reesor


People also ask

How do I remove a commit from repository?

To remove the last commit from git, you can simply run git reset --hard HEAD^ If you are removing multiple commits from the top, you can run git reset HEAD~2 to remove the last two commits. You can increase the number to remove even more commits.

How do I use git obliterate?

Usage. Download the file, chmod +x it, and copy it to /usr/local/bin (or somewhere else in your PATH ). Then you can do git obliterate <file> and it will wipe it from history. Singing Cher's “If I Could Turn Back Time” is optional.


2 Answers

  1. List all branches that contain the commit:

    git branch --contains COMMITSHA
    
  2. Remove commit from these branches:

    git checkout BRANCH
    git rebase -i COMMITSHA^
    # delete line with commit and save
    

    If a changed branch is tracked in any remote, push it there with override:

    git push --force REMOTE BRANCH
    

    e.g:

    git push --force origin master
    

    (Note that, depending on your development process, the commit may appear in untracked remote branches as well.)

  3. Purge the commit, so it can not be restored from your local repo:

    git reflog expire --all BRANCH1 BRANCH2 # list all branches you changed
    git prune --expire now
    

    Note that you must also run this command on all remote repositories that had this commit. If you have no access to the remote repo, you have to cross your fingers — commit will eventually expire by itself and will be purged by git gc.

    Be warned that above commands will remove all dangling objects from Git repo and all the history of branch changes — so you wouldn't be able to restore (by non-forensic means) anything lost prior to its run.

  4. Tell all collaborators to fetch changed branches and update any work they might have based on them. They should do as follows:

    git fetch REMOTE      
    

    For each branch that is based on a branch you changed above (including the branch itself if they have it locally):

    git checkout BRANCH
    git rebase REMOTE/BRANCH
    git reflog expire --all BRANCH
    

    After they're done:

    git prune --expire now
    
like image 102
Alexander Gladysh Avatar answered Sep 21 '22 13:09

Alexander Gladysh


  1. Make sure that no refs need that commit (reset back to before it, or rebase it out)
  2. Delete the object from .git/objects (it'll be in a folder named after the first two characters of the hash, and the filename will be the rest of the hash).

Note, however, that if you pushed this commit to a public repository, removing it locally won't remove it from the remote.

like image 39
Amber Avatar answered Sep 22 '22 13:09

Amber