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

时间:2012-06-15 12:02:10

标签: git branching-and-merging pack

我检查了一大堆文件到一个分支并合并,然后不得不删除它们,现在我留下了一个大的.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)来尝试整理包文件,但它们也不会出现在.bash_history文件中。

7 个答案:

答案 0 :(得分:156)

问题是,即使您删除了文件,它们仍然存在于以前的版本中。这就是git的重点,即使你删除了某些东西,你仍然可以通过访问历史记录来恢复它。

您要做的事情称为重写历史记录,它涉及git filter-branch命令。

GitHub在其网站上对此问题有一个很好的解释。 https://help.github.com/articles/remove-sensitive-data

为了更直接地回答您的问题,您基本上需要运行的是unwanted_folename_or_folder替换此命令:

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

这将从存储库的活动历史记录中删除对文件的所有引用。

接下来,执行GC循环以强制对文件的所有引用都过期并从packfile中清除。在这些命令中不需要替换任何内容。

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

答案 1 :(得分:6)

一个选项:

手动运行git gc以将多个包文件压缩为一个或几个包文件。 此操作是持久的(即大包文件将保留其压缩行为),因此使用git gc --aggressive定期压缩存储库可能是有益的

另一种选择是将代码和.git保存在某处,然后删除.git并使用此现有代码重新启动,创建一个新的git存储库(git init)。

答案 2 :(得分:5)

方案A :如果您的大型文件仅添加到分支机构,则无需运行git filter-branch。您只需要删除分支并运行垃圾收集:

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

方案B :但是,根据您的bash历史记录,您确实将更改合并到master中。如果您尚未与任何人分享更改(尚未git push)。最简单的方法是将master重新设置为与具有大文件的分支合并之前。这将消除分支中的所有提交以及合并后对master进行的所有提交。因此,您可能会失去更改 - 除了大文件 - 您可能真正想要的更改:

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

然后运行方案A中的步骤。

方案C :如果您希望保留合并后,主服务器上的分支发生了其他更改,则最好将主服务器和选择性服务器进行更改包括你想要的提交:

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

在编辑器中,删除与添加大文件的提交相对应的行,但保留其他所有内容。保存并退出。您的主分支应该只包含您想要的内容,而不包含大文件。请注意,git rebase没有-p将会消除合并提交,因此您将在<commit hash>之后留下母版的线性历史记录。这可能对您有好处,但如果没有,您可以尝试-p,但git help rebasecombining -p with the -i option explicitly is generally not a good idea unless you know what you are doing

然后运行方案A中的命令。

答案 3 :(得分:2)

正如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),如下所示:

从历史记录中删除所有大于100M的文件:

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

重要!

运行BFG时,请注意YOUR_FILE_NAMEYOUR_FOLDER_NAME确实只是文件/文件夹名称。 他们不是路径 ,所以foo/bar.jpg之类的东西不起作用!相反,所有具有指定名称的文件/文件夹都将从回购历史记录中删除,无论它们存在哪个路径或分支。

答案 4 :(得分:1)

我对节目有点迟,但如果上述答案没有解决问题,那么我找到了另一种方式。只需从.pack中删除特定的大文件即可。我有这个问题,我偶然检查了一个2GB的大文件。我按照此链接中说明的步骤进行操作:http://www.ducea.com/2012/02/07/howto-completely-remove-a-file-from-git-history/

答案 5 :(得分:0)

运行以下命令,将PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA替换为要删除文件的路径,而不仅仅是文件名。这些参数将:

  1. 强制Git处理但不检出每个分支和标签的全部历史记录
  2. 删除指定文件以及由此产生的所有空提交
  3. 覆盖现有标签
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

答案 6 :(得分:-3)

与编码相比,这更是一种方便的解决方案。压缩文件。以文件视图格式打开zip(与解压缩不同)。删除.pack文件。解压缩并替换文件夹。奇迹般有效!