Delete commits before date

One thing that has come up at work is the size and speed of our git repository. It is over 4GB with more than 15,700 commits and just under 46,000 files. This makes things very slow. It has also made cloning the repository physically impossible as the server runs out of memory about 60% of the way through (I tried continuously between 22:00 and 1:00 last night/this morning). As such it has been decided that this needs to be corrected.

One thing was that we used to keep many SVGs and Adobe Illustrator files in our history. We could remove these and free up half the repository, but do we really need all our history since the beginning of this repo? The answer was no, in fact, we don't need anything older than 3 months. We plan to split the repo apart to effectively give each team a different repo to work in, thereby avoiding problems with merges similar to those that have destroyed work in the past.

The question is how to get rid of these commits? There are a lot of resources for doing this, including a great Stack Overflow post and a very handy tip on Code Project, and in the Git docs themselves. At first I sought to remove the offending images folder from the history separately from the date based removal, but this was not necessary because before 3 months ago this was already removed from the repository. As such I merely needed to delete everything before 3 months ago. Things were a bit tricky though, because of the way git filter-branch behaved with regards to variables in the shell. Ultimately I ended up with the solution below for cleaning out the history. This is not the whole solution, after this it is necessary to repack and forcibly push to the server. This is a destructive operation, so everyone with a copy will likely need to download the repository again, or you risk the old stuff coming back. The code below is for a Mac, so certain parameters may need to change.

  git filter-branch --commit-filter '\
  commitDate=$(echo "$GIT_COMMITTER_DATE" | cut -d " " -f 1 | cut -d "@" -f 2);\
  oldDate=$(date -v-3m -v0H -v0M -v0S "+%s");\
  if [ $commitDate -lt $oldDate ];\
    skip_commit "$@";\
    git commit-tree "$@";\
  fi' -- --all
Show Comments