重写子模块历史记录后的仓库及其子模块

15
使用git filter-branch重写仓库历史后,所有的SHA都会发生变化。
现在,如果这个仓库(我们称之为X)作为git子模块被另一个仓库(我们称之为Y)使用,那么就会出现问题。 实际上,根据子模块中提交的SHA,Y知道要加载哪个版本的子模块X。由于X中的所有SHA都已经改变,Y指向的SHA已经不存在了。
是否有一种方法可以重写Y的历史记录,使其指向子模块X的新提交SHA(包括当前和过去的提交)?
我猜想原则上可以通过给出旧SHA和新SHA之间的对应关系来实现,但我担心可能涉及到复杂的bash脚本。 是否有更简单的方法?
1个回答

9

但我担心它会涉及令人讨厌的bash脚本。

恐怕是这样的。

有更简单的方法吗?

据我所知没有。
以下是一些提示(不是完整的脚本),您需要使用这个脚本才能正常工作:

如果您仍然可以访问重写后的存储库,则其原始历史记录(即filter-branch之前)保存在.git/refs/original中。

这意味着您可以循环查找旧的历史记录SHA1:

 git -C /path/to/rewritten/repo for-each-ref --format="%(refname)" refs/original

如果更改仅限于一个分支,您可以轻松地将新的SHA1与旧的匹配(第一个旧的与重写分支的第一个提交相匹配,第二个旧的...以此类推)
如果不是,则必须查找revs以找到匹配项(相同的日期,相同的提交消息)
git rev-list --all \
  | while read commit
 do
 ...

确保父仓库更新其子模块的引用:
cd parent/repo
cd asubmodule
git fetch

这样,新的SHA1就可以使用了。

最后,在父仓库中进行filter-branch操作,查找一个gitlink索引中的特殊条目,匹配旧的SHA1之一。

对于每个匹配项,您在子模块文件夹中检出新的SHA1,返回到父仓库并添加和提交:这将记录一个新的gitlink SHA1。

cd parent/repo/asubmodule
git checkout <new SHA1>
cd ..
git add .
git commit -m "Record new SHA1 for asubmodule"

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