重写子模块历史后的子模块存储库
Repository with submodules after rewriting history of submodule
用 git filter-branch
重写存储库的历史后,所有 SHA 都发生了变化。
现在,如果该存储库(我们称之为 X
)用作另一个存储库(我们称之为 Y
)中的 git 子模块,我们就会遇到问题。
事实上,Y
知道根据该子模块中提交的 SHA 加载哪个版本的子模块 X
。由于 X
中的所有 SHA 现在都已更改,因此 Y
指向不再存在的 SHA。
有没有办法重写 Y
的历史,使其指向子模块 X
的新提交 SHA(包括当前和过去的提交)?
我猜想鉴于旧 SHA 和新 SHA 之间的对应关系,这在原则上是可能的,但我担心它会涉及讨厌的 bash 脚本。
有没有更简单的?
but I am afraid it would involve nasty bash scripts.
恐怕是的。
Is there anything easier?
据我所知没有。
以下是该脚本运行所需的一些线索(不是完整的脚本):
如果您仍然可以访问重写的回购协议,其原始历史记录(在过滤器分支之前)保存在.git/refs/original
。
这意味着您可以循环查找旧历史 SHA1:
git -C /path/to/rewritten/repo for-each-ref --format="%(refname)" refs/original
如果更改仅限于一个分支,您可以轻松地将新 SHA1 与旧 SHA1 匹配(第一个旧的匹配重写分支的第一次提交,第二个旧的...等等)
如果没有,您将不得不寻找一个 revs 以找到匹配项(同一日期,合理的提交消息)
git rev-list --all \
| while read commit
do
...
确保父仓库更新了子模块的引用:
cd parent/repo
cd asubmodule
git fetch
这样,新的 SHA1 就可用了。
最后,您可以在父存储库中执行过滤分支,查找 gitlink, special entry in the index,匹配旧 SHA1 之一。
对于每个匹配项,您在子模块文件夹中检出新的 SHA1,返回到父存储库的上一级,添加并提交:这将记录一个新的 gitlink SHA1。
cd parent/repo/asubmodule
git checkout <new SHA1>
cd ..
git add .
git commit -m "Record new SHA1 for asubmodule"
用 git filter-branch
重写存储库的历史后,所有 SHA 都发生了变化。
现在,如果该存储库(我们称之为 X
)用作另一个存储库(我们称之为 Y
)中的 git 子模块,我们就会遇到问题。
事实上,Y
知道根据该子模块中提交的 SHA 加载哪个版本的子模块 X
。由于 X
中的所有 SHA 现在都已更改,因此 Y
指向不再存在的 SHA。
有没有办法重写 Y
的历史,使其指向子模块 X
的新提交 SHA(包括当前和过去的提交)?
我猜想鉴于旧 SHA 和新 SHA 之间的对应关系,这在原则上是可能的,但我担心它会涉及讨厌的 bash 脚本。
有没有更简单的?
but I am afraid it would involve nasty bash scripts.
恐怕是的。
Is there anything easier?
据我所知没有。
以下是该脚本运行所需的一些线索(不是完整的脚本):
如果您仍然可以访问重写的回购协议,其原始历史记录(在过滤器分支之前)保存在.git/refs/original
。
这意味着您可以循环查找旧历史 SHA1:
git -C /path/to/rewritten/repo for-each-ref --format="%(refname)" refs/original
如果更改仅限于一个分支,您可以轻松地将新 SHA1 与旧 SHA1 匹配(第一个旧的匹配重写分支的第一次提交,第二个旧的...等等)
如果没有,您将不得不寻找一个 revs 以找到匹配项(同一日期,合理的提交消息)
git rev-list --all \
| while read commit
do
...
确保父仓库更新了子模块的引用:
cd parent/repo
cd asubmodule
git fetch
这样,新的 SHA1 就可用了。
最后,您可以在父存储库中执行过滤分支,查找 gitlink, special entry in the index,匹配旧 SHA1 之一。
对于每个匹配项,您在子模块文件夹中检出新的 SHA1,返回到父存储库的上一级,添加并提交:这将记录一个新的 gitlink SHA1。
cd parent/repo/asubmodule
git checkout <new SHA1>
cd ..
git add .
git commit -m "Record new SHA1 for asubmodule"