如何用Git filter-branch/filter-repo更新子模块Git链接?
问题:仓库中子模块历史重写后更新Git链接
我有一个Git仓库A,它依赖子模块B。子模块B在LFS迁移后历史被重写,我希望仓库A的完整历史仍能正常使用。现在我已经拿到了B的OldSHA1→NewSHA1映射表,需要在A中将旧的Git链接从OldSHA1替换为NewSHA1。
已尝试的方法
方法1:使用filter-repo
我尝试在仓库A上运行带完整OldSHA1==>NewSHA1映射参数的filter-repo命令,但它似乎无法识别Git链接。
方法2:使用filter-branch
我参考相关教程尝试了filter-branch命令,先测试单个OldSHA1=>NewSHA1映射,执行的命令如下:
git filter-branch --commit-filter ' if [ "$GIT_COMMIT" = <OLDSHA1> ]; then cd <SUBMODULE_ABSOLUTE_PATH>; git checkout <NEWSHA1>; cd ..; git add -u; git commit -m "updated gitlink"; else git commit-tree "$@"; fi' HEAD
遇到的错误
执行上述命令后持续收到以下错误:
fatal: reference is not a tree: <NEWSHA1>
即使改用git -C <子模块绝对路径> checkout指定路径,仍出现相同错误。
我的问题
- 我是否存在明显的操作错误?
- 是否有更好的实现方法?我只是想在对象数据库中替换字符串,但找不到简单的方式。
- 是否有像filter-repo那样能在整个仓库执行的方法?还是需要在每个分支单独运行?
感谢任何帮助、建议或实现思路!
编辑1
根据建议修改脚本为:
git filter-branch --commit-filter ' if [ "$GIT_COMMIT" = <SpecificCommitID> ]; then git update-index --add --cacheinfo 160000,<SpecificNewSha1>,<SubmodulePath>; fi git commit-tree "$@"; ' HEAD
但没有效果,提示:
WARNING: Ref 'refs/heads/develop' is unchanged
编辑2
非常感谢用户@torek!以下是可用的代码片段:
git filter-branch --index-filter ' if [ "$(git rev-parse --quiet --verify :<SUBMODULEPATH>)" = <OLDSHA1> ]; then git update-index --cacheinfo 160000,<NEWSHA1>,<SUBMODULEPATH>; fi' HEAD --all
之后你需要遍历所有OldSHA1/NewSHA1对,或者使用回答中提到的case字典。再次感谢!
内容的提问来源于stack exchange,提问作者Bibzball
相关产品推荐
相关产品推荐

