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

Git hook for updating Git submodule on branch change

我正在处理一些使用 Git 子模块的旧代码。该代码有几个正在积极使用的不同分支,不幸的是,这些分支中的每一个都依赖于相关子模块的不同修订版; this has made development extremely complicated。我面临的问题之一是,当我在分支之间切换时,例如masternewfeature-foo 使用 git checkout newfeature-foo,子模块的状态保持在 master 的状态,这通常会导致编译错误,甚至更糟糕的是会导致运行时行为的差异,从而造成严重破坏通过用户测试和一般理智。

例如,给定 .gitmodules 配置:

[submodule "robotcontroller"]
    path = robotcontroller
    url = https://coolrobots.com/repos/robotcontroller
    branch = master
    ignore = dirty

有没有办法使用 Git 挂钩强制自动完全重新检出 .gitmodules 文件中列出的所有子模块,当它在检出 "root" Git 存储库时发生变化?

听起来您的回购协议中发生了很多事情,使事情变得混乱。我们可以反复多次来找到有冲突的设置,但我会这样做:

去掉ignore = dirty

这只是隐藏了有用的信息——也许子模块没有彻底检出,因为它会覆盖文件。至少,在尝试对其进行任何操作之前确认子模块是干净的 - cd mysubmodulegit status = clean

post-checkout 钩子删除 robotcontroller 并更新所有子模块。

#!/bin/sh

# post-checkout hook that update submodules

prev_HEAD=""
new_HEAD=""
new_branch=""

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

   git submodule update
fi

exit 0

PS。根 Git 存储库的正确术语是 "superproject"。 :-)