如何从Git仓库的提交历史中删除一个大文件?

1081
我不小心把一个DVD剪辑文件放进了一个网站项目中,粗心地使用了git commit -a -m ...命令,结果仓库膨胀了2.2GB。下次我做了一些修改,删除了视频文件,然后提交了所有更改,但是压缩文件仍然存在于仓库的历史记录中。
我知道我可以从这些提交中创建分支,然后将一个分支合并到另一个分支上。但是我应该怎么做才能合并这两个提交,使得这个大文件不会在历史记录中显示,并且在垃圾回收过程中被清除掉呢?

13
这篇文章应该能帮助你:http://help.github.com/removing-sensitive-data/。 - MBO
4
相关链接:完全从Git仓库提交历史中删除文件 - user456814
1
请注意,如果你的大文件在子目录中,你需要指定完整的相对路径。 - Johan
10
请看一下我的回答,它使用了git filter-repo。你不应再使用git filter-branch,因为它非常慢且经常难以使用。git filter-repo快约100倍。 - Donat
2
经过我第十次尝试,正确的答案是git应该拒绝检入这些文件,而不是创建所有这些骚动。 - Todd Hoff
显示剩余7条评论
25个回答

835
使用BFG Repo-Cleaner,这是一个更简单、更快速的替代方案,专门用于从Git历史中删除不需要的文件。
请仔细遵循使用说明。核心部分只有这一句话:
java -jar bfg.jar --strip-blobs-bigger-than 100M my-repo.git

任何大小超过100MB的文件(不包括您最新的提交)将从您的Git存储库历史记录中删除。然后,您可以使用git gc清除无用的数据。
git reflog expire --expire=now --all && git gc --prune=now --aggressive

修剪完之后,我们可以强制推送到远程仓库。
git push --force

注意:无法在GitHub上强制推送受保护的分支。
BFG通常比运行git-filter-branch快10-50倍,并且通常更易于使用。
完全披露:我是BFG Repo-Cleaner的作者。

6
值得重申整个克隆和清空过程,以查看是否会再次出现要求拉取的信息。但几乎可以确定是由于您的远程服务器配置为拒绝非快进式更新(即它被配置为防止您丢失历史记录,而这正是您要做的)。您需要在远程更改该设置,或者如果失败,将更新后的仓库历史推送到全新的空白仓库。 - Roberto Tyley
13
@RobertoTyley 很好,你帮我节省了时间,非常感谢。顺便说一下,在你的步骤之后可能需要执行 git push --force 命令,否则远程仓库不会改变。 - Weiyi
4
在“git push --force”命令中,将“+1”添加到命令中。此外,值得注意的是:远程可能不允许强制推送(例如,默认情况下,gitlab.com不允许强制推送。必须“取消保护”该分支)。 - MatrixManAtYrService
3
BFG 对我来说效果非常好,仅用几分钟就将一个517MB的代码库压缩到了38MB。在找到这个答案之前,其他方法都对我无效。 - MitchellK
3
未记录的问题(大多数情况下)当出现“存储库已打包”错误时。在目标存储库上使用git gc,然后重新执行您正在使用BFG进行的任何操作。一旦解决了这个问题,它就可以很好地工作。可能需要更明确的文档,但我不是最快的学习者;p - DaveRGP
显示剩余29条评论

702
NB: 自从撰写这个答案以来,git filter-branch已被弃用,并且不再受支持。请参阅man页面获取更多信息。

你想做的事情非常具有破坏性,如果你对其他开发者公开历史记录。请参阅"从上游rebase恢复" 在 git rebase 文档中,以修复历史记录后的必要步骤。

你至少有两个选择:git filter-branch 和一个 交互式rebase,下面都有解释。

使用 git filter-branch

我曾经遇到过类似的问题,通过一个Subversion导入得到庞大的二进制测试数据,并写了关于从git存储库中删除数据的文章。

假设你的git历史是:

$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A     login.html
* cb14efd Remove DVD-rip
| D     oops.iso
* ce36c98 Careless
| A     oops.iso
| A     other.html
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

请注意 git lola 是一个非标准但非常有用的别名(有关详细信息,请参阅本答案末尾的附录)。--name-status 开关用于 git log,显示与每个提交相关的树修改。
在“Careless”提交中(其 SHA1 对象名称为 ce36c98),文件 oops.iso 是错误添加并在下一次提交 cb14efd 中删除的 DVD 剪辑。使用上述博客文章中描述的技术,要执行的命令如下:
git filter-branch --prune-empty -d /dev/shm/scratch \
  --index-filter "git rm --cached -f --ignore-unmatch oops.iso" \
  --tag-name-filter cat -- --all

选项:

  • --prune-empty删除由于筛选操作而变为空(即不改变树形结构)的提交。在典型情况下,此选项可产生更清晰的历史记录。
  • -d指定一个尚不存在的临时目录,用于构建筛选后的历史记录。如果您在现代Linux发行版上运行,指定/dev/shm中的树形目录将导致更快的执行速度。
  • --index-filter是主要操作,在历史记录的每个步骤中针对索引运行。您想要删除所有出现的oops.iso,但它并不在所有提交中都存在。命令git rm --cached -f --ignore-unmatch oops.iso会在出现时删除DVD副本,并在其他情况下不会出错。
  • --tag-name-filter描述如何重写标签名称。过滤器cat为恒等操作。您的存储库可能没有任何标签,但我包括了此选项以保持完整性。
  • --指定git filter-branch选项的结束。
  • --all--之后表示所有引用的简写形式。您的存储库可能只有一个引用(master),但我包括了此选项以保持完整性。
经过一番思考,历史现在是这样的:
$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A     login.html
* e45ac59 Careless
| A     other.html
|
| * f772d66 (refs/original/refs/heads/master) Login page
| | A   login.html
| * cb14efd Remove DVD-rip
| | D   oops.iso
| * ce36c98 Careless
|/  A   oops.iso
|   A   other.html
|
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

请注意,新的“Careless”提交仅添加了other.html,而“Remove DVD-rip”提交不再位于主分支上。标记为refs/original/refs/heads/master的分支包含您的原始提交,以防您犯了错误。要删除它,请按照{{link1:“缩小存储库的清单”}}中的步骤进行操作。
$ git update-ref -d refs/original/refs/heads/master
$ git reflog expire --expire=now --all
$ git gc --prune=now

为了一个更简单的选择,克隆存储库以丢弃不需要的部分。
$ cd ~/src
$ mv repo repo.old
$ git clone file:///home/user/src/repo.old repo

使用file:///...克隆URL会复制对象,而不仅仅是创建硬链接。
现在你的历史记录是:
$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A     login.html
* e45ac59 Careless
| A     other.html
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

第一个和第二个提交的SHA1对象名称(“索引”和“管理页面”)保持不变,因为过滤操作没有修改这些提交。 “粗心”的丢失了oops.iso,“登录页面”得到了一个新的父级,所以它们的SHA1发生了变化。
交互式变基
具有以下历史记录:
$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A     login.html
* cb14efd Remove DVD-rip
| D     oops.iso
* ce36c98 Careless
| A     oops.iso
| A     other.html
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

你想要从“Careless”中删除oops.iso,就好像你从未添加过它一样,然后“Remove DVD-rip”对你来说就没有用了。因此,我们进行交互式变基的计划是保留“Admin page”,编辑“Careless”,并丢弃“Remove DVD-rip”。
运行$ git rebase -i 5af4522会启动一个带有以下内容的编辑器。
pick ce36c98 Careless
pick cb14efd Remove DVD-rip
pick f772d66 Login page

# Rebase 5af4522..f772d66 onto 5af4522
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

执行我们的计划,我们对其进行修改。
edit ce36c98 Careless
pick f772d66 Login page

# Rebase 5af4522..f772d66 onto 5af4522
# ...

那就是,我们删除带有“删除DVD-rip”的行,并将“Careless”上的操作更改为编辑而不是选择
保存退出编辑器后,我们会在命令提示符下看到以下消息。
Stopped at ce36c98... Careless
You can amend the commit now, with

        git commit --amend

Once you are satisfied with your changes, run

        git rebase --continue

根据信息所示,我们正处于“Careless”提交中需要编辑,因此我们运行两个命令。
$ git rm --cached oops.iso
$ git commit --amend -C HEAD
$ git rebase --continue

第一个命令从索引中移除了有问题的文件。第二个命令修改或修正了“Careless”,使其成为更新后的索引,-C HEAD指示git重用旧的提交信息。最后,git rebase --continue继续进行剩余的rebase操作。
这样就得到了以下的历史记录:
$ git lola --name-status
* 93174be (HEAD, master) Login page
| A     login.html
* a570198 Careless
| A     other.html
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

这就是你想要的。
补充说明:通过 ~/.gitconfig 启用 git lola。 引用 Conrad Parker
在 2010 年的 linux.conf.au 上,我从 Scott Chacon 的演讲《Git Wrangling - Advanced Tips and Tricks》中学到了最好的技巧,就是这个别名。
lol = log --graph --decorate --pretty=oneline --abbrev-commit
这个功能可以很好地展示你的代码树的图形,显示合并等分支结构。当然,有一些非常好用的图形界面工具可以展示这样的图形,但是git lol的优势在于它可以在控制台或通过ssh使用,因此对于远程开发或嵌入式开发来说非常有用...

So, just copy the following into ~/.gitconfig for your full color git lola action:

[alias]
        lol = log --graph --decorate --pretty=oneline --abbrev-commit
        lola = log --graph --decorate --pretty=oneline --abbrev-commit --all
[color]
        branch = auto
        diff = auto
        interactive = auto
        status = auto

5
当使用git filter-branch时,我为什么无法推送代码,出现了"failed to push some refs to 'git@bitbucket.org:product/myproject.git'"的错误提示? 这是因为为了防止您丢失历史记录,非快速转发的更新被拒绝了。在再次推送之前,请先合并远程更改。 - Agung Prasetyo
11
在你的git push命令中加上-f(或--force)选项:“通常情况下,该命令会拒绝更新一个不是本地参照所覆盖的远程参照的祖先的远程参照。这个标志禁用了这个检查。这可能会导致远程存储库丢失提交;请谨慎使用。” - Greg Bacon
6
这是一个非常详细的回答,解释了如何使用git-filter-branch从历史记录中删除不需要的大文件。但值得一提的是,自从Greg写下这个回答以来,BFG Repo-Cleaner已经发布,通常更快更易于使用 - 有关详细信息,请参见我的回答。 - Roberto Tyley
2
在我执行上述任何一个过程之后,远程仓库(GitHub 上的)并没有删除大文件。只有本地删除了。我强制推送了,但仍然没有用。我错过了什么吗? - 4Z4T4R
1
感谢您详细的回答,已经解决了我的问题。 - Gideon A.
显示剩余10条评论

316
NB: 自从撰写这个答案以来,git filter-branch已被弃用,并且不再受支持。请参阅man页面获取更多信息。
为什么不使用这个简单而强大的命令呢?
git filter-branch --tree-filter 'rm -f DVD-rip' HEAD
--tree-filter选项在每次项目检出后运行指定的命令,然后重新提交结果。在这种情况下,您可以从每个快照中删除名为DVD-rip的文件,无论它是否存在。
如果您知道哪个提交引入了巨大的文件(比如35dsa2),您可以将HEAD替换为35dsa2..HEAD,以避免重写太多历史记录,从而避免分叉提交(如果您尚未推送)。这个评论由@alpha_989提供,似乎对此处很重要。
请参见此链接

7
比bfg好得多。我使用bfg无法清理git中的文件,但这个命令有帮助。 - podarok
4
很好。提醒其他人的一点是,如果这个大文件在多个分支中,你需要针对每个分支进行此操作。 - James
1
这对我在本地提交上起作用,但我无法上传到GitHub。而且它似乎比其他解决方案更简单。 - Richard G
6
如果你知道你将文件放置的提交commit(比如说35dsa2),你可以用35dsa2..HEAD替换HEAD。在这种方式下,tree-filterindex-filter慢得多,因为它不会尝试检出所有提交并重写它们。如果你使用HEAD,它会尝试那样做。 - alpha_989
11
运行上述命令后,您需要运行git push --all --force命令,以使远程的历史记录与您现在在本地创建的修改版本相匹配。 (@stevec) - Noel Evans
显示剩余5条评论

145

我看到的解决这个问题最好的答案是:https://dev59.com/AWkv5IYBdhLWcg3wZwG-#42544963。因为这个帖子在谷歌搜索排名上很高,但另一个帖子不在。

一个极快的一行脚本

这个Shell脚本显示了存储库中所有Blob对象,按大小从小到大排序。

对于我的示例仓库,它比这里找到的其他脚本运行快了100倍
在我的可靠的Athlon II X4系统上,它处理了包含5,622,155个对象的Linux内核存储库,只需要一分钟多点时间

基本脚本

git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '/^blob/ {print substr($0,6)}' \
| sort --numeric-sort --key=2 \
| cut --complement --characters=13-40 \
| numfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest

当您运行上面的代码时,您将获得如下所示的漂亮的可读性良好的输出

...
0d99bb931299  530KiB path/to/some-image.jpg
2ba44098e28f   12MiB path/to/hires-image.png
bd1741ddce0d   63MiB path/to/some-video-1080p.mp4

快速文件删除

假设您希望从每个可以从 HEAD 访问到的提交中删除文件 ab,您可以使用以下命令:

git filter-branch --tree-filter 'rm -f a b' --prune-empty HEAD
git filter-branch --index-filter 'git rm --cached --ignore-unmatch a b' HEAD

6
如果您的代码库有任何标签,您很可能还想添加 --tag-name-filter cat 标记来重新标记新的相应提交,因为它们被重写了,即 git filter-branch --index-filter 'git rm --cached --ignore-unmatch a b' --tag-name-filter cat HEAD(参见 这个相关答案)。 - naitsirhc
4
Mac的说明和其他一些信息出现在原链接帖子中。 - nruth
3
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD 这个命令可以立即删除指定文件的 Git 历史记录。"workorder right of the bat" 句子不完整,无法翻译。请提供更多上下文或完整句子。 - eleijonmarck
2
我最喜欢的答案。在Mac OS上进行轻微调整(使用GNU命令):git rev-list --objects --all \ | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \ | awk '/^blob/ {print substr($0,6)}' \ | sort --numeric-sort --key=2 \ | gnumfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest - Florian Oswald
1
谢谢,但对于Mac OSX + zsh来说它并不起作用,我将其修改为更简单的版本:<code> git rev-list --objects --all git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' awk '/^blob/ {print substr($0,6)}' sort --numeric-sort --key=2</code> - Vasili Pascal
显示剩余3条评论

125

比git filter-branch快100倍,使用更简单

这个帖子中有很多很好的答案,但同时也有很多已经过时了。不再推荐使用git-filter-branch,因为它在处理包含大量提交的大型代码库时非常慢且难以使用。

git-filter-repo更快且更易于使用。

git-filter-repo是一个Python脚本,可以在github上找到:https://github.com/newren/git-filter-repo。安装后,它看起来就像一个普通的git命令,可以通过git filter-repo来调用。

你只需要一个文件:Python3脚本git-filter-repo。将其复制到包含在PATH变量中的路径中。在Windows上,你可能需要更改脚本的第一行(参考INSTALL.md)。你需要在系统上安装Python3,但这并不困难。

首先,你可以运行

git filter-repo --analyze

这有助于你确定接下来要做什么。
你可以在任何地方删除你的DVD副本文件。
git filter-repo --invert-paths --path-match DVD-rip
 

Filter-repo非常快速。一项在我的电脑上用filter-branch大约花费9小时的任务,使用filter-repo只需4分钟即可完成。您可以通过filter-repo做更多好玩的事情。请参考文档。

警告:在副本上进行此操作。filter-repo的许多操作是无法撤销的。filter-repo将更改所有修改过的提交(当然也包括其下的所有子孙提交)的提交哈希!


2
我该如何将本地仓库中的更改提交到远程仓库?或者这不可能,我应该克隆修改后的仓库到一个新的仓库? - diman82
4
最好的方法是创建一个新的空仓库,将你克隆的仓库的远程仓库设置为它,并推送。这适用于所有这里给出的答案:你会得到许多新的提交哈希值。这是不可避免的,因为提交哈希值保证了仓库的内容和历史记录。另一种替代方案很危险,你可能会进行强制推送,然后运行GC来摆脱文件。但除非你测试过并且明确了所有后果,否则不要这样做! - Donat
我已经使用--force选项推送了代码,这在克隆的代码库中运行良好(作为一种预防措施)。 - diman82
20
“git filter-repo --strip-blobs-bigger-than 10M” 在我的电脑上效果更好。 - Lucas
1
这对我很有效。filter-repo有更高级用例的良好文档,但在我的情况下,我只需要摆脱我意外提交的大文件。在我的情况下,在新版本中复制项目目录,运行命令,重新添加远程并推送(不是严格的全新克隆)就可以正常工作。 - Alex L
3
现在应该接受这个答案。表现得非常好。 - james-see

112

在尝试了SO上的几乎所有答案之后,我终于找到了这个宝石,可以快速删除并清除我的存储库中的大文件,并允许我再次进行同步:http://www.zyxware.com/articles/4027/how-to-delete-files-permanently-from-your-local-and-remote-git-repositories

切换到您的本地工作文件夹并运行以下命令:

git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch FOLDERNAME" -- --all

将FOLDERNAME替换为您希望从给定的Git仓库中删除的文件或文件夹。

完成后,请运行以下命令清理本地仓库:

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

现在将所有更改推送到远程仓库:

git push --all --force

这将清理远程代码库。


1
对我来说运行得非常好。 - Ramon Vasconcelos
4
这个方法对我也奏效了。它能够删除存储库中的特定文件夹(例如,包含过大文件或Github存储库的文件夹),但同时在本地文件系统上保留该文件夹(如果存在的话)。 - skizzo
可能还需要使用 git push origin --tags --force 命令来在打标签的版本中从远程仓库中删除大文件。 - Kostas Stamos
这很棒。想要补充一下,对于最后一个命令,如果您有一个包含许多提交的非常大的repo,而不是使用“--all”,请阅读此答案(https://dev59.com/rmUp5IYBdhLWcg3wrY5p#51468389)以拆分推送(注意,将*git push替换为git push -f*)。我不得不这样做,因为尝试一次性推送所有内容时,打包大小超过了2 GB。还有第二个评论- 备份所有东西 - Stardust
1
我想只有我没有意识到这个命令不仅会从git仓库中删除文件,还会从项目本身中清除。虽然确实起作用了! - Karl
显示剩余4条评论

44
这些命令在我的情况下有效:
git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch oops.iso' --prune-empty --tag-name-filter cat -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

这个版本与之前的版本有一点不同。
对于那些需要将其推送到GitHub/Bitbucket的人(我只在Bitbucket上进行了测试):
# WARNING!!!
# This will rewrite completely your Bitbucket refs
# will delete all branches that you didn't have in your local

git push --all --prune --force

# Once you pushed, all your teammates need to clone repository again
# git pull will not work

4
与上面有何不同,为什么更好? - Andy Hayden
1
由于某些原因,mkljun版本在我的情况下没有减少git空间,我已经使用git rm --cached files从索引中删除了文件。Greg Bacon的建议更加完整,与我的建议相当类似,但他错过了--force索引,适用于多次使用filter-branch的情况,并且他写了很多信息,而我的版本就像它的摘要。 - Kostanos
1
这真的很有帮助,但是我需要在这里使用-f选项而不仅仅是-rf。结果如下:git rm --cached -rf --ignore-unmatch oops.iso,而不是像@lfender6445建议的那样git rm --cached -r --ignore-unmatch oops.iso - drstevok

20
根据GitHub的文档,只需按照以下步骤操作:
  1. 摆脱大文件

    选项1:您不想保留这个大文件:

    rm path/to/your/large/file        # 删除大文件
    

    选项2:您想将大文件保存到一个未跟踪的目录中

    mkdir large_files                       # 创建目录large_files
    touch .gitignore                        # 如果需要,创建.gitignore文件
    '/large_files/' >> .gitignore           # 不跟踪目录large_files
    mv path/to/your/large/file large_files/ # 将大文件移动到未跟踪的目录中
    
  2. 保存您的更改

    git add path/to/your/large/file   # 将删除操作添加到索引中
    git commit -m 'delete large file' # 提交删除操作
    
  3. 从所有提交中删除大文件

    git filter-branch --force --index-filter \
      "git rm --cached --ignore-unmatch path/to/your/large/file" \
      --prune-empty --tag-name-filter cat -- --all
    git push <remote> <branch>
    

你能详细说明一下“从所有提交中删除大文件”的步骤是如何工作的吗?那真是太棒了! - clayg
感谢@clayg。我并不深入理解git filter-branch命令,正如我所写的,我只是按照GitHub文档进行操作。我知道的是,该命令浏览您的.git文件夹,并查找给定文件的所有记录,并将其从历史记录中删除。 - Kevin R.
@KevinR,你需要强制推送,对吧? - Exploring
这是正确的 @Exploring - Kevin R.
谢谢,该死的Python程序员们以及检查二进制文件。 - Owl

13
我在Bitbucket账户上遇到了这个问题,我不小心存储了我的网站的巨大的*.jpa备份文件。
git filter-branch --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch MY-BIG-DIRECTORY-OR-FILE' --tag-name-filter cat -- --all
将MY-BIG-DIRECTORY替换为相关文件夹,以完全重写您的历史记录(包括标签)。
来源:Finding and Purging Big Files From Git History

1
这个回答对我很有帮助,除了答案中的脚本有一点问题,不能为我搜索所有分支。但是链接中的命令完美地解决了这个问题。 - Ali B
如果需要覆盖以前的备份,请在 git filter-branch 后面添加 -f - Sheldon

10

2022年适用的新答案

请勿使用:

git filter-branch

在推送之后,这个命令可能不会改变远程仓库。如果你在使用它之后进行克隆,你会发现什么都没有改变,仓库的大小仍然很大。看起来这个命令现在已经过时了。例如,如果你按照 https://github.com/18F/C2/issues/439 中的步骤操作,这个方法是行不通的。

解决方案

这个解决方案基于以下方法:

git filter-repo

步骤:
(1)在.git中找到最大的文件(将10更改为您想要显示的文件数量)。
git rev-list --objects --all | grep -f <(git verify-pack -v  .git/objects/pack/*.idx| sort -k 3 -n | cut -f 1 -d " " | tail -10)

(2)通过传递您想要删除的文件的路径和名称,开始对这些大文件进行过滤:
 git filter-repo --path-glob '../../src/../..' --invert-paths --force

或者使用文件的扩展名,例如,筛选所有的.zip文件:
 git filter-repo --path-glob '*.zip' --invert-paths --force

或者,例如,过滤所有的.a库文件:
 git filter-repo --path-glob '*.a' --invert-paths --force

或者 无论你在步骤1中找到什么。

(3)

 git remote add origin git@github.com:.../...git

(4)
git push --all --force

git push --tags --force

完成了!!!

  1. 中的 "Strat" 是什么意思?你在这一步骤中做了什么?
  2. 请解释一下第三步在做什么,特别是 ".../...git" 的部分。我已经有一个带有远程的 repo。所有的 .../ 都是关于什么的?
- pauljohn32
我喜欢这个解决方案。发帖者应该提到“filter-repo”不是本地的git命令,你需要安装一个Python脚本:https://github.com/newren/git-filter-repo - inorganik
这是来自未来的信息吗?请告诉我2022年的生活是什么样子的。我简直不敢相信你们还在使用git。 - Frank Hileman
第一步可以使用git filter-repo --analyze来完成。 - undefined

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