我不小心把一个dvd光盘放到了一个网站项目中,然后不小心提交-a -m…而且,快,回购膨胀了2.2 g。下次我做了一些编辑,删除了视频文件,并提交了所有内容,但压缩文件仍然在存储库中,在历史中。

我知道我可以从这些提交中启动分支,并将一个分支重置到另一个分支上。但是我应该怎么做才能合并两次提交,使大文件不显示在历史记录中,并在垃圾收集过程中被清理?


当前回答

在尝试了SO中的几乎所有答案后,我终于找到了这个gem,它可以快速删除我的存储库中的大文件,并允许我再次同步:http://www.zyxware.com/articles/4027/how-to-delete-files-permanently-from-your-local-and-remote-git-repositories

CD到本地工作文件夹,执行以下命令:

git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch FOLDERNAME" -- --all

将FOLDERNAME替换为你想从给定的git存储库中删除的文件或文件夹。

一旦完成,运行以下命令清理本地存储库:

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

现在将所有更改推到远程存储库:

git push --all --force

这将清理远程存储库。

其他回答

当您遇到这个问题时,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和一些博客的回答,我把这些放在了一起。感谢他们!

git reset --soft HEAD~1

它将保留更改,但删除提交,然后您可以重新提交这些更改。

根据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>

新的答案在20222年有效。

请勿使用:

git filter-branch

此命令可能不会在按下后更改远程回购。如果你在使用它后进行克隆,你会看到什么都没有改变,回购仍然有一个很大的大小。这个命令现在已经过时了。例如,如果您使用https://github.com/18F/C2/issues/439中的步骤,这将不起作用。

你需要使用

git filter-repo

步骤:

(1)找到。git中最大的文件:

git rev-list --objects --all | grep -f <(git verify-pack -v  .git/objects/pack/*.idx| sort -k 3 -n | cut -f 1 -d " " | tail -10)

(2)开始过滤这些大文件:

 git filter-repo --path-glob '../../src/../..' --invert-paths --force

or

 git filter-repo --path-glob '*.zip' --invert-paths --force

or

 git filter-repo --path-glob '*.a' --invert-paths --force

或 无论你在第一步中找到什么。

(3)

 git remote add origin git@github.com:.../...git

(4)

git push --all --force

git push --tags --force

完成了! !

这些命令在我的案例中起作用:

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