How do I remove the old history from a git repository?
I'm afraid I couldn't find anything quite like this particular scenario.
I have a git repository with a lot of history: 500+ branches, 500+ tags, going back to mid-2007. It contains ~19,500 commits. We'd like to remove all of the history before Jan 1, 2010, to make it smaller and easier to deal with (we would keep a complete copy of the history in an archive repository).
I know the commit that I want to have become the root of the new repository. I can't, however, figure out the correct git mojo to truncate the repo to start with that commit. I'm guessing some variant of
git filter-branch
involving grafts would be necessary; it might also be necessary to treat each of the 200+ branches we want to keep separately and then patch the repo back together (something I do know how to do).
Has anyone ever done something like this? I've got git 1.7.2.3 if that matters.
Solution 1:
Maybe it's too late to post a reply, but as this page is the first Google's result, it may still be helpful.
If you want to free some space in your git repo, but do not want to rebuild all your commits (rebase or graft), and still be able to push/pull/merge from people who has the full repo, you may use the git clone shallow clone (--depth parameter).
; Clone the original repo into limitedRepo
git clone file:///path_to/originalRepo limitedRepo --depth=10
; Remove the original repo, to free up some space
rm -rf originalRepo
cd limitedRepo
git remote rm origin
You may be able to shallow your existing repo, by following these steps:
; Shallow to last 5 commits
git rev-parse HEAD~5 > .git/shallow
; Manually remove all other branches, tags and remotes that refers to old commits
; Prune unreachable objects
git fsck --unreachable ; Will show you the list of what will be deleted
git gc --prune=now ; Will actually delete your data
How to remove all git local tags?
Ps: Older versions of git didn't support clone/push/pull from/to shallow repos.
Solution 2:
You can create a graft of the parent of your new root commit to no parent (or to an empty commit, e.g. the real root commit of your repository). E.g. echo "<NEW-ROOT-SHA1>" > .git/info/grafts
After creating the graft, it takes effect right away; you should be able to look at git log
and see that the unwanted old commits have gone away:
$ echo 4a46bc886318679d8b15e05aea40b83ff6c3bd47 > .git/info/grafts
$ git log --decorate | tail --lines=11
commit cb3da2d4d8c3378919844b29e815bfd5fdc0210c
Author: Your Name <[email protected]>
Date: Fri May 24 14:04:10 2013 +0200
Another message
commit 4a46bc886318679d8b15e05aea40b83ff6c3bd47 (grafted)
Author: Your Name <[email protected]>
Date: Thu May 23 22:27:48 2013 +0200
Some message
If all looks as intended, you can utilize git filter-branch -- --all
to make it permanent.
BEWARE: after doing the filter-branch step, all commit ids will have changed, so anybody using the old repo must never merge with anyone using the new repo.