对于包含子模块的项目的CI构建,我想确保工作树与中央存储库中提交的状态完全匹配。
在获取并签出超级项目的修订版后,我执行以下步骤来更新子模块:
git submodule foreach 'git reset --hard && git clean -xdf'
git submodule update --init
这似乎适用于所有情况,除非在中央存储库中删除了子模块。在这种情况下,作业工作副本仍包含已删除的子模块。
此外,超级项目上的git clean -xdf
似乎没有触及陈旧的子模块。
那么,是否可以自动检测陈旧的本地子模块并将其删除?
答案 0 :(得分:1)
问题是你的repo的配置仍然完全被陈旧的子模块的数据所污染。我设法通过首先清理repo配置来使git clean -xdf
工作。
我从源代码使用git 1.8.1.3,但子模块删除仍然是一个主要问题。我完全失去了为什么任何子模块信息存储在repo配置中。我们完全停止使用它们,并改为子树合并。
假设陈旧的子模块位于目录foo
。
如果子模块仍在您的.git/config
文件中列出,但已从.gitmodules
中删除,则会在上游删除该子模块。你现在需要做4件事:
.git/config
rm foo/.git
rm -rf .git/modules/foo
git clean -xdf
答案 1 :(得分:0)
我已经提出了一个Perl脚本来清除子模块删除后的repo配置。不幸的是,它仅在过时子模块目录位于超级项目的根目录中时才有效。因为,猜测一下,在删除了子模块的git-link和.gitmodules条目后,git不存储它在树中的位置。即使repo配置完全脏,也不能使用清除删除所需的单个信息。为此编写git维护者是值得的。目前我建议每个人单独留下子模块。
无论如何,这是脚本。在此git clean -xdf
确实有效之后。诚实。 : - )
#!/usr/bin/perl
our %mods;
open MOD, ".gitmodules" or die $!;
while (<MOD>) {
if (/\[submodule "(.+)"\]/) {
$mods{$1} = 1;
}
}
close MOD;
rename ".git/config", ".git/config~" or die $!;
open BAK, ".git/config~";
unlink ".git/config~";
open CFG, ">.git/config";
our $print_on = 1;
while (<BAK>) {
if (/\[submodule "(.+)"\]/) {
$print_on = $mods{$1};
unlink "$1/.git" unless $print_on;
} elsif (/^\[/) {
$print_on = 1;
}
print CFG if $print_on;
}
close BAK;
close CFG;