Git子模块工作流问题

bla*_*oul 6 git git-submodules

最近我们的Git存储库遇到了很多问题.我们是git子模块的用户,我们的应用程序之间共有4个共享存储库.

例如,存储库"网站"总共有3个子模块.

[submodule "vendor/api"]
    path = vendor/api
    url = git@your.cool.domain.com:api
[submodule "vendor/auth"]
    path = vendor/auth
    url = git@your.cool.domain.com:auth
[submodule "vendor/tools"]
    path = vendor/tools
    url = git@your.cool.domain.com:tools
Run Code Online (Sandbox Code Playgroud)

我们已经正确检查了我们的主存储库'网站'.现在,我的一位同事做了推动,然后我git pull; git status:

# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   vendor/api (new commits)
#   modified:   vendor/auth (new commits)
#   modified:   vendor/tools (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")

mcfly@future:~/projects/website$ git diff

diff --git a/vendor/api b/vendor/api
index 41795fc..b582d80 160000
--- a/vendor/api
+++ b/vendor/api
@@ -1 +1 @@
-Subproject commit 41795fc4dde464d633f4c0f01eebb6ab1ad55582
+Subproject commit b582d802419b0ee7bc3959e7623fec0b94680269
diff --git a/vendor/auth b/vendor/auth
index a00369b..4599a71 160000
--- a/vendor/auth
+++ b/vendor/auth
@@ -1 +1 @@
-Subproject commit a00369bf29f14c761ce71f7b95aa1e9c107fb2ed
+Subproject commit 4599a7179c9b7ca4afa610a15ffa4a8fc6ebf911
diff --git a/vendor/tools b/vendor/tools
index f966744..c678cf6 160000
--- a/vendor/tools
+++ b/vendor/tools
@@ -1 +1 @@
-Subproject commit f966744359510656b492ae3091288664cdb1410b
+Subproject commit c678cf6f599fc450e312f0459ffe74e593f5890f
Run Code Online (Sandbox Code Playgroud)

有什么问题git diff?问题是每个子模块的新提交都是OLDER而不是将被覆盖的提交.这不是我们想要的,因为在存储库已正确指向41795fc4dde464d633f4c0f01eebb6ab1ad55582,a00369bf29f14c761ce71f7b95aa1e9c107fb2edf966744359510656b492ae3091288664cdb1410b如果我们添加此修改,我们的下一个承诺,我们大概会制动的事情.我不知道为什么它会得到最旧的版本,而不是最新版本.

我试图自己解决这个问题,但没有成功:

mcfly@future:~/projects/website$ git pull; git submodule foreach git pull
Run Code Online (Sandbox Code Playgroud)

做最后一个命令是不对的,因为我们可能会将'website'的指针更新到每个子模块的最新版本,我们不希望这样.我们希望保留它在存储库中的正确修订版.

我要解释的一件事我们通常在这个子模块中工作,例如:

mcfly@future:~/projects/website$ cd vendor/api
mcfly@future:~/projects/website/vendor/api$ git checkout master
mcfly@future:~/projects/website/vendor/api$ echo "lorem ipsum" >> example.file
mcfly@future:~/projects/website/vendor/api$ git add example.file; git push
Run Code Online (Sandbox Code Playgroud)

当我们做一个git submodule update'master'分支在每个子模块上丢失.

最后,正确的做法是什么push,pull并使用子模块而没有所有这些问题?

先感谢您

Chr*_*her 8

看看git-scm文档并将其传递给您的团队.您正在看到的现象在"使用子模块克隆项目"部分中有详细描述.

首先,您观察到的初始状态,其中git diff显示这些提交哈希的意外相反结果,表示您在父仓库中合并了子模块更新,但未在git submodule update本地运行.git submodule update每次下拉主项目中的子模块更改时都必须运行.为什么?该子模块的指针,即什么样的父母库认为是状态vendor/auth,是不实际的HEAD承诺子模块库中vendor/auth.在您了解git如何跟踪子模块状态之前,这有点令人困惑.同样,git-scm文档值得一读.

其次,通过设计git submodule update放弃master子模块上的分支.查看这些文档的"子模块问题"部分.通常使用git的手册页告诉我们需要知道的内容:

update
   Update the registered submodules, i.e. clone missing submodules and checkout the commit specified in the index of the containing repository. This will
   make the submodules HEAD be detached unless --rebase or --merge is specified or the key submodule.$name.update is set to rebase, merge or none.  none
   can be overridden by specifying --checkout.
Run Code Online (Sandbox Code Playgroud)

HEAD每次在git submodule update没有参数的情况下发布时,您都会将子模块置于"分离"状态.

那么如何在没有这些问题的情况下使用子模块呢?首先,问问自己和你的团队:我们真的需要它们吗?在某些情况下,子模块是一个功能强大且有用的功能,但它们的设计更多地针对第三方库,而不是主动项目分解为子存储库.你当然可以这样使用它们,但管理开销可能会迅速超过你获得的任何好处.除非您的存储库非常大,或者您的子模块完全是模块化的,否则值得问一下"我们是否会更好地使用单个存储库?" 即使答案为"否",也请查看子树合并,这可能对您的用例更为成功.

如果您仍想使用子模块,请查看上面链接的文档,以及有关子模块工作流的SO和其他网站上的许多问题答案.他们应该帮助你实现一个更健全的过程.