不分离磁头的 Git 子模块替换



我的情况:我有大量的计算机用于各种任务。我有大量的库,每个库都有自己的git repo。

我的愿望:我希望能够修改任何计算机上的一个库,执行gitcommit/push;然后转到另一台计算机,执行git pull,并更新所有库。然后我修改其中一个库,提交/推送,当我到达下一台计算机时,一切都正常了。

我目前的尝试:我有一个顶级git项目,它将所有其他库repo作为子模块合并在一起。这包括一个.gitmodules文件,该文件通过使用指定每个模块的工作分支

git config -f .gitmodules submodule.modulename.branch develop

我为每个模块设置了update = merge。我将submodule.recurse设置为true,因此顶层的git pull对每个模块执行操作

它是如何被打破的:头部变得分离。我编写了一个脚本,解析.gitmodules文件,并对每个模块的相应分支执行checkout。然后CCD_ 7和CCD_。每当我修改东西并尝试拉动时,例如在另一台机器上,头部就会分离。如果我在开始修改之前没有注意到头部脱落,我必须仔细解读残骸,然后才能进行修改。

在过去的十年里,关于git分离头,确实存在3.6k堆栈溢出问题,而且大多数问题似乎来自子模块功能。我还没有全部经历过,但我所尝试的并不奏效。

我忘了为什么我拒绝了git-subtree,但git-subrepo已经一年多没有被接触了,有153个问题和25个拉取请求悬而未决,所以我认为它已经死了。

有人对此有有效的解决方案吗?


@vonC接受的答案看起来不错

我可能会简化一下,但我对顶级项目的自述现在说:

建议结账:

git clone --recursive --jobs=8 *mysuperproject_clone_url*
cd *mysuperproject*
git config alias.pullall 'submodule foreach git pull'
git config alias.statusall 'submodule foreach git status'
git config alias.switchall 
"submodule foreach --recursive 'git switch $(git config -f ${toplevel}/.gitmodules submodule.${sm_path}.branch)'"
git switchall

从存储库更新

git pullall

如果头部脱落,用

git switchall

添加模块

在以下示例中,名为newmodule的模块在路径develop上工作。

cd /path/to/mysuperproject
git submodule add git@github.com:myaccount/newmodule
git config -f .gitmodules submodule.newmodule.branch develop
git config -f .gitmodules submodule.newmodule.update merge

如果子模块位于默认的master分支上,则仍然需要配置该分支。

如果您将子模块切换到不同的分支,那么在顶级中,您必须再次配置

git config -f .gitmodules submodule.newmodule.branch newbranch

并推动子模块和顶级项目。

在不同的工作目录上(例如在不同的机器上(,您必须

cd /path/to/mysuperproject
git pull
git switchall
git pullall

我之前提到git submodule update --remote --merge应该而不是分离分支之后的子模块的HEAD。

我知道您已经设置了update = merge,但只是为了测试,请尝试完整的update命令,看看这是否有效。

由于HEAD仍然是分离的,您需要添加(例如添加到git别名脚本中(命令

git submodule foreach --recursive git switch $(git config -f .gitmodules submodule.${sm_path}.branch)

我刚刚测试过:

首先,在Git存储库中,我检查子模块是否处于分离的HEAD模式:

vonc@vclp MINGW64 ~/git/git (master)
$ git submodule update --init
Submodule 'sha1collisiondetection' (https://github.com/cr-marcstevens/sha1collisiondetection.git) registered for path 'sha1collisiondetection'
Cloning into 'C:/Users/vonc/git/git/sha1collisiondetection'...
Submodule path 'sha1collisiondetection': checked out '855827c583bc30645ba427885caa40c5b81764d2'

vonc@vclp MINGW64 ~/git/git/sha1collisiondetection (master)
$ git br
* (HEAD detached at 855827c)
master

然后我用转义的$:$定义我的别名
访问.gitmodules文件时不需要../。这就是$toplevel的作用。

vonc@vclp MINGW64 ~/git/git (master)
$ git config alias.switchall 
"submodule foreach --recursive 'git switch $(git config -f ${toplevel}/.gitmodules submodule.${sm_path}.branch)'"

最终测试:

vonc@vclp MINGW64 ~/git/git (master)
$ git switchall
Entering 'sha1collisiondetection'
Previous HEAD position was 855827c Detect endianess on HP-UX
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
vonc@vclp MINGW64 ~/git/git (tmp)
$ cd sha1collisiondetection/
vonc@vclp MINGW64 ~/git/git/sha1collisiondetection (master)
$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
vonc@vclp MINGW64 ~/git/git/sha1collisiondetection (master)
$ git branch
* master

最新更新