【问题标题】:How can i completely remove data from a git repository?如何从 git 存储库中完全删除数据?
【发布时间】:2012-03-24 20:17:24
【问题描述】:

在我的项目中,我错误地将一些大图像文件添加到我的存储库中。我读了GitHub 如何从历史记录中删除文件,它确实有效:您再也看不到历史记录中的文件了。但是后来我从我的项目中创建了一个tar.gz 进行备份,现在它的大小是以前的两倍!我没有添加任何其他可以证明这种增加的理由,所以我怀疑用于表示图像文件的 repo 数据并没有真正从 repo 中剔除。有人可以证实吗?有解决办法吗?

edit 澄清一下我对 git 知之甚少,所以我完全按照GitHub help pages 中指示的步骤进行操作,唯一的例外是我必须使用第二个中的force 开关文件,如git filter-branch -f --index-filter ...

为了部分回答我自己的问题,我想我可以通过

创建第二个没有不需要的材料的 git repo
  • 在不同的位置创建一个空的仓库
  • 在我的项目的不同步骤重现文件情况,排除不需要的文件
  • 最后使用新的 repo 而不是旧的 repo 将材料推送到 GitHub。

以前做过吗?具体来说,我可以在 GitHub 上使用新的 git 存储库而不是旧的与相同的项目吗?

顺便说一句,这是关于a presentation 我现在正在写的;有 其中存在多个高分辨率版本的巴别塔图像,这解释了问题的大小(约 100MB 不需要的数据)。

edit 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%...

edit 3 体验 git 的绝对复杂性令人生畏。我在这一点上放弃了。我用一个小的一次性回购做了一个测试;我做了一个初始提交,添加了一个大文件,做了一个提交,删除了文件并尝试用

从内存中擦除它的痕迹
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 purge 扩展名可以做到这一点吗?我的意思是,git filter-branch --index-filter 'git rm --cached --ignore-unmatch very-big-file.xcf' --prune-empty -- --all 并不是我在轻微宿醉时可以从记忆中输入的内容。

【问题讨论】:

  • 你能补充一点关于你是如何删除它们的吗?你跑git gc了吗?您是否使用 git rm --cached 将其从索引中删除?
  • @CaptainGiraffe 在这种情况下不是必需的。
  • 您按照git filter-branch 的说明在所有分支上都这样做了,对吧?然后您是否执行了rm -rf .git/refs/original/git reflog expire=now --allgit gc --prune=now 步骤?
  • 糟糕,我上面的reflog expire 中有错字。 Anwyay 让我扩展您的第三次更新...

标签: git repository size


【解决方案1】:

一种快速的方法是让历史看起来完全像您想要的那样,将存储库添加为新的空存储库的远程,然后获取。您只会获得它们所代表的历史记录中的引用和对象。

您现在可以将其推送到新的 GitHub 存储库。

【讨论】:

    【解决方案2】:

    重新“编辑 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??” ...不丢失东西真的很努力。即使你试图让它失去东西。 :-)

    【讨论】:

    • 好吧,看来我错过了什么;将在今天晚些时候重试
    猜你喜欢
    • 2011-03-28
    • 2011-01-23
    • 2013-05-28
    • 2015-11-05
    • 2015-04-19
    • 1970-01-01
    • 2023-03-08
    • 2010-11-15
    相关资源
    最近更新 更多