我不小心把一个dvd光盘放到了一个网站项目中,然后不小心提交-a -m…而且,快,回购膨胀了2.2 g。下次我做了一些编辑,删除了视频文件,并提交了所有内容,但压缩文件仍然在存储库中,在历史中。
我知道我可以从这些提交中启动分支,并将一个分支重置到另一个分支上。但是我应该怎么做才能合并两次提交,使大文件不显示在历史记录中,并在垃圾收集过程中被清理?
我不小心把一个dvd光盘放到了一个网站项目中,然后不小心提交-a -m…而且,快,回购膨胀了2.2 g。下次我做了一些编辑,删除了视频文件,并提交了所有内容,但压缩文件仍然在存储库中,在历史中。
我知道我可以从这些提交中启动分支,并将一个分支重置到另一个分支上。但是我应该怎么做才能合并两次提交,使大文件不显示在历史记录中,并在垃圾收集过程中被清理?
当前回答
根据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>
其他回答
使用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倍,而且通常更容易使用。
完全披露:我是好心眼巨人回收清理器的作者。
我用一个bitbucket帐户遇到了这个问题,我不小心在那里存储了我网站的巨大*.jpa备份。
git filter-branch——prune-empty——index-filter 'git rm -rf——cached——ignore-unmatch MY-BIG-DIRECTORY-OR-FILE'——tag-name-filter cat -- --all
用所讨论的文件夹重新安装MY-BIG-DIRECTORY,以完全重写历史记录(包括标记)。
来源:https://web.archive.org/web/20170727144429/http: / / naleid.com: 80 /博客/ 2012/01/17 / finding-and-purging-big-files-from-git-history /
当您遇到这个问题时,git rm是不够的,因为git会记住这个文件在我们的历史中曾经存在过一次,因此会保留对它的引用。
更糟糕的是,重基也不容易,因为任何对blob的引用都会阻止git垃圾收集器清理空间。这包括远程引用和reflog引用。
我把git forget-blob放在一起,一个尝试删除所有这些引用的小脚本,然后使用git filter-branch重写分支中的每个提交。
一旦你的blob完全没有被引用,git gc就会删除它
它的用法很简单,git forget-blob file-to-forget。你可以在这里获得更多信息
https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/
多亏了Stack Overflow和一些博客的回答,我把这些放在了一起。感谢他们!
我基本上按照这个答案做了: https://stackoverflow.com/a/11032521/1286423
(对于历史,我复制粘贴在这里)
$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch YOURFILENAME" HEAD
$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --prune
$ git push origin master --force
这并没有起作用,因为我喜欢重命名和移动东西。一些大文件在重命名的文件夹中,我认为gc不能删除对这些文件的引用因为树对象中的引用指向这些文件。 我最终的解决方法是:
# 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
我的repo (.git)从32MB变成了388KB,即使过滤器分支也无法清理。
这将从你的历史记录中删除它
git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch bigfile.txt' --prune-empty --tag-name-filter cat -- --all