假设子模块的存储库确实包含您想要使用的提交(与从超级项目的当前状态引用的提交不同),有两种方法可以做到这一点。
第一种方法要求您已经知道要使用的子模块的提交。它通过直接调整子模块,然后更新超级项目,从“内向外”工作。第二种方法从“由外而内”的方式工作,找到修改子模块的超级项目提交,然后重置超级项目的索引以引用不同的子模块提交。
内,
如果你已经知道你想让子模块使用哪个提交,cd到子模块,检查你想要的提交,然后git添加和git在超级项目中提交它。
例子:
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'
哎呀,有人做了一个超级项目提交,引用子模块sub中未发布的提交。不知怎么的,我们已经知道我们想让子模块在提交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
子模块更新是静默的,因为子模块已经处于指定的提交状态。第一个差异表明索引和工作树是相同的。第三个差异表明,唯一的阶段性变化是将子子模块移动到不同的提交。
提交
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'
子模块更新OK(它表示一个分离的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
第一个差异表明子现在在ce5d37c~中是相同的。第二个差异表明索引和工作树是相同的。第三个差异显示唯一的阶段性变化是将子子模块移动到不同的提交。
提交
git commit
这将提交已修复的子模块条目。