Git:如何将子模块推送到远程存储库?

时间:2011-12-04 01:49:13

标签: git git-submodules

我使用git来跟踪我正在处理的网站。我在我的机器上工作并将提交推送到按照本指南配置的远程服务器:using Git to manage a website

上周我尝试使用Git子模块管理一些第三方库,今天我尝试推送到服务器,发现在服务器中所有子模块目录都是空的。

我尝试添加并提交对本地子模块的更改,实际上git status表示工作目录是干净的。

我该怎么办?

4 个答案:

答案 0 :(得分:10)

子模块的意思是它们是存储库中的git存储库,而父repo只知道应该在子模块中检出哪些提交 - 它对内容一无所知。因此,只知道未填充子模块的父项目的服务器自然会在其中看不到任何内容。

您需要在某个时刻初始化服务器上​​的子模块。您的工作树看起来与您的仓库分开,因此就像使用git checkout -f一样,您需要适应:GIT_WORK_TREE=/path/to/whatever git submodule update --init。之后,当你的钩子在推动后运行git checkout -f时,它还需要运行git submodule update(再次适当地设置工作树)。

但它比这更复杂。您没有提供有关子模块来自何处的任何信息,但子模块知道其来源,就像您的存储库一样。初始化一个时,它会尝试从该原点进行克隆,并且通常需要从该原点进行更新。如果我怀疑,您的第三方库的来源是公共的,您没有推送访问权限,那么您将不得不为子模块设置自己的中央存储库。当您在其中一个子模块中提交时,您将推送到其中央存储库,然后然后推送父项目,这样当它尝试更新其他地方的子模块时,它就能够获取它们。

因此,回顾一下,工作流程是这样的:

  • 提交第三方子模块(或其独立克隆)
  • 将第三方库推送到其中央存储库
  • 在父repo中添加子模块(让它知道新的提交)并提交
  • 将父项目推送到其中央仓库
  • parent的中央repo hook检出你的服务器,然后更新那里的子模块

答案 1 :(得分:5)

正如Jefromi指出的那样,你的子模块需要一个“遥控器”才能被推动。

我想你缺少的步骤是

submodule-dir/$ git remote add origin <where to push submodule>

这是一个简单的示例:Git: Pushing a new submodule

答案 2 :(得分:3)

子模块实际上是一个单独的仓库,它被推送到另一个远程仓库。所以基本上当你更改子模块中的某些东西时,你需要在你的子模块的工作空间中推动它。此外,在推送到子模块后,您还需要推送主项目。

以下是一些examples

答案 3 :(得分:1)

我遇到了类似的问题:PC(A)中的repo克隆与外部网站中的遥控器我希望在同一个网络中的另一台PC(B)中克隆我的本地仓库将我的更改推送到(通过ssh)并进行一些测试(我的一些回归测试需要很长时间),这样我就可以继续在不同的分支上工作(如果需要的话)。 (A)中的回购有一个子模块。

我在(B)中创建了裸仓库:

mkdir /path/to/bare_git && cd /path/to/bare_git
git --bare init

并将其添加为我在(A)中的本地仓库中的新遥控器:

git add remote name_of_B_repo ssh://user@host/path/to/bare_git/

并将(A)中的本地仓库(可能尚未公开的更改)推送到我的ssh仓库:

git push name_of_B_repo branch_to_push

在此之后,我从(B)内克隆我的裸仓:

mkdir /path/to/B_clone && cd /path/to/B_clone
git clone /path/to/bare_git
git submodule update --remote

我可以看到我的子模块没有被包括在内。

解决方案1 ​​:如果您对测试/更改子模块的内容不感兴趣,但需要它来进行测试,那么您可以直接在.git中包含外部网站链接/ config of(B)clone as:

[submodule]
        url = http://submodule_external_website_url

然后,只需更新您的子模块:

git submodule update --remote

解决方案2 :如果您有兴趣更改(A)中子模块的内容并将其发送到(B),首先需要将(B)中的ssh repo添加到您的local(A)submodule repo作为新的远程:

cd /path/to/submodule
git add remote name_of_B_repo ssh://user@host/path/to/bare_git/

将更改推送到它:

cd /path/to/main_A_local_repo
git submodule foreach git push name_of_B_repo branch_to_push

将子模块本地路径添加到(B)中克隆仓库的.git / config文件中:

[submodule]
        url = /path/to/bare_git

并像以前一样更新您的模块:

git submodule update --remote