Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git:跟踪子模块中的分支,但在其他子模块中提交(可能是嵌套的)_Git_Git Branch_Git Submodules - Fatal编程技术网

Git:跟踪子模块中的分支,但在其他子模块中提交(可能是嵌套的)

Git:跟踪子模块中的分支,但在其他子模块中提交(可能是嵌套的),git,git-branch,git-submodules,Git,Git Branch,Git Submodules,我正在寻找一种情况,在这种情况下,我有一个带有(可能是嵌套的子模块)的git结构。对于每个子模块,我想分别指定它们是否应该跟踪分支 (参见示例) 例如,我的项目可能如下所示: main.tex |- submod1 @ master | |-subsubmod1 @qsdf123 |- submod2 @ master | |-subsubmod2 @shasha12 |- submod3 @ qsdf321 现在,我想要一种更新子模块的方法 git submodule updat

我正在寻找一种情况,在这种情况下,我有一个带有(可能是嵌套的子模块)的git结构。对于每个子模块,我想分别指定它们是否应该跟踪分支 (参见示例)

例如,我的项目可能如下所示:

main.tex
|- submod1 @ master
|    |-subsubmod1 @qsdf123
|- submod2 @ master
|    |-subsubmod2 @shasha12
|- submod3 @ qsdf321
现在,我想要一种更新子模块的方法

git submodule update --recursive
将所有子模块更新为其上次记录的sha(即,它将对subsubmod1、subsubmod2和submod3起作用,但对其余部分执行错误操作)。 另一方面

git submodule update --recursive --remote
将所有子模块更新到关联的分支(默认情况下为master),也就是说,它将对submod1和submod2起作用,但对其余部分做错误的操作

有没有办法把这件事做好

作为对第一个答案的回应,我将澄清我所说的“做错事”是什么意思

这里有一个小例子

bartb@EB-Latitude-E5450~/桌面/测试$git init
已在/home/bartb/Desktop/test/.Git中初始化空Git存储库/
bartb@EB-Latitude-E5450~/Desktop/test$git子模块添加../remote/submod1
正在克隆到“submod1”。。。
完成。
bartb@EB-Latitude-E5450~/Desktop/test$git子模块添加../remote/submod2
克隆到“submod2”。。。
完成。
bartb@EB-Latitude-E5450~/桌面/测试$cd子模块1
bartb@EB-Latitude-E5450~/Desktop/test/submod1$git log
提交42d476962fc4e25c64ff2a807d2bf9b3e2ea31f8
作者:Bart Bogaerts
日期:2016年6月21日星期二08:56:05+0300
初始化提交
提交db1ba3bc4b02df4677f1197dc137ff36ddfeeb5f
作者:Bart Bogaerts
日期:2016年6月21日星期二08:55:52+0300
初始化提交
bartb@EB-Latitude-E5450~/Desktop/test/submod1$git签出db1ba3bc4b02df4677f1197dc137ff36ddfeeb5f
注意:正在签出“db1ba3bc4b02df4677f1197dc137ff36ddfeeb5f”。
你处于“分离的头部”状态。你可以环顾四周,做实验
更改并提交它们,您可以放弃在此过程中所做的任何提交
通过执行另一个签出,在不影响任何分支的情况下进行状态设置。
如果要创建新分支以保留创建的提交,可以
再次使用-b和checkout命令(现在或以后)执行此操作。示例:
git签出-b
HEAD现在位于db1ba3b…初始化提交
bartb@EB-Latitude-E5450~/Desktop/test/submod1$cd。。
bartb@EB-Latitude-E5450~/Desktop/test$git config-f.gitmodules submodule.submod2.branch master
bartb@EB-Latitude-E5450~/Desktop/test$git commit-a-m“模块”
[主(根提交)ea9e55f]模块
3个文件已更改,9个插入(+)
创建模式100644.git模块
创建模式160000子模块1
创建模式160000子模块2
bartb@EB-Latitude-E5450~/桌面/测试$git状态
论分行行长
没有要提交的内容,正在清理目录
bartb@EB-Latitude-E5450~/Desktop/test$git子模块更新--递归--远程
子模块路径“submod1”:签出“42d476962fc4e25c64ff2a807d2bf9b3e2ea31f8”
bartb@EB-Latitude-E5450~/桌面/测试$git状态
论分行行长
未为提交而暂存的更改:
(使用“git add…”更新将提交的内容)
(使用“git签出--…”放弃工作目录中的更改)
修改:submod1(新提交)
正如您所看到的,在最新的
git子模块更新之后,远程
submod1在主机上签出,尽管我从未为它配置过主机分支。这就是我所说的“做错事”的意思

子模块也会发生同样的情况:它们都在主模块上签出,而不是在特定的提交时签出

这个“问题”实际上是git子模块更新--remote的预期问题

This option is only valid for the update command. Instead of using the superproject’s recorded SHA-1 to update the submodule, use the status of the submodule’s remote-tracking branch. The remote used is branch’s remote (branch.<name>.remote), defaulting to origin. The remote branch used defaults to master, but the branch name may be overridden by setting the submodule.<name>.branch option in either .gitmodules or .git/config (with .git/config taking precedence).
这就是我想要避免的

编辑:另一个请求是:我不想对SubMod或SubSubMod进行任何修改(这些是联合项目)。

更新2020:

报告:

当前(2016年)的答案对子模块不太适用(不再适用),因为
$top/.gitmodules
不包含子模块(和子子子模块)的分支信息

新解决方案:

其中
git su
是我脚本的名称


2016年原始答复:

将所有子模块更新到关联的分支(默认情况下为master),也就是说,它将对submod1和submod2起作用,但对其余部分做错误的操作

事实上,是的,它会“为其他人做错误的事情”

我将使用git版本2.9.0.windows.1,通过下面的示例(名为
parent
的回购协议和子模块“
sub
”,本身和子模块“
subsub
”)来说明这个bug

我将提出一个简单的解决方案,允许
sub
遵循
master
,同时确保
subsub
不会在其自身的
master
上签出


安装程序 让我们通过两次提交进行回购
subsubsub

vonc@VONCAVN7 D:\git\tests\subm
> git init subsub1
Initialized empty Git repository in D:/git/tests/subm/subsub1/.git/
> cd subsub1
> git commit --allow-empty -m "subsub c1"
[master (root-commit) f3087a9] subsub c1
> git commit --allow-empty -m "subsub c2"
[master 03d08cc] subsub c2
让我们将该回购
subsub
设为另一回购'
sub
'的子模块:

vonc@VONCAVN7 D:\git\tests\subm
> git init sub
Initialized empty Git repository in D:/git/tests/subm/sub/.git/

> cd sub
> git submodule add -- ../subsub
Cloning into 'D:/git/tests/subm/sub/subsub'...
done.
vonc@VONCAVN7 D:\git\tests\subm\sub\subsub
> cd ..
vonc@VONCAVN7 D:\git\tests\subm\sub
> git add .
> git commit -m "subsub at HEAD-1"
[master (root-commit) 1b8144b] subsub at HEAD-1
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 subsub
vonc@VONCAVN7 D:\git\tests\subm\sub
> git commit --allow-empty -m "sub c1"
[master b7d1c40] sub c1
> git commit --allow-empty -m "sub c2"
[master c77f4b2] sub c2

vonc@VONCAVN7 D:\git\tests\subm\sub
> gl
* c77f4b2  - (HEAD -> master) sub c2 (2 seconds ago) VonC
* b7d1c40  - sub c1 (3 seconds ago) VonC
* 1b8144b  - subsub at HEAD-1 (77 seconds ago) VonC
默认情况下,该子模块“
subsubsub
”将在其自己的
master
HEAD()处签出:

让我们确保
sub
已在
c1
处签出
subsub
(这不是
master HEAD C2
):

让我们将子模块“
subsub
”(在
master~1
c1
)添加并提交到其父repo“
sub
”:

vonc@VONCAVN7 D:\git\tests\subm
> git init sub
Initialized empty Git repository in D:/git/tests/subm/sub/.git/

> cd sub
> git submodule add -- ../subsub
Cloning into 'D:/git/tests/subm/sub/subsub'...
done.
vonc@VONCAVN7 D:\git\tests\subm\sub\subsub
> cd ..
vonc@VONCAVN7 D:\git\tests\subm\sub
> git add .
> git commit -m "subsub at HEAD-1"
[master (root-commit) 1b8144b] subsub at HEAD-1
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 subsub
vonc@VONCAVN7 D:\git\tests\subm\sub
> git commit --allow-empty -m "sub c1"
[master b7d1c40] sub c1
> git commit --allow-empty -m "sub c2"
[master c77f4b2] sub c2

vonc@VONCAVN7 D:\git\tests\subm\sub
> gl
* c77f4b2  - (HEAD -> master) sub c2 (2 seconds ago) VonC
* b7d1c40  - sub c1 (3 seconds ago) VonC
* 1b8144b  - subsub at HEAD-1 (77 seconds ago) VonC
让我们在该回购协议的子协议中添加两个提交:

vonc@VONCAVN7 D:\git\tests\subm
> git init sub
Initialized empty Git repository in D:/git/tests/subm/sub/.git/

> cd sub
> git submodule add -- ../subsub
Cloning into 'D:/git/tests/subm/sub/subsub'...
done.
vonc@VONCAVN7 D:\git\tests\subm\sub\subsub
> cd ..
vonc@VONCAVN7 D:\git\tests\subm\sub
> git add .
> git commit -m "subsub at HEAD-1"
[master (root-commit) 1b8144b] subsub at HEAD-1
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 subsub
vonc@VONCAVN7 D:\git\tests\subm\sub
> git commit --allow-empty -m "sub c1"
[master b7d1c40] sub c1
> git commit --allow-empty -m "sub c2"
[master c77f4b2] sub c2

vonc@VONCAVN7 D:\git\tests\subm\sub
> gl
* c77f4b2  - (HEAD -> master) sub c2 (2 seconds ago) VonC
* b7d1c40  - sub c1 (3 seconds ago) VonC
* 1b8144b  - subsub at HEAD-1 (77 seconds ago) VonC
sub
的最新提交在右侧提交时引用了其子模块“
subsubsub
”(subsub
c1
one,而不是
c2
one)

最后,让我们制作一个主父回购“
parent
”,并添加“
sub
”作为子模块:

vonc@VONCAVN7 D:\git\tests\subm
> git init parent
Initialized empty Git repository in D:/git/tests/subm/parent/.git/
> cd parent

vonc@VONCAVN7 D:\git\tests\subm\parent
> git submodule add -- ../sub
Cloning into 'D:/git/tests/subm/parent/sub'...
done.
让我们确保
sub
未在其
master
头部签出(就像我们之前对
subsub
所做的那样)

现在,我们将
sub
(在其
c1
commit处签出,而不是在其
c2主节点
头部签出)添加到
父节点
repo:

vonc@VONCAVN7 D:\git\tests\subm\parent
> git add .
> git st
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   .gitmodules
        new file:   sub


vonc@VONCAVN7 D:\git\tests\subm\parent
> git commit -m "sub at c1"
[master (root-commit) 27374ec] sub at c1
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 sub

缺陷: 如果我克隆回购协议
vonc@VONCAVN7 D:\git\tests\subm\parent
> git config -f .gitmodules submodule.sub.branch master
> git diff
diff --git a/.gitmodules b/.gitmodules
index 8688a8c..97974c1 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,4 @@
 [submodule "sub"]
        path = sub
        url = ../sub
+       branch = master

vonc@VONCAVN7 D:\git\tests\subm\parent
> git add .
> git commit -m "sub follows master"
[master 2310a02] sub follows master
 1 file changed, 1 insertion(+)

vonc@VONCAVN7 D:\git\tests\subm\parent
> gl
* 2310a02  - (HEAD -> master) sub follows master (1 second ago) VonC
* 27374ec  - sub at c1 (2 minutes ago) VonC
vonc@VONCAVN7 D:\git\tests\subm
> git clone --recursive parent p1
Cloning into 'p1'...
done.
Submodule 'sub' (D:/git/tests/subm/sub) registered for path 'sub'
Cloning into 'D:/git/tests/subm/p1/sub'...
done.
Submodule path 'sub': checked out 'b7d1c403edaddf6a4c00bbbaa8e2dfa6ffbd112f'
Submodule 'subsub' (D:/git/tests/subm/subsub) registered for path 'sub/subsub'
Cloning into 'D:/git/tests/subm/p1/sub/subsub'...
done.
Submodule path 'sub/subsub': checked out 'f3087a9bc9b743625e0799f57c017c82c50e35d6'
vonc@VONCAVN7 D:\git\tests\subm\p1
> git submodule update --recursive --remote
Submodule path 'sub': checked out 'c77f4b2590794e030ec68a8cea23ae566701d2de'
Submodule path 'sub/subsub': checked out '03d08cc81e3b9c0734b8f53fad03ea7b1f0373df'
vonc@VONCAVN7 D:\git\tests\subm\p1\sub
> git ls-tree @
100644 blob 25a0feba7e1c1795be3b8e7869aaa5dba29d33e8    .gitmodules
160000 commit f3087a9bc9b743625e0799f57c017c82c50e35d6  subsub
vonc@VONCAVN7 D:\git\tests\subm\p1\sub
> git submodule update --recursive
Submodule path 'subsub': checked out 'f3087a9bc9b743625e0799f57c017c82c50e35d6'
#!/bin/bash
git submodule update --recursive --remote
export top=$(pwd)
git submodule foreach --recursive 'b=$(git config -f ${top}/.gitmodules submodule.${path}.branch); case "${b}" in "") git checkout ${sha1};; esac'
cd /path/to/parent/repo
git subupd
vonc@VONCAVN7 D:\git\tests\subm\p1
> git subupd
Submodule path 'sub/subsub': checked out '03d08cc81e3b9c0734b8f53fad03ea7b1f0373df'
Entering 'sub'
Entering 'sub/subsub'
Previous HEAD position was 03d08cc... subsub c2
HEAD is now at f3087a9... subsub c1
export top=$(pwd)
git submodule foreach --recursive \
  'b=$(git config -f ${top}/.gitmodules submodule.${path}.branch); \
   case "${b}" in \
     "") git checkout ${sha1};; \
      *) git checkout ${b}; git pull origin ${b};; \
   esac'