我不小心把一个dvd光盘放到了一个网站项目中,然后不小心提交-a -m…而且,快,回购膨胀了2.2 g。下次我做了一些编辑,删除了视频文件,并提交了所有内容,但压缩文件仍然在存储库中,在历史中。
我知道我可以从这些提交中启动分支,并将一个分支重置到另一个分支上。但是我应该怎么做才能合并两次提交,使大文件不显示在历史记录中,并在垃圾收集过程中被清理?
我不小心把一个dvd光盘放到了一个网站项目中,然后不小心提交-a -m…而且,快,回购膨胀了2.2 g。下次我做了一些编辑,删除了视频文件,并提交了所有内容,但压缩文件仍然在存储库中,在历史中。
我知道我可以从这些提交中启动分支,并将一个分支重置到另一个分支上。但是我应该怎么做才能合并两次提交,使大文件不显示在历史记录中,并在垃圾收集过程中被清理?
当前回答
这将从你的历史记录中删除它
git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch bigfile.txt' --prune-empty --tag-name-filter cat -- --all
其他回答
为什么不使用这个简单而强大的命令呢?
git filter-branch --tree-filter 'rm -f DVD-rip' HEAD
——tree-filter选项在项目每次签出后运行指定的命令,然后重新提交结果。在这种情况下,您从每个快照中删除一个名为DVD-rip的文件,无论它是否存在。
如果你知道是哪个提交引入了这个巨大的文件(比如35dsa2),你可以用35dsa2替换HEAD。HEAD以避免重写太多的历史,从而避免在还没有推送的情况下出现不同的提交。@alpha_989提供的这个评论似乎太重要了,不能在这里省略。
请看这个链接。
除了git filter-branch(缓慢但纯粹的git解决方案)和BFG(更简单,性能非常好)之外,还有另一个性能良好的过滤工具:
https://github.com/xoofx/git-rocket-filter
从它的描述来看:
git-rocket-filter的目的类似于git-filter-branch命令,但提供了以下独特的功能:
快速重写提交和树(从x10到x100的顺序)。 内置支持使用——keep(保存文件或目录)的白名单和使用——remove选项的黑名单。 使用.gitignore类似的模式进行树过滤 快速和简单的c#脚本提交过滤和树过滤 支持每个文件/目录模式的树过滤脚本 自动修剪空的/不变的提交,包括合并提交
使用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倍,而且通常更容易使用。
完全披露:我是好心眼巨人回收清理器的作者。
根据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 reset --soft HEAD~1
它将保留更改,但删除提交,然后您可以重新提交这些更改。