Last active
August 29, 2015 14:13
-
-
Save jarthod/77be79746dda9b1542f3 to your computer and use it in GitHub Desktop.
Ruby script to cleanup large files from your git repository
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Ruby shows you the largest objects in your git repo's pack file & offers you to remove them automatically | |
# Based on http://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/ by Antony Stubbs | |
# Use this to fetch all branches locally first: | |
# for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do | |
# git branch --track ${branch##*/} $branch | |
# done | |
require 'shellwords' | |
# list all objects including their size, sort by size, take top 20 | |
puts " > Listing objects" | |
objects = `git verify-pack -v .git/objects/pack/pack-*.idx | grep -Ev "non delta|chain length|git/objects" | tr -s " " | sort -k3gr | head -n 20`.lines.map(&:chomp) | |
puts " > Building file index" | |
files = Hash[`git rev-list --all --objects`.lines.map {|l| l.chomp.split(' ', 2)}] | |
to_remove = [] | |
puts " > largest files:" | |
objects.each do |object| | |
sha, _, size, compressedSize = object.split(' ') | |
file = files[sha] | |
exists = File.file?(file) | |
puts " %5d kB (compressed: %5d kB) - %s%s" % [size.to_i/1024, compressedSize.to_i/1024, file, ("*" if exists)] | |
to_remove << file unless exists | |
end | |
print " > do you want to remove these #{to_remove.size} files (not present in current branch)? (y/N): " | |
if gets.chomp == 'y' | |
files = to_remove.map {|f| Shellwords.escape(f)}.join(' ') | |
cmd = "git filter-branch --tag-name-filter cat --index-filter 'git rm -r --cached --ignore-unmatch #{files}' --prune-empty -f -- --all" | |
puts " > #{cmd}" | |
system cmd | |
cmd = "rm -rf .git/refs/original && git reflog expire --expire=now --all && git gc --aggressive --prune=now" | |
puts " > #{cmd}" | |
system cmd | |
puts " > now you need to 'git push origin --force --all && git push origin --force --tags'" | |
puts " > and tell your teammates to 'git rebase'" | |
else | |
puts ' > ok, bye.' | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment