2010-01-29 134 views
70

(解决了,看到问题体的底部)
寻找这个现在很长一段时间,我有什么到现在是:删除文件(历史)

几乎相同的方法,但他们都留在包文件中的对象...卡住了。
我的尝试:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_name' 
rm -Rf .git/refs/original 
rm -Rf .git/logs/ 
git gc 

还有在包文件,这是我怎么知道的:

git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3 

这:

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch file_name" HEAD 
rm -rf .git/refs/original/ && git reflog expire --all && git gc --aggressive --prune 

同...

试过git clone诀窍,它删除了一些文件(〜其中3000),但最大的文件仍然存在...

我有一些在存储库中的大型遗留文件,〜200M,我真的不希望他们在那里......而且我不想库重置为0 :(

SOLUTION: 这是摆脱了文件的最短途径:

  1. 检查的.git /填充裁判 - 我的问题是,我有没有refs/remotes/origin/master线对于远程仓库,删除它,否则git将不会删除这些文件
  2. (o ptional)git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5 - 检查最大文件
  3. (可选)git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98 - 要检查那些是什么文件
  4. git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names' - 从所有版本
  5. rm -rf .git/refs/original/删除文件 - 删除Git的备份
  6. git reflog expire --all --expire='0 days' - 到期的所有松动物体
  7. git fsck --full --unreachable - 检查是否有任何松动的对象
  8. git repack -A -d - 重新包装
  9. git prune - 终于去掉这些对象
+5

Soooo,你的问题是......? – zneak 2010-01-29 19:31:05

+0

可能的重复项:http://stackoverflow.com/questions/2100907/how-to-purge-a-huge-file-from-commits-history-in-git/2158271 http://stackoverflow.com/questions/872565/how-do-i-remove-sensitive-files-from-gits-history – 2010-01-29 20:58:14

+0

zneak - 我的问题在标题中。 gbacon - 试过这些,这些文件仍然保留在包文件中... – Devenv 2010-01-29 22:52:16

回答

59

我不能肯定地说没有访问您的库数据,但我相信有在运行git filter-branch之前,可能还有一个或多个打包引用依然引用旧的提交。这可以解释为什么git fsck --full --unreachable不会将大blob称为无法访问的对象,即使您已经过期了reflog并删除了原始(未打包)的引用。

这是我会怎么做(git filter-branchgit gc已经完成后):

1)确认原裁判都不见了:

rm -rf .git/refs/original

2)过期的所有引用日志条目:

git reflog expire --all --expire='0 days'

3)检查旧包装的裁判

这可能会非常棘手,这取决于你有多少打包裁判有。我不知道任何Git命令会自动执行此操作,因此我认为您必须手动执行此操作。备份.git/packed-refs。现在编辑.git/packed-refs。检查旧的参考(特别是,看它是否包装从.git/refs/original任何参考)。如果您发现任何不需要在那里的旧的,删除它们(删除该参考线)。

在完成清理packed-refs文件,看是否git fsck注意到无法访问的对象:

git fsck --full --unreachable

是否奏效,以及git fsck现在报告你的大斑点为不可达,你可以移动到下一步。

4)重新包装打包存档(S)

git repack -A -d

这将确保不可达的对象得到解压和住宿解压。

5)修剪松动(不可达)对象

git prune

而且应该这样做。 Git真的应该有更好的方式来管理打包裁判。也许有一种我不知道的更好的方式。如果没有更好的方法,手动编辑packed-refs文件可能是唯一的出路。

+1

Yey! !我爱你 ! 问题出现在packed-refs文件中,从某些服务器上备份起来的时候有refs/remotes/origin/master ...一旦我删除它,它就开始消失......谢谢! (使用完整的解决方案更新问题主体) – Devenv 2010-02-02 00:43:19

+0

呵呵,关于packed-refs的提示非常有帮助! – 2014-12-12 11:20:48

2

参见:How do I remove sensitive files from git’s history

如果文件不以转存在上面会失败。在这种情况下,“ - 忽略的不匹配”开关将修复它:

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD 

然后,让所有松散物出repostiry的:

git gc --prune='0 days ago' 
+0

是的,试过这个,仍然有包中的文件,并且尺寸没有变化太多... – Devenv 2010-01-29 22:53:48

+0

我只是做了一个混帐沙箱,并尝试过它。这里也不好。让我们看看我能弄清楚什么。 – 2010-01-30 01:07:17

+0

明白了。请参阅编辑版本。 – 2010-01-30 02:01:59

1

您有多种原因的仍大的git回购股票的大小在git gc之后,因为它是does not remove all loose objects

我详细的“reduce the git repository size

但一招这些原因在你的情况,以测试将clone your "cleaned" Git repo,看看无性系都具有适当的大小。

(“‘干净’回购”作为一个地方你做套用filter-branch,然后gcprune

+0

是的,它已经测试过了,现在再测试一次,它减少了2K的存储库:)并且这些文件仍然存在...... – Devenv 2010-02-01 10:06:09

+0

奇怪的是'git count-objects -v - > count:0,size:0,in-pack :10021,packs:1,size-pack:244547,prune-packable:0,garbage:0' 但是:'git clone test1 test2 - >检出文件:100%(8509/8509),done' – Devenv 2010-02-01 10:11:56

4

我试图摆脱历史上的一个大文件,上面的答案奏效,直到一点。重点是:如果你有标签,他们不会工作。如果提交包含大文件是从一个标签到达,那么你就需要调整滤波器分支命令正是如此:

git filter-branch --tag-name-filter cat \ 
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \ 
--all --tags 
0

我有同样的问题,我发现在GitHub上有很大tutorial通过解释一步步骤如何摆脱您意外犯下的文件。

下面是Cupcake建议的程序的小结。

如果你有一个名为file_to_remove从历史记录中删除文件:

cd path_to_parent_dir 

git filter-branch --force --index-filter \ 
    'git rm --cached --ignore-unmatch file_to_remove' \ 
    --prune-empty --tag-name-filter cat -- --all 
+0

链接只有堆栈溢出非常沮丧的回答,因为如果链接在未来中断,那么答案变得毫无用处。请考虑总结答案中链接中包含的相关信息。 – 2014-04-04 00:05:06

+0

我更新了我的答案。感谢您的建议。 – 2014-04-04 09:58:35

6

我发现这是与问候非常有助于消除整个文件夹的上面并没有真正帮助我:https://help.github.com/articles/remove-sensitive-data

我使用:

git filter-branch -f --force \ 
--index-filter 'git rm -rf --cached --ignore-unmatch folder/sub-folder' \ 
--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 
7

我建议使用BFG Repo-Cleaner,更简单,更快速的替代git-filter-branch专门针对提交历史重写文件而设计的。其中一种让你的生活更轻松的方式是它实际上默认处理所有引用(所有标签,分支,像refs/remotes/origin/master等等),但它也快于10-50x

您应仔细按照这些步骤在这里:http://rtyley.github.com/bfg-repo-cleaner/#usage - 但核心的一点就是这一点:下载BFG's jar(需要Java 6或以上),并运行此命令:

$ java -jar bfg.jar --delete-files file_name my-repo.git 

任何命名file_name文件(即是不是在您的最新提交)将从您的存储库的历史将完全删除。然后,您可以使用git gc清理掉死数据:

$ git gc --prune=now --aggressive 

的BFG一般是简单得多比git-filter-branch使用 - 选项都是围绕这两个常见的用例定制:

  • 删除疯狂大文件
  • 删除密码,证书 &其他私人数据

完全披露:我是BFG Repo-Cleaner的作者。

+0

这是否也推送后从远程仓库清理私人数据? – 2013-07-23 06:20:10

+0

@ThomasLauria yup,同样的清理文件在推送时被推送到远程回购 - http://rtyley.github.io/bfg-repo-cleaner/#usage上的说明应该覆盖它。如果您可以控制远程回购,那么您也可以在推送后运行“git gc --prune = now --aggressive”以确保立即从中删除死对象。 – 2013-07-23 08:11:53