重写子模块历史记录后包含子模块的存储库

Enz*_*nzo 11 git git-submodules

在重写了存储库的历史记录之后git filter-branch,所有的SHA都会发生变化.

现在,如果该存储库(让我们称之为X)被用作另一个存储库中的git子模块(让我们调用它Y),我们就遇到了问题.
实际上,Y根据该子模块X中提交的SHA 知道要加载的子模块的版本.由于X现在所有的SHA 都已发生变化,因此Y指向不再存在的SHA.

有没有办法重写它的历史Y,它指向子模块的新提交SHA X(在当前和过去的提交中)?

我猜想,鉴于旧的SHA和新的SHA之间的对应关系,原则上这是可能的,但我担心它会涉及令人讨厌的bash脚本.
还有什么比这更容易了

Von*_*onC 8

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

我担心会这样.

还有什么比这更容易了

从来没听说过.
以下是该脚本工作所需的一些线索(不是完整的脚本):

如果您仍然可以访问重写的仓库,则会保留其原始历史记录(过滤器分支之前).git/refs/original.

这意味着你可以循环旧的历史SHA1:

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

如果更改仅限于一个分支,则可以轻松地将新SHA1与旧SHA1匹配(第一个旧的SHA1与重写的分支的第一个提交匹配,第二个旧的匹配...等等)

如果没有,你将不得不寻找一个转速,以找到一个匹配(相同的日期,合理的提交消息)

git rev-list --all \
  | while read commit
 do
 ...
Run Code Online (Sandbox Code Playgroud)

确保父repo更新其子模块的引用:

cd parent/repo
cd asubmodule
git fetch
Run Code Online (Sandbox Code Playgroud)

这样,新的SHA1可用.

最后,您可以在父repo中执行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"
Run Code Online (Sandbox Code Playgroud)