假定子模块的存储库中确实包含您要使用的提交(与从超级项目的当前状态引用的提交不同),有两种方法可以实现。
第一个要求您已经知道要使用的子模块中的提交。它通过直接调整子模块然后更新超级项目而从“由内而外”工作。第二个工作是从“外部,内部”进行的,方法是找到修改了子模块的超级项目的提交,然后重置超级项目的索引以引用另一个子模块的提交。
反了
如果你已经知道其呈交你想要的子模块来使用,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
这将提交固定的子模块条目。