我不小心把一个dvd光盘放到了一个网站项目中,然后不小心提交-a -m…而且,快,回购膨胀了2.2 g。下次我做了一些编辑,删除了视频文件,并提交了所有内容,但压缩文件仍然在存储库中,在历史中。
我知道我可以从这些提交中启动分支,并将一个分支重置到另一个分支上。但是我应该怎么做才能合并两次提交,使大文件不显示在历史记录中,并在垃圾收集过程中被清理?
我不小心把一个dvd光盘放到了一个网站项目中,然后不小心提交-a -m…而且,快,回购膨胀了2.2 g。下次我做了一些编辑,删除了视频文件,并提交了所有内容,但压缩文件仍然在存储库中,在历史中。
我知道我可以从这些提交中启动分支,并将一个分支重置到另一个分支上。但是我应该怎么做才能合并两次提交,使大文件不显示在历史记录中,并在垃圾收集过程中被清理?
当前回答
比git的filter-branch快100倍,更简单
在这个帖子里有很多很好的答案,但同时很多都过时了。不再推荐使用git-filter-branch,因为它很难使用,而且在大型存储库上非常慢。
Git-filter-repo使用起来更快更简单。
git-filter-repo是一个Python脚本,可以在github: https://github.com/newren/git-filter-repo上获得。安装时,它看起来像一个普通的git命令,可以由git filter-repo调用。
您只需要一个文件:Python3脚本git-filter-repo。将其复制到path变量中包含的路径。在Windows上,您可能需要更改脚本的第一行(请参阅INSTALL.md)。您需要在系统上安装Python3,但这不是什么大问题。
首先你可以跑
git filter-repo --analyze
这可以帮助你决定下一步要做什么。
你可以在任何地方删除你的DVD-rip文件:
git filter-repo --invert-paths --path-match DVD-rip
Filter-repo非常快。一个在我的电脑上用filter-branch花了9个小时的任务,用filter-repo只用了4分钟就完成了。你可以用filter-repo做更多的事情。请参阅相关文档。
警告:在存储库的副本上执行此操作。filter-repo的许多操作不能撤消。Filter-repo将更改所有修改过的提交(当然)及其所有后代直到最后一次提交的提交哈希值!
其他回答
你可以使用branch filter命令:
git filter-branch -tree-filter 'rm -rf path/to/your/file' HEAD
根据GitHub文档,只需遵循以下步骤:
去掉大文件
选项1:你不想保留大文件:
rm path/to/your/large/file # delete the large file
选项2:您希望将大文件保存到一个未跟踪的目录中
mkdir large_files # create directory large_files
touch .gitignore # create .gitignore file if needed
'/large_files/' >> .gitignore # untrack directory large_files
mv path/to/your/large/file large_files/ # move the large file into the untracked directory
保存更改
git add path/to/your/large/file # add the deletion to the index
git commit -m 'delete large file' # commit the deletion
从所有提交中删除大文件
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch path/to/your/large/file" \
--prune-empty --tag-name-filter cat -- --all
git push <remote> <branch>
这些命令在我的案例中起作用:
git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch oops.iso' --prune-empty --tag-name-filter cat -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
它与上面的版本没有什么不同。
对于那些需要把这个推到github/bitbucket的人(我只用bitbucket测试了这个):
# WARNING!!!
# this will rewrite completely your bitbucket refs
# will delete all branches that you didn't have in your local
git push --all --prune --force
# Once you pushed, all your teammates need to clone repository again
# git pull will not work
比git的filter-branch快100倍,更简单
在这个帖子里有很多很好的答案,但同时很多都过时了。不再推荐使用git-filter-branch,因为它很难使用,而且在大型存储库上非常慢。
Git-filter-repo使用起来更快更简单。
git-filter-repo是一个Python脚本,可以在github: https://github.com/newren/git-filter-repo上获得。安装时,它看起来像一个普通的git命令,可以由git filter-repo调用。
您只需要一个文件:Python3脚本git-filter-repo。将其复制到path变量中包含的路径。在Windows上,您可能需要更改脚本的第一行(请参阅INSTALL.md)。您需要在系统上安装Python3,但这不是什么大问题。
首先你可以跑
git filter-repo --analyze
这可以帮助你决定下一步要做什么。
你可以在任何地方删除你的DVD-rip文件:
git filter-repo --invert-paths --path-match DVD-rip
Filter-repo非常快。一个在我的电脑上用filter-branch花了9个小时的任务,用filter-repo只用了4分钟就完成了。你可以用filter-repo做更多的事情。请参阅相关文档。
警告:在存储库的副本上执行此操作。filter-repo的许多操作不能撤消。Filter-repo将更改所有修改过的提交(当然)及其所有后代直到最后一次提交的提交哈希值!
使用BFG Repo-Cleaner,这是一个更简单、更快的Git -filter-branch的替代方案,专门用于从Git历史记录中删除不需要的文件。
仔细按照使用说明,核心部分就是这样:
$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-repo.git
任何超过100MB大小的文件(不是最近提交的文件)都将从Git存储库的历史记录中删除。然后你可以使用git gc清除死数据:
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
修剪后,我们可以强制推送到远程repo*
$ git push --force
*注意:不能在GitHub上强制推送一个保护分支
BFG通常比运行git-filter-branch快10-50倍,而且通常更容易使用。
完全披露:我是好心眼巨人回收清理器的作者。