如何完全从git仓库中删除数据?

3
在我的项目中,我错误地将一些大的图像文件添加到了我的代码库中。我查阅了GitHub上有关如何从历史记录中删除文件的信息,并成功地执行了操作:在历史记录中你已经看不到这些文件了。但是,我为备份从我的项目中创建了一个tar.gz文件,它现在比原来的大小大了两倍!我没有添加其他任何可以解释这个增加的东西,所以我怀疑代表图像文件的代码库数据并没有真正地被清除。有人能证实吗?是否有解决方法?
编辑以澄清,我对git知之甚少,所以我按照GitHub帮助页面上指示的步骤进行操作,唯一的例外是我必须从第二个文件开始使用force开关,如git filter-branch -f --index-filter ...
为了部分回答自己的问题,我认为我可以创建一个没有不需要的材料的第二个git代码库。
  • 在不同的位置创建一个空的repo
  • 在项目的不同步骤中复制文件情况,省略不需要的部分
  • 最后使用新的repo代替旧的repo将材料推送到GitHub上。

这样做过吗?具体来说,我能否使用新的git repo代替GitHub上相同项目的旧repo?

顺便说一句,这是关于我正在写的a presentation。其中有一张巴别塔的图片,有多个高清版本,这就解释了问题的规模(大约100MB的不必要数据)。

编辑2 非常感谢您的建议;我已经做了。

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

由此产生的效果是*.tar.gz文件大小仅减少了0.5%...

编辑3 体验到Git的复杂性确实让人畏惧。我在这一点上放弃了。我做了一个小型的测试repo;我进行了初始提交,添加了一个大文件,进行了提交,删除了该文件,并尝试从内存中擦除其痕迹。

rm very-big-file.xcf
git filter-branch --index-filter 'git rm --cached --ignore-unmatch very-big-file.xcf' --prune-empty -- --all
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune=now

这些是记录的 *.tar.gz 文件大小:

foo.tar.gz          7,518 
foo2.tar.gz    65,735,003 
foo3.tar.gz    32,777,155 

大文件的压缩大小为32,955,246字节,这使得它完全有可能仍然完整存在于.git下,甚至可能是未压缩的形式。
GIT为什么如此顽固?
难道没有任何git清除扩展程序可以做到这一点吗?我的意思是,当我有点宿醉时,我不太可能从记忆中输入类似于“git filter-branch --index-filter 'git rm --cached --ignore-unmatch very-big-file.xcf' --prune-empty -- --all”的命令。

1
你能否再多说一点关于你是如何移除它们的?你运行了 git gc 吗?你使用 git rm --cached 从索引中移除了它吗? - Nic
@CaptainGiraffe 在这种情况下不是必要的。 - Nic
1
дҪ жҢүз…§git filter-branchзҡ„жҢҮзӨәеңЁжүҖжңүеҲҶж”ҜдёҠжү§иЎҢдәҶеҗ—пјҹ然еҗҺдҪ жҳҜеҗҰжү§иЎҢдәҶrm -rf .git/refs/original/гҖҒgit reflog expire=now --allе’Ңgit gc --prune=nowиҝҷдәӣжӯҘйӘӨпјҹ - torek
抱歉,我在上面的“reflog expire”中打错了一个字。无论如何,让我详细说明一下你的第三个更新... - torek
2个回答

0

关于“编辑3”...这里是一个完整的序列,我实际上记录并重试以消除打字错误。 :-) 请注意,在删除大文件后,您无法filter-branch,除非您提交该删除(对于此示例来说有点无意义)。检查du -s输出。

$ git init bigoop
Initialized empty Git repository in /tmp/bigoop/.git/
$ cd bigoop
$ echo tiny file with not much in it > tiny
$ git add tiny
$ git commit -m 'initial commit'
[master (root-commit) bd07e5a] initial commit
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 tiny
$ cp /path/to/huge/file hugefile
$ git add hugefile
$ git commit -m 'oops, add huge file'
[master 25cd764] oops, add giant file
 1 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 hugefile
$ du -s .git
618992  .git
$ rm hugefile
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch hugefile' --prune-empty -- --all
Cannot rewrite branch(es) with a dirty working directory.
$ git checkout hugefile
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch hugefile' --prune-empty -- --all
Rewrite 25cd7647f49173fa8f42c0ca0a2ab8baf1842fca (2/2)rm 'hugefile'

Ref 'refs/heads/master' was rewritten
$ du -s .git
619012  .git
$ rm -rf .git/refs/original/
$ git reflog expire --expire=now --all
$ git gc --prune=now
Counting objects: 3, done.
Writing objects: 100% (3/3), done.
Total 3 (delta 0), reused 0 (delta 0)
$ du -s .git
140     .git

关于“GIT Y U SO STUBBORN??”,它确实非常努力地不丢失任何东西。即使你试图让它丢失东西,它也会尽力保留。 :-)

好的,看起来我漏掉了什么东西;今天稍后再重试。 - flow

0
一个快速的方法是让历史记录看起来完全像你想要的那样,将存储库添加为新空存储库的远程,然后只需获取。您只会获取它们所代表的参考和历史记录中的对象。
现在,您可以将此推送到新的GitHub存储库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接