删除由git创建的大.pack文件

lyr7nygr  于 2022-11-27  发布在  Git
关注(0)|答案(8)|浏览(628)

我签入了一个分支和合并的文件负载,然后不得不删除它们,现在我留下了一个大的.pack文件,我不知道如何摆脱.
我删除了所有使用git rm -rf xxxxxx的文件,我还运行了--cached选项。
有人能告诉我如何删除当前位于以下目录中的大型.pack文件吗:
.git/objects/pack/pack-xxxxxxxxxxxxxxxxx.pack
我是否只需要删除我仍然拥有但不再使用的分支?或者我是否需要运行其他东西?
我不知道有多大的区别,但它显示了一个挂锁对文件。
谢谢
编辑
以下是我的bash_history的一些摘录,应该给予你了解我是如何进入这种状态的(假设我现在正在一个名为'my-branch'的git分支上工作,并且我有一个包含更多文件夹/文件的文件夹):

git add .
git commit -m "Adding my branch changes to master"
git checkout master
git merge my-branch
git rm -rf unwanted_folder/
rm -rf unwanted_folder/     (not sure why I ran this as well but I did)

我想我也运行了以下代码,但它没有与其他代码一起出现在bash_history中:

git rm -rf --cached unwanted_folder/

我还以为我运行了一些git命令(比如git gc)来整理pack文件,但它们也没有出现在.bash_history文件中。

bmp9r5qi

bmp9r5qi1#

问题是,即使你删除了文件,它们仍然存在于之前的版本中。这就是git的意义所在,即使你删除了某个文件,你仍然可以通过访问历史记录来恢复它。
您要执行的操作称为重写历史,它涉及到git filter-branch命令。
GitHub在他们的网站上对这个问题有很好的解释。https://help.github.com/articles/remove-sensitive-data
为了更直接地回答您的问题,您基本上需要运行以下命令,并相应地替换unwanted_filename_or_folder

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch unwanted_filename_or_folder' --prune-empty

这将从存储库的活动历史记录中删除对文件的所有引用。
下一步,执行GC循环以强制所有对文件的引用过期并从包文件中清除。这些命令中不需要替换任何内容。

git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
# or, for older git versions (e.g. 1.8.3.1) which don't support --stdin
# git update-ref $(git for-each-ref --format='delete %(refname)' refs/original)
git reflog expire --expire=now --all
git gc --aggressive --prune=now
ep6jt1vc

ep6jt1vc2#

方案A:如果你的大文件只被添加到一个分支,你不需要运行git filter-branch,你只需要删除分支并运行垃圾收集:

git branch -D mybranch
git reflog expire --expire-unreachable=all --all
git gc --prune=all

方案B:不过,看起来根据你的bash历史记录,您已将更改合并到主控形状中。如果您尚未与任何人共享更改(还没有git push)。最简单的方法是将master重置回合并之前的分支。这将消除合并后分支中的所有提交以及对master的所有提交。因此您可能会丢失更改--除了大文件之外--你可能真的需要:

git checkout master
git log # Find the commit hash just before the merge
git reset --hard <commit hash>

然后运行场景A中的步骤。

方案C:如果在合并之后,分支中还有其他的修改或者master上的修改,那么最好重定master的基,并选择性地包含你想要的提交:

git checkout master
git log # Find the commit hash just before the merge
git rebase -i <commit hash>

在你的编辑器中,删除对应于添加了大文件的提交的行,但保留其他所有内容。保存并退出。你的master分支应该只包含你想要的内容,而不包含大文件。注意,git rebase不包含-p将消除合并提交,所以你会在<commit hash>之后留下master的线性历史记录。这对你来说可能没问题。但如果不是,可以尝试使用-p,但git help rebase表示combining -p with the -i option explicitly is generally not a good idea unless you know what you are doing
然后运行方案A中的命令。

lg40wkob

lg40wkob3#

运行以下命令,用要删除的文件的路径替换PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA,而不仅仅是文件名。这些参数将:
1.强制Git处理但不 checkout 每个分支和标签的整个历史记录
1.删除指定的文件以及由此生成的任何空提交
1.覆盖现有标记

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" --prune-empty --tag-name-filter cat -- --all

这将从存储库的活动历史记录中强制删除对文件的所有引用。
下一步,执行GC循环,强制所有对文件的引用过期并从包文件中清除。这些命令中不需要替换任何内容。

git update-ref -d refs/original/refs/remotes/origin/master
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --aggressive --prune=now
rjee0c15

rjee0c154#

正如loganfsmyth在他的answer中所说的,你需要清除git历史记录,因为即使从repo中删除了这些文件,它们仍然存在。官方GitHub文档recommend BFG,我发现它比filter-branch更容易使用:

从历史记录中删除文件

Download BFG从他们的网站。确保你已经安装了java,然后创建一个镜像克隆并清除历史记录。确保用你想删除的文件名替换YOUR_FILE_NAME

git clone --mirror git://example.com/some-big-repo.git
java -jar bfg.jar --delete-files YOUR_FILE_NAME some-big-repo.git
cd some-big-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push

删除文件夹

同上,但使用--delete-folders

java -jar bfg.jar --delete-folders YOUR_FOLDER_NAME some-big-repo.git

其他选项

BFG还允许更花哨的选项(请参阅docs),如下所示:
从历史记录中删除所有大于100 M的文件:

java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git

重要!

运行BFG时,请注意YOUR_FILE_NAMEYOUR_FOLDER_NAME实际上只是文件/文件夹名称。它们不是路径,因此类似foo/bar.jpg的内容将不起作用!相反,所有具有指定名称的文件/文件夹将从存储库历史记录中删除,无论它们存在于哪个路径或分支。

ha5z0ras

ha5z0ras5#

一个选项:
手动运行git gc将多个包文件压缩为一个或几个包文件。此操作是永久性的(即大型包文件将保留其压缩行为),因此使用git gc --aggressive定期压缩资料档案库可能会有所帮助
另一种选择是将代码和.git保存到某个地方,然后删除.git,并使用现有代码重新开始,创建一个新的git仓库(git init)。

pb3s4cty

pb3s4cty6#

我有点晚了,但如果上面的答案没有解决这个问题,那么我找到了另一种方法。简单地从. pack中删除特定的大文件。我遇到了这个问题,我不小心签入了一个2GB的大文件。我按照以下链接中解释的步骤操作:http://www.ducea.com/2012/02/07/howto-completely-remove-a-file-from-git-history/

7vux5j2d

7vux5j2d7#

这里使用的是BFG as recommended by GitHub,与@Timo的答案相同,但略有不同,因为我花了一些时间查看CLI选项。
假设我在沿着以前推送了超过60MB的图像,并且我无法真正撤销提交。

java -jar /jarfiles/bfg-1.14.0.jar --delete-files '*.{png,jpg,JPG,PNG}'

然后,我会得到一个建议,建议我应该运行以下命令,我将这样做

git reflog expire --expire=now --all && git gc --prune=now --aggressive

最后,将更改同步到远程

git push --force

您可以验证包文件大小是否随着

du -sh ./
oxiaedzo

oxiaedzo8#

这是一个比编码更方便的解决方案。2压缩文件。3以文件视图格式打开压缩文件(与解压缩不同)。4删除.pack文件。5解压缩并替换文件夹。6工作起来很有魅力!

相关问题