Git:如何从历史提交中删除文件?

mar*_*osh 107 git

我提交了id 56f06019(例如).在那个提交中,我不小心提交了大文件(50Mb).在另一个提交中,我添加相同的文件,但大小合适(小).现在我克隆的回购太重了:(如何从回购历史中删除那个大文件以减少我的回购的大小?

seh*_*ehe 155

Pro Git书的第9章有一节关于删除对象.

让我简要介绍一下这里的步骤:

git filter-branch --index-filter \
    'git rm --cached --ignore-unmatch path/to/mylarge_50mb_file' \
    --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)

像之前描述的rebasing选项一样,filter-branch是重写操作.如果您已发布历史记录,则必须--force推送新的参考号.

这种filter-branch方法比rebase方法强大得多,因为它

  • 允许你一次处理所有分支/ refs,
  • 动态重命名任何标签
  • 即使自添加文件以来已经进行了多次合并提交,也可以干净地运行
  • 即使在(a)分支的历史中多次(重新)添加/删除文件,也能干净地运行
  • 不会创建新的,无关的提交,而是在修改与它们关联的树时复制它们.这意味着保留了诸如签名提交,提交注释等内容

filter-branch 保持备份,所以除非你使reflogs和垃圾收集过期,否则repo的大小不会立即减少:

rm -Rf .git/refs/original       # careful
git gc --aggressive --prune=now # danger
Run Code Online (Sandbox Code Playgroud)

  • 我使用双引号而不是单引号(在Windows Server 2012 cmd.exe上)使上面的git filter-branch工作 (2认同)
  • 对我有用的是这个 filter-branch 命令行。`git filter-branch --force --index-filter 'git rm --ignore-unmatch --cached PathTo/MyFile/ToRemove.dll' -- fbf28b005^..` 然后`rm --recursive --force .git /refs/original` 和 `rm --recursive --force .git/logs` 然后我使用了 `git prune --expire now` 和 `git gc --aggressive` 这对我来说比上面列出的确切步骤更好. 感谢您提供 Git Pro 书籍的链接,因为它非常宝贵。 (2认同)

Ofe*_*gev 5

您可以使用git-extras工具。该命令完全从库中删除一个文件,其中包括过去的提交和标签。

https://github.com/tj/git-extras/blob/master/Commands.md

  • 惊人的!这完成了工作。如此美丽简单。 (2认同)

San*_*xit 5

我尝试在 Windows /sf/answers/611907131/上使用以下答案

单引号在 Windows 上不起作用;你需要双引号。

以下为我工作。

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PathRelativeRepositoryRoot/bigfile.csv" -- --all
Run Code Online (Sandbox Code Playgroud)

删除大文件后,我能够将更改推送到 GitHub master。