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
Git: How to remove file from historical commit?
提问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.
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-branch
is rewriting operation. If you have published history, you'll have to --force
push the new refs.
与之前描述的变基选项一样,filter-branch
是重写操作。如果您已发布历史记录,则必须--force
推送新的 refs。
The filter-branch
approach is considerably more powerful than the rebase
approach, 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-branch
keeps 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工具。该泯命令完全从库中删除一个文件,其中包括过去的提交和标签。
回答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.
如果其他人已经克隆了您的存储库,您将通知他们,因为您刚刚更改了历史记录。