git 不分离磁头的子模块替换
git submodule replacement that doesn't detach heads
我的情况:我有大量计算机用于各种任务。我有大量的库,每个库都有自己的 git 存储库。
我的愿望:我希望能够在任何一台计算机上修改其中一个库,做一个git commit/push;然后转到另一台计算机,执行 git pull
,并更新所有库。然后我修改其中一个库,commit/push,当我到达下一台计算机时一切正常。
我目前的尝试:我有一个顶级 git 项目,它将所有其他库 repos 作为子模块合并。这包括一个 .gitmodules 文件,该文件使用
指定每个模块的工作分支
git config -f .gitmodules submodule.modulename.branch develop
我为每个模块设置了 update = merge
。
我将 submodule.recurse
设置为 true,因此顶层的 git pull
会对每个模块执行 某些操作 。
它是怎么坏的: 脑袋掉了。我编写了一个脚本来解析 .gitmodules
文件并对每个模块的适当分支执行 checkout
。然后我 commit
和 push
顶层模块。每当我修改东西并尝试拉动时,例如在另一台机器上,磁头分离。如果我在开始修改之前没有注意到头部脱落,我必须在提交更改之前仔细地整理残骸。
在过去的十年里,关于 git 分离头的堆栈溢出问题确实有 3600 个,而且大多数似乎来自子模块功能。我还没有完成所有这些,但是我尝试过的方法没有用。
我忘记了我为什么拒绝 git-subtree
,但是 git-subrepo
已经一年多没有被触及了,有 153 个问题和 25 个 pull requests 待处理,所以我认为它已经死了。
有人对此有可行的解决方案吗?
@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
我 mentioned before git submodule update --remote --merge
应该 而不是 分离分支后子模块的 HEAD。
我知道你已经设置了 update = merge
,但只是为了测试,请尝试完整的更新命令,看看是否有效。
由于 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
我的情况:我有大量计算机用于各种任务。我有大量的库,每个库都有自己的 git 存储库。
我的愿望:我希望能够在任何一台计算机上修改其中一个库,做一个git commit/push;然后转到另一台计算机,执行 git pull
,并更新所有库。然后我修改其中一个库,commit/push,当我到达下一台计算机时一切正常。
我目前的尝试:我有一个顶级 git 项目,它将所有其他库 repos 作为子模块合并。这包括一个 .gitmodules 文件,该文件使用
指定每个模块的工作分支git config -f .gitmodules submodule.modulename.branch develop
我为每个模块设置了 update = merge
。
我将 submodule.recurse
设置为 true,因此顶层的 git pull
会对每个模块执行 某些操作 。
它是怎么坏的: 脑袋掉了。我编写了一个脚本来解析 .gitmodules
文件并对每个模块的适当分支执行 checkout
。然后我 commit
和 push
顶层模块。每当我修改东西并尝试拉动时,例如在另一台机器上,磁头分离。如果我在开始修改之前没有注意到头部脱落,我必须在提交更改之前仔细地整理残骸。
在过去的十年里,关于 git 分离头的堆栈溢出问题确实有 3600 个,而且大多数似乎来自子模块功能。我还没有完成所有这些,但是我尝试过的方法没有用。
我忘记了我为什么拒绝 git-subtree
,但是 git-subrepo
已经一年多没有被触及了,有 153 个问题和 25 个 pull requests 待处理,所以我认为它已经死了。
有人对此有可行的解决方案吗?
@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
我 mentioned before git submodule update --remote --merge
应该 而不是 分离分支后子模块的 HEAD。
我知道你已经设置了 update = merge
,但只是为了测试,请尝试完整的更新命令,看看是否有效。
由于 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