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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8740187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 12:39:09  来源:igfitidea点击:

Git: How to remove file from historical commit?

git

提问by marioosh

I have commit with id 56f06019 (for example). In that commit i have accidentally commited large file (50Mb). In another commit i add the same file but in the right size (small). Now my repo when i clone is too heavy :( How to remove that large file from repo history to reduce the size of my repo ?

我已提交 ID 为 56f06019(例如)。在那个提交中,我不小心提交了大文件(50Mb)。在另一个提交中,我添加了相同的文件,但大小合适(小)。现在我克隆时的仓库太重了:( 如何从仓库历史记录中删除那个大文件以减小仓库的大小?

回答by sehe

Chapter 9 of the Pro Gitbook has a section on Removing Objects.

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

Let me outline the steps briefly here:

让我在这里简要概述这些步骤:

git filter-branch --index-filter \
    'git rm --cached --ignore-unmatch path/to/mylarge_50mb_file' \
    --tag-name-filter cat -- --all

Like the rebasing option described before, filter-branchis rewriting operation. If you have published history, you'll have to --forcepush the new refs.

与之前描述的变基选项一样,filter-branch是重写操作。如果您已发布历史记录,则必须--force推送新的 refs。

The filter-branchapproach is considerably more powerful than the rebaseapproach, since it

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

  • allows you to work on all branches/refs at once,
  • renames any tags on the fly
  • operates cleanly even if there have been several merge commits since the addition of the file
  • operates cleanly even if the file was (re)added/removed several times in the history of (a) branch(es)
  • doesn't create new, unrelated commits, but rather copies them while modifying the trees associated with them. This means that stuff like signed commits, commit notes etc. are preserved
  • 允许您一次处理所有分支/引用,
  • 即时重命名任何标签
  • 即使自添加文件以来有几次合并提交,也能干净地运行
  • 即使文件在(a)分支的历史记录中(重新)添加/删除了几次,也能干净地运行
  • 不会创建新的、不相关的提交,而是在修改与它们关联的树时复制它们。这意味着诸如签名提交、提交注释等内容将被保留

filter-branchkeeps backups too, so the size of the repo won't decrease immediately unless you expire the reflogs and garbage collect:

filter-branch也保留备份,因此除非您使 reflogs 和垃圾收集过期,否则 repo 的大小不会立即减少:

rm -Rf .git/refs/original       # careful
git gc --aggressive --prune=now # danger

回答by Ofer Segev

You can use git-extrastool. The obliteratecommand completely remove a file from the repository, including past commits and tags.

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

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

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

回答by Sandeep Dixit

I tried using following answer on windows https://stackoverflow.com/a/8741530/8461756

我尝试在 Windows https://stackoverflow.com/a/8741530/8461756上使用以下答案

Single quote does not work on windows, you need double quotes.

单引号在 Windows 上不起作用,您需要双引号。

Following worked for me.

以下对我来说有效。

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PathRelativeRepositoryRoot/bigfile.csv" -- --all

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PathRelativeRepositoryRoot/bigfile.csv" -- --all

After removing the big file, I was able to push my changes to github master.

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

回答by Lo?c d'Anterroches

You will need to git rebasein the interactive mode see an example here: How can I remove a commit on GitHub?and how to remove old commits.

您将需要在交互模式下使用git rebase,请在此处查看示例:如何删除 GitHub 上的提交?以及如何删除旧提交

If your commit is at HEAD minus 10 commits:

如果您的提交是 HEAD 减去 10 次提交:

$ git rebase -i HEAD~10

After the edition of your history, you need to push the "new" history, you need to add the +to force (see the refspec in the push options):

在你的历史版本编辑后,你需要推送“新”历史,你需要添加+强制(参见推送选项中的refspec ):

$ git push origin +master

If other people have already cloned your repository, you will to inform them, because you just changed the history.

如果其他人已经克隆了您的存储库,您将通知他们,因为您刚刚更改了历史记录。