In my personal git repo, I have a directory that contains thousands of small images that are no longer needed. Is there a way to delete them from the entire git history? I h
The ProGit book has an interesting section on Removing Object.
It does end with this:
Your history no longer contains a reference to that file.
However, yourreflog
and a new set of refs that Git added when you did thefilter-branch
under.git/refs/original
still do, so you have to remove them and then repack the database. You need to get rid of anything that has a pointer to those old commits before you repack:
$ rm -Rf .git/refs/original
$ rm -Rf .git/logs/
$ git gc
$ git prune --expire
(git prune --expire
is not mandatory but can remove the directory content from the loose objects)
Backup everything before doing those commands, just in case ;)
Actually none of these techniques workedfor me. I found the most reliable was was to simply pull locally into another repo:
git pull file://$(pwd)/myGitRepo
It also saves you the hassle of deletig old tags.
see the story on my blog: http://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/
Brandon Thomson asked in a comment to Rainer Blome's solution if this just fixed the gitk view or if the refs will be really gone. A good way to check this is to remember one of the sha1 hashes (or a unique prefix of it) of the old commits and try
$ git ls-tree hash-value
This should show you the content of the repos main folder as it was in this commit. After
$ rm -Rf .git/refs/original
$ rm -Rf .git/logs/
as shown by VonC and removing the refs/original/…
lines from .git/info/refs
and .git/packed-refs
as shown by Rainer Blome, a final
$ git gc --prune=now
made not only the refs, but also the old objects (commits, trees, and blobs) go away. The above shown git ls-tree hash-value
proves this.
Another nice command to check this is git count-objects -v
(run it before the filter-brach and after the pruning and compare the size).
Note: As I'm not allowed yet to comment on the other answers, I had to write a new one although it mainly combines previous given answers.
If you want to go the manual cleanup route, there are some more files that may also contain a ref to the position of your original branch before the git-filter-branch. For example, I filtered my "home" branch:
.git/info/refs:
179ad3e725816234a7182476825862e28752746d refs/original/refs/heads/home
.git/packed-refs:
179ad3e725816234a7182476825862e28752746d refs/original/refs/heads/home
After I removed those lines, gitk did not show the old commits any more.
As this is an old question, perhaps some of this wasn't possible back then. This also assumes you're using bash or cygwin.
Warning: The second and third lines will permanently delete all commits unreachable from your branches/tags.
After running filter-branch
, do
for ref in $(git for-each-ref --format='%(refname)' refs/original); do git update-ref -d $ref; done
git reflog expire --expire=now --all
git gc --prune=now
git for-each-ref --format='%(refname)'
gets the reference names, and git update-ref -d
deletes the reference. It is generally better not to modify the .git
folder directly, and in particular this command handles the case when the refs are in packed-refs
.
The second and third lines are taken directly from How to clean up unused side-branches in your commit trees?.
git-filter-branch by default saves old refs in refs/original/*
namespace.
You need to delete them, and then do git gc --prune=now