我正在尝试使用filter-branch
. 我之前成功地使用过这个命令,但我目前在特定的边缘情况下遇到了麻烦。
问题是这些大文件从未真正被删除,而是被具有相同路径的较小版本所取代。
据我所知,我相信我有一个独特的问题。
Git 日志
详细地说,这是我的回购的基本表示:
----- A ------ B ----------- HEAD
在哪里:
A is the commit where the large files were introduced
B is the commit (about 30 later) where the large files were replaced with smaller ones
HEAD is thousands of commits forward of B (~2 years of active development)
Git 过滤器分支
理论上,我应该能够做这样的事情:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filenames' <parent of A>..B
我相信我应该使用<parent of A>
,因为filter-branch
不包括在内。(我不确定我是否也需要使用 B 的父级,但这是我现在最不担心的问题)。
运行它会给我错误:
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch filenames' <parent of A>..B
Which ref do you want to rewrite?
所以我--glob="refs/heads/master*"
在命令的末尾包含了似乎可以解决问题的命令(source)。
执行完成后,文件已被完全删除 - git 似乎忽略了我指定的上限。
所以我想知道这种方法是否可行?
替代方法
我想我应该列出我的一些其他想法,以便潜在的答案可以集中在解决问题上。
- 务实的方法是在 HEAD 提交文件名更改,然后运行
git filter-branch ... HEAD
. 但是,我的存储库有许多正在积极开发的分支,我相信这种方法会非常混乱。 - 另一种方法可能是做类似这里描述的事情。去引用:
create a temporary branch to point at HEAD^, filter-branch it, then add a graft to stitch the remaining commit on top of it, then filter-branch HEAD and then remove the graft.
希望有人以前遇到过这个问题并且可以提供他们的专业知识。
更新
我要删除的文件总共约为 500MB,所以我非常渴望删除它们,这是可以理解的!他们早在我加入公司之前就已经承诺了,并且是我们从内部 Mercurial 服务器迁移到 GitHub 的残余(我想将 500MB 推送到内部服务器将不如 GitHub 引人注目......)。
更新 2
我一直在关注 twalberg 的第二个答案(我认为我以正确的方式使用它):
git filter-branch --index-filter '(( $(git rev-list <SHA-of-child-of-B> --not $GIT_COMMIT | wc -l) > 0 )) && git rm --cached --ignore-unmatch <filenames>'
这会产生我期望的那种输出:
...
Rewrite dc8a4b29463bfa43c2f3efe0c6e5a29a5cc6e0ef (1071/5680)rm 'file1'
rm 'file2'
rm 'file3'
rm 'file4'
...
在以(预期?)错误结束之前:
Rewrite e6b712b57257e2edd0bb9fbbac59e4c9d7b5aa79 (1072/5680)index filter failed: (( $(git rev-list e6b712b --not $GIT_COMMIT | wc -l) > 0 )) && git rm -rf --ignore-unmatch <filename>
e6b712b
的孩子在哪里B
。
在这一点上,我假设一切正常,所以我对我的存储库进行了本地文件系统克隆来测试它:
git clone file://<repo> <new repo>
对象的数量和包文件的大小减少了非常少 - 我不知道为什么。通过git count-objects -v
针对原始存储库filter-branch
运行与针对它运行的存储库:
原始存储库:
count: 0
size: 0
in-pack: 106640
packs: 1
size-pack: 815512
prune-packable: 0
garbage: 0
filter-branch
ed 和文件系统克隆的存储库:
count: 0
size: 0
in-pack: 96165
packs: 1
size-pack: 793656
prune-packable: 0
garbage: 0
我真的不确定为什么这仍然不起作用 - 也许我没有正确遵循建议的答案?