Git:如何将子模块推送到远程存储库?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8372625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git: how to push submodule to a remote repository?
提问by Carlo
I use git to track website I'm working on. I work on my machine and push commits to a remote server configured following this guide: using Git to manage a website.
我使用 git 来跟踪我正在处理的网站。我在我的机器上工作并将提交推送到按照本指南配置的远程服务器:使用 Git 管理网站。
Last week I tried using Git submodules to manage some third party libraries and today I tried pushing to the server, finding out that in the server all the submodule directories are empty.
上周我尝试使用 Git 子模块来管理一些第三方库,今天我尝试推送到服务器,发现服务器中所有子模块目录都是空的。
I tried adding and commiting changes to the local submodule, indeed git status
says that the working directory is clean.
我尝试添加并提交对本地子模块的更改,确实git status
说工作目录是干净的。
What can I do?
我能做什么?
回答by Cascabel
The point of submodules is that they are git repositories within repositories, and the parent repo only knows what commit should be checked out in the submodule - it knows nothing about the content. So a server only aware of the parent project, which hasn't populated the submodules, will naturally see nothing in them.
子模块的要点是它们是存储库中的 git 存储库,而父存储库只知道应该在子模块中检出哪些提交——它对内容一无所知。因此,只知道未填充子模块的父项目的服务器自然不会在其中看到任何内容。
You'll need to at some point initialize the submodules on your server. It looks like you've got a setup with your work tree separate from your repo, so just like with that git checkout -f
, you'll need to accommodate that: GIT_WORK_TREE=/path/to/whatever git submodule update --init
. Afterwards, when your hook runs git checkout -f
after pushing, it'll also need to run git submodule update
(again with the work tree appropriately set).
您需要在某个时候初始化服务器上的子模块。看起来您的工作树与存储库分开设置,因此就像那样git checkout -f
,您需要适应:GIT_WORK_TREE=/path/to/whatever git submodule update --init
。之后,当你的钩子git checkout -f
在推送后运行时,它也需要运行git submodule update
(再次适当设置工作树)。
But it's more complicated than this. You haven't given any information about where your submodules came from, but a submodule is aware of its origin, just like your repository is. When you initialize one, it tries to clone from that origin, and updating it often requires fetching from that origin. If as I suspect, the origin for your third-party libraries is something public that you don't have push access to, you're going to have to set up your own central repositories for the submodules. When you commit in one of the submodules, you'd push to its central repo, and thenpush the parent project, so that when it tries to update submodules elsewhere, it's able to fetch them.
但它比这更复杂。您没有提供有关子模块来自何处的任何信息,但是子模块知道其来源,就像您的存储库一样。当您初始化一个时,它会尝试从该源进行克隆,并且更新它通常需要从该源获取。如果我怀疑您的第三方库的来源是公共的,您没有推送访问权限,那么您将不得不为子模块设置自己的中央存储库。当您提交其中一个子模块时,您将推送到其中央存储库,然后推送父项目,以便当它尝试更新其他地方的子模块时,它能够获取它们。
So, to recap, the workflow is something like this:
所以,回顾一下,工作流程是这样的:
- commit in third-party submodule (or standalone clone of it)
- push third-party library to its central repository
- add submodule in parent repo (make it aware of the new commit) and commit
- push parent project to its central repo
- parent's central repo hook checks out to your server, and updates submodule there
- 在第三方子模块(或它的独立克隆)中提交
- 将第三方库推送到其中央存储库
- 在父仓库中添加子模块(让它知道新提交)并提交
- 将父项目推送到其中央仓库
- 父母的中央 repo 挂钩检查到您的服务器,并在那里更新子模块
回答by Aurelien
As Jefromi pointed out, your submodule needs a "remote" to be able to get pushed.
正如 Jefromi 指出的那样,您的子模块需要一个“远程”才能被推送。
I guess the step you are missing is therefore
因此,我想您缺少的步骤是
submodule-dir/$ git remote add origin <where to push submodule>
submodule-dir/$ git remote add origin <where to push submodule>
Here a simple example step by step: Git: Pushing a new submodule
这里有一个简单的例子一步一步:Git: Pushing a new submodule
回答by Alejandro Vazquez Bofill
I had a similar problem: a clone of a repo in a PC (A) with remote in an external website and I wanted to have a clone of my local repo in another PC (B) in the same network where I could push my changes to (through ssh) and make some tests (some of my regression test take a very long time), so that I could keep on working on (A) on an different branch if needed. The repo in (A) has a submodule.
我有一个类似的问题:在外部网站远程的 PC (A) 中的 repo 克隆,我想在同一网络中的另一台 PC (B) 中克隆我的本地 repo,我可以在那里推送我的更改到(通过 ssh)并进行一些测试(我的一些回归测试需要很长时间),以便我可以在需要时继续在不同的分支上处理 (A)。(A) 中的 repo 有一个子模块。
I created bare repo in (B):
我在 (B) 中创建了裸仓库:
mkdir /path/to/bare_git && cd /path/to/bare_git
git --bare init
and added it as a new remote in my local repo in (A):
并将其添加为 (A) 中我的本地存储库中的新遥控器:
git add remote name_of_B_repo ssh://user@host/path/to/bare_git/
and pushed the local repo in (A) (possibly with changes not made public yet) to my ssh repo:
并将 (A) 中的本地存储库(可能尚未公开更改)推送到我的 ssh 存储库:
git push name_of_B_repo branch_to_push
After this, I clone my bare repo from within (B):
在此之后,我从 (B) 中克隆我的裸仓库:
mkdir /path/to/B_clone && cd /path/to/B_clone
git clone /path/to/bare_git
git submodule update --remote
and I could see that my submodule was not included.
我可以看到我的子模块不包括在内。
Solution 1: If you are not interesting in testing/changing the content of your submodule, but you need it to make your tests, then you can include the external website link directly in the .git/config of (B) clone as:
解决方案 1:如果您对测试/更改子模块的内容不感兴趣,但需要它来进行测试,那么您可以将外部网站链接直接包含在 (B) 克隆的 .git/config 中:
[submodule]
url = http://submodule_external_website_url
then, just update your submodule:
然后,只需更新您的子模块:
git submodule update --remote
Solution 2: If you are interested in changing the content of the submodule in (A) and send them to (B), you first need to add the ssh repo in (B) to your local (A) submodule repo as a new remote:
解决方案2:如果您有兴趣更改(A)中子模块的内容并将它们发送到(B),您首先需要将(B)中的ssh repo添加到本地(A)子模块repo作为新的远程:
cd /path/to/submodule
git add remote name_of_B_repo ssh://user@host/path/to/bare_git/
push your changes to it:
将您的更改推送到它:
cd /path/to/main_A_local_repo
git submodule foreach git push name_of_B_repo branch_to_push
add the submodule local path to the .git/config file of clone repo in (B) as:
将子模块本地路径添加到 (B) 中 clone repo 的 .git/config 文件中:
[submodule]
url = /path/to/bare_git
and update your modules as before:
并像以前一样更新您的模块:
git submodule update --remote
回答by favoretti
Submodule is in fact a separate repo, which is pushed to another remote. So basically when you change something in your submodule you need to be in your submodule's working space to push to it. Moreover, after you have pushed to your submodule, you need to push the main project as well.
子模块实际上是一个单独的 repo,它被推送到另一个远程。因此,基本上当您更改子模块中的某些内容时,您需要在子模块的工作空间中进行推送。此外,在推送到子模块后,还需要推送主项目。
Here are some examples
这里有一些例子