假设子模块的存储库确实包含您要使用的提交(与从超级项目的当前状态引用的提交不同),有两种方法可以做到这一点。
第一个要求您已经知道要使用的子模块的提交。它通过直接调整子模块然后更新超级项目来“从内到外”工作。第二个从“外部,内部”工作,通过查找修改子模块的超级项目提交,然后重置超级项目的索引以引用不同的子模块提交。
反了
如果您已经知道要让子模块使用哪个提交,请到cd
子模块,检查您想要的提交,然后git add
将git commit
其返回到超级项目中。
例子:
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'
糟糕,有人做了一个超级项目提交,它引用了子模块中未发布的提交sub
。不知何故,我们已经知道我们希望子模块处于 commit 状态5d5a3ee314476701a20f2c6ec4a53f88d651df6c
。去那里直接检查一下。
在子模块中结帐
$ cd sub
$ git checkout 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
Note: moving to '5d5a3ee314476701a20f2c6ec4a53f88d651df6c' which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
git checkout -b <new_branch_name>
HEAD is now at 5d5a3ee... quux
$ cd ..
由于我们正在检查一个提交,这会在子模块中产生一个分离的 HEAD。如果您想确保子模块正在使用一个分支,请使用git checkout -b newbranch <commit>
在提交时创建和签出一个分支或签出您想要的分支(例如,在提示处带有所需提交的分支)。
更新超级项目
子模块中的签出在超级项目中反映为对工作树的更改。所以我们需要在超级项目的索引中对变化进行分阶段并验证结果。
$ git add sub
检查结果
$ git submodule update
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
子模块更新是静默的,因为子模块已经在指定的提交处。第一个差异表明索引和工作树是相同的。第三个差异表明唯一的分阶段更改是将sub
子模块移动到不同的提交。
犯罪
git commit
这将提交固定的子模块条目。
外,内
如果您不确定应该从子模块中使用哪个提交,您可以查看超级项目中的历史来指导您。您还可以直接从超级项目管理重置。
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'
这与上述情况相同。但这一次我们将专注于从超级项目中修复它,而不是将其浸入子模块中。
查找超级项目的错误提交
$ git log --oneline -p -- sub
ce5d37c local change in sub
diff --git a/sub b/sub
index 5d5a3ee..e47c0a1 160000
--- a/sub
+++ b/sub
@@ -1 +1 @@
-Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
+Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
bca4663 added sub
diff --git a/sub b/sub
new file mode 160000
index 0000000..5d5a3ee
--- /dev/null
+++ b/sub
@@ -0,0 +1 @@
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
好的,看起来它在 中坏了ce5d37c
,所以我们将从其父模块 ( ce5d37c~
) 中恢复子模块。
或者,您可以从补丁文本 ( 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
) 中获取子模块的提交,并改用上述“由内而外”的过程。
在超级项目中结帐
$ git checkout ce5d37c~ -- sub
这会将子模块条目重置为在超级项目sub
中提交时的内容。ce5d37c~
更新子模块
$ git submodule update
Submodule path 'sub': checked out '5d5a3ee314476701a20f2c6ec4a53f88d651df6c'
子模块更新正常(它表示 HEAD 已分离)。
检查结果
$ git diff ce5d37c~ -- sub
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
第一个差异显示sub
现在在ce5d37c~
. 第二个差异表明索引和工作树是相同的。第三个差异显示唯一的分阶段更改是将sub
子模块移动到不同的提交。
犯罪
git commit
这将提交固定的子模块条目。