git clone [remote_path_to_repo] repo_cleanup
cd repo_cleanup
# Ensure my local checkout is complete..
git lfs fetch all
# Dry run of looking for all file types above 10MB
git lfs migrate info --above=10MB --everything
# Migrate & rewrite local history
git lfs migrate import --above=10MB --everything
# Force-push to overwrite remote history
# This will break compatibility with all existing checkouts!
# Ensure you first coordinate with all other developers to make fresh checkouts.
git push -f --mirror
# Do it in a new testing branch
$ git checkout -b test
# Remove file-name from every commit on the new branch
# --index-filter, rewrite index without checking out
# --cached, remove it from index but not include working tree
# --ignore-unmatch, ignore if files to be removed are absent in a commit
# HEAD, execute the specified command for each commit reached from HEAD by parent link
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch file-name' HEAD
# The output is OK, reset it to the prior branch master
$ git checkout master
$ git reset --soft test
# Remove test branch
$ git branch -d test
# Push it with force
$ git push --force origin master
它不起作用,因为我喜欢重命名和移动很多东西。所以一些大文件位于已重命名的文件夹中,我认为 gc 无法删除对这些文件的引用,因为 tree 指向这些文件的对象中有引用。我真正杀死它的最终解决方案是:
# First, apply what's in the answer linked in the front
# and before doing the gc --prune --aggressive, do:
# Go back at the origin of the repository
git checkout -b newinit <sha1 of first commit>
# Create a parallel initial commit
git commit --amend
# go back on the master branch that has big file
# still referenced in history, even though
# we thought we removed them.
git checkout master
# rebase on the newinit created earlier. By reapply patches,
# it will really forget about the references to hidden big files.
git rebase newinit
# Do the previous part (checkout + rebase) for each branch
# still connected to the original initial commit,
# so we remove all the references.
# Remove the .git/logs folder, also containing references
# to commits that could make git gc not remove them.
rm -rf .git/logs/
# Then you can do a garbage collection,
# and the hidden files really will get gc'ed
git gc --prune --aggressive