Mau*_*fer 301 git git-submodules
我有一个带有子模块的项目,该子模块指向无效的提交:子模块提交仍然是本地的,当我尝试从另一个repo获取它时,我得到:
$ git submodule update
fatal: reference is not a tree: 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
Unable to checkout '2d7cfbd09fc96c04c4c41148d44ed7778add6b43' in submodule path 'mysubmodule'
Run Code Online (Sandbox Code Playgroud)
我知道子模块HEAD应该是什么,有什么办法,我可以在当地改变这一状况,在不脱离回购推确实已经提交2d7cfbd09fc96c04c4c41148d44ed7778add6b43
?
Chr*_*sen 377
假设子模块的存储库确实包含您要使用的提交(与从超级项目的当前状态引用的提交不同),有两种方法可以执行此操作.
第一个要求您已经知道要使用的子模块的提交.它通过直接调整子模块然后更新超级项目从"内部,外部"工作.第二个工作来自"外部,中",通过查找超级项目的修改子模块的提交,然后重置超级项目的索引来引用不同的子模块提交.
如果你已经知道其呈交你想要的子模块使用,cd
子模块,检查出你想要的承诺,那么git add
和git commit
它放回超级项目.
例:
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'
Run Code Online (Sandbox Code Playgroud)
哎呀,有人做了一个超级项目提交,它引用了子模块中未发布的提交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 ..
Run Code Online (Sandbox Code Playgroud)
由于我们正在检查提交,因此在子模块中生成一个分离的HEAD.如果要确保子模块正在使用分支,则使用git checkout -b newbranch <commit>
在提交时创建和签出分支或签出所需的分支(例如,在提示处具有所需提交的分支).
子模块中的结账在超级项目中反映为对工作树的更改.因此,我们需要在超级项目的索引中进行更改并验证结果.
$ git add sub
Run Code Online (Sandbox Code Playgroud)
$ 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
Run Code Online (Sandbox Code Playgroud)
子模块更新是静默的,因为子模块已经在指定的提交中.第一个差异显示索引和工作树是相同的.第三个差异表明,唯一的分阶段变化是将sub
子模块移动到另一个提交.
git commit
Run Code Online (Sandbox Code Playgroud)
这将提交修复后的子模块条目.
如果您不确定应该从子模块中使用哪个提交,则可以查看超级项目中的历史记录以指导您.您还可以直接从超级项目管理重置.
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'
Run Code Online (Sandbox Code Playgroud)
这与上述情况相同.但这一次我们将重点从超级项目中修复它,而不是浸入子模块中.
$ 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
Run Code Online (Sandbox Code Playgroud)
好吧,它看起来很糟糕ce5d37c
,所以我们将从其父(ce5d37c~
)恢复子模块.
或者,您可以从补丁文本(5d5a3ee314476701a20f2c6ec4a53f88d651df6c
)中获取子模块的提交,并使用上面的"内部,外部"过程.
$ git checkout ce5d37c~ -- sub
Run Code Online (Sandbox Code Playgroud)
这sub
会将子模块条目重置为ce5d37c~
超级项目中提交的内容.
$ git submodule update
Submodule path 'sub': checked out '5d5a3ee314476701a20f2c6ec4a53f88d651df6c'
Run Code Online (Sandbox Code Playgroud)
子模块更新正常(它表示已分离的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
Run Code Online (Sandbox Code Playgroud)
第一个差异显示sub
现在是相同的ce5d37c~
.第二个差异显示索引和工作树是相同的.第三个差异显示唯一的分阶段变化是将sub
子模块移动到另一个提交.
git commit
Run Code Online (Sandbox Code Playgroud)
这将提交修复后的子模块条目.
小智 187
试试这个:
git submodule sync
git submodule update
Run Code Online (Sandbox Code Playgroud)
Dan*_*dok 16
此错误可能意味着子模块中缺少提交.也就是说,存储库(A)具有子模块(B).A想要加载B以使其指向某个提交(在B中).如果该提交以某种方式丢失,您将得到该错误.一旦可能的原因:对提交的引用被推入A,但是实际的提交没有从B推出.所以我从那里开始.
不太可能,存在权限问题,并且无法提取提交(如果您使用git + ssh,则可能).
确保子模块路径在.git/config和.gitmodules中看起来正常.
最后一件事 - 在子模块目录中:git reset HEAD --hard
chr*_*lly 10
这可能发生在:
例如这样的事情发生了:
$ cd submodule
$ emacs my_source_file # edit some file(s)
$ git commit -am "Making some changes but will forget to push!"
Run Code Online (Sandbox Code Playgroud)
此时应该有子模块.
$ cd .. # back to parent repository
$ git commit -am "updates to parent repository"
$ git push origin master
Run Code Online (Sandbox Code Playgroud)
因此,远程用户无法找到丢失的提交,因为它们仍在本地磁盘上.
将修改子模块的人告知,即
$ cd submodule
$ git push
Run Code Online (Sandbox Code Playgroud)
我这样做时遇到了这个错误:
$ git submodule update --init --depth 1
Run Code Online (Sandbox Code Playgroud)
但是父项目中的提交指向了较早的提交。
删除子模块文件夹并运行:
$ git submodule update --init
Run Code Online (Sandbox Code Playgroud)
没有解决问题。我删除了回购协议,然后在没有深度标志的情况下再次尝试,它正常工作。
此错误在Ubuntu 16.04 git 2.7.4中发生,但在Ubuntu 18.04 git 2.17中不发生,TODO查找确切的修复提交或版本。
小智 5
当您有一个子模块指向已重新建立基础的存储库,并且给定的提交为“ gone”时,也会发生这种情况。尽管提交可能仍在远程存储库中,但它不在分支中。如果您不能创建一个新分支(例如,不是您的存储库),那么您就不得不更新超级项目以指向一个新的提交。或者,您可以将子模块的副本之一推送到其他位置,然后更新超级项目以指向该存储库。