Git钩子,用于在分支更改时更新Git子模块

Git钩子,用于在分支更改时更新Git子模块,git,branch,git-submodules,githooks,Git,Branch,Git Submodules,Githooks,我正在使用一些使用Git子模块的旧代码。该代码有几个正在积极使用的分支,每个分支都依赖于相关子模块的不同版本。我面临的一个问题是,当我使用git checkout newfeature foo在分支之间从master切换到newfeature foo时,子模块的状态保持在master的状态,这通常会导致编译错误,甚至更糟的是,可能会导致运行时行为的差异,从而破坏用户测试和一般的正常运行 例如,给定.gitmodules配置: [submodule "robotcontroller"] p

我正在使用一些使用Git子模块的旧代码。该代码有几个正在积极使用的分支,每个分支都依赖于相关子模块的不同版本。我面临的一个问题是,当我使用
git checkout newfeature foo
在分支之间从
master
切换到
newfeature foo
时,子模块的状态保持在
master
的状态,这通常会导致编译错误,甚至更糟的是,可能会导致运行时行为的差异,从而破坏用户测试和一般的正常运行

例如,给定
.gitmodules
配置:

[submodule "robotcontroller"]
    path = robotcontroller
    url = https://coolrobots.com/repos/robotcontroller
    branch = master
    ignore = dirty
  • 提交77d4697处的分支
    master
    引用了
    robotcontroller@f57d1b3
  • b38d29f的分支
    newfeature foo
    引用了
    robotcontroller@60b27d4
  • 873639f处的分支
    主机
    根本没有子模块
    机器人控制器
  • 301dca4的分支
    newfeature foo
    引用了
    robotcontroller@bdf5991

例如,在签出“根”Git存储库时,是否无法使用Git钩子强制自动完全重新签出
.gitmodules
文件中列出的所有子模块?

听起来您的repo中有很多事情让人困惑。我们可以反复检查,找出相互冲突的设置,但我会这样做:

摆脱
ignore=dirty

这只是隐藏了有用的信息——可能子模块没有完全签出,因为它会覆盖文件。至少,在尝试对子模块执行任何操作之前,请确认子模块是干净的-
cd mysubmodule
git status
=clean

签出后
移除
机器人控制器
并更新所有子模块的钩子

#!/bin/sh

# post-checkout hook that update submodules

prev_HEAD="$1"
new_HEAD="$2"
new_branch="$3"

if [ "$new_branch" = 1 ]; then
   if ! grep -Fq robotcontroller .gitmodules; then
      rm -rf robotcontroller
   fi

   git submodule update
fi

exit 0

注:根Git存储库的正确术语是“超级项目”。-)

如果签出更改了分支,则可以在签出后挂钩中使用
git子模块更新
。子模块在某些提交中消失的事实使得这一点更加棘手。
git checkout——递归子模块newfeature foo
,还是我遗漏了什么?@Mort如果你不知道存储库有子模块,或者如果你整天都在处理大量不同的存储库,那个额外的——递归子模块非常烦人。好吧,不过你们可以把它放到你们的问题中去。“这个问题已有一个简单的解决方案,但我觉得它很烦人,原因如下……我想要一个具有以下更简单属性的不同解决方案……”你确定你在回答这个问题吗?谢谢;这比我担心的要容易。您是否知道一种优雅的方法可以将其推广到
.gitmodules
中的任何和所有潜在条目?我不能总是知道存在什么子模块名,在
sh
脚本中编写定制逻辑来解析
。gitmodules
会很麻烦。正如@torek所说的,这会更棘手。比较
prev\u HEAD
new\u HEAD
中的
.gitmodules
(并解析差异),或者列出所有可能的子模块,并在
.gitmodules
中逐个grep。