git 是否可以将定义为相对路径的子模块推送到裸露?
我遇到了这样的场景:
我创建了一个 Git 存储库。
$ git init
在子目录中克隆外部存储库。 (在我的例子中使用 git-hg)
$ git hg clone lib remote_uri
将克隆库添加为子模块
$ git submodule add lib ./lib
然后我提交了更改
$ git commit -am "added lib"
在此过程之后,如果我 git clone
这个存储库和 git submodule init/update
新的,我得到了 repo 和 lib。
无论如何,如果我尝试将存储库推送到裸存储库,然后从裸存储库克隆到另一个位置,则新存储库会在尝试获取库时崩溃。 我尝试在裸露中执行 git submodule init ,但是如果您没有工作副本,该命令将不起作用。
有人知道可以做什么吗?
** 更新 ** 这是一个没有 hg 的例子。
This is a way to reproduce it.
/tmp$ git clone https://github.com/gitster/git.git
/tmp$ cd git/
/tmp/git [master]$ git clone https://github.com/gitster/git.git gitrepo
/tmp/git [master]$ git submodule add ./gitrepo
/tmp/git [master]$ git commit -am "added repo"
/tmp$ cd ..
/tmp$ git clone --bare git gitbare
/tmp$ git clone gitbare gittest
/tmp$ cd gittest/
/tmp/gittest [master]$ git submodule init
Submodule 'gitrepo' (/tmp/gitbare/gitrepo) registered for path 'gitrepo'
/tmp/gittest [master]$ git submodule update
fatal: repository '/tmp/gitbare/gitrepo' does not exist
Clone of '/tmp/gitbare/gitrepo' into submodule path 'gitrepo' failed
I got this scenario:
I created a Git repository.
$ git init
Cloned an external repository in a sub directory. (using git-hg in my case)
$ git hg clone lib remote_uri
Added the the cloned library as submodule
$ git submodule add lib ./lib
Then I commited the changes
$ git commit -am "added lib"
After this procedure, if I git clone
this repo and git submodule init/update
the new one, I get the repo and the lib.
Anyway, If I try to push the repo to a bare one, and clone from the bare to another place, the new one crashes trying to get the lib.
I tried to git submodule init
in the bare, but the command doesn't work if you doesn't have a working copy.
Someone got any idea what can be done?
** Update **
Here is an example without the hg.
This is a way to reproduce it.
/tmp$ git clone https://github.com/gitster/git.git
/tmp$ cd git/
/tmp/git [master]$ git clone https://github.com/gitster/git.git gitrepo
/tmp/git [master]$ git submodule add ./gitrepo
/tmp/git [master]$ git commit -am "added repo"
/tmp$ cd ..
/tmp$ git clone --bare git gitbare
/tmp$ git clone gitbare gittest
/tmp$ cd gittest/
/tmp/gittest [master]$ git submodule init
Submodule 'gitrepo' (/tmp/gitbare/gitrepo) registered for path 'gitrepo'
/tmp/gittest [master]$ git submodule update
fatal: repository '/tmp/gitbare/gitrepo' does not exist
Clone of '/tmp/gitbare/gitrepo' into submodule path 'gitrepo' failed
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你似乎在期待不可能的事情。子模块本身就是存储库,并且为了能够从任何地方克隆它们,必须有一个可供它们访问的存储库,就像父存储库一样。您添加了一个没有公共 URL 配置的子模块。 Git 无法神奇地从您保存在原始存储库中的版本中获取它。
您需要将子模块的 URL 更新为可以从您想要克隆的任何位置访问的内容。您应该以与父存储库相同的方式托管它,无论是在单台计算机上、在单个网络上还是在 GitHub 上。
顺便说一句,您的复制说明与您的实际用例并不相同。在您发布的玩具案例中,您所要做的就是使用公共 URL: 正确添加子模块,
一切都会正常工作。如果您以类似的方式托管您尝试添加为子模块的内容,那么此命令的适当版本将适合您。
You seem to be expecting the impossible. Submodules are repositories in their own right, and to be able to clone them from anywhere, there has to be an accessible repository for them, just like there does for the parent repository. You've added a submodule with no public URL configuration. Git isn't going to be able to magically fetch it out of the version you stuck in that original repository.
You need to update the URL for the submodule to something that'll be accessible from wherever you want to clone it from. You should host it in the same way that you do your parent repository, whether that's on a single machine, on a single network, or on GitHub.
And by the way, your reproduction instructions are not the same as your actual use case. In the toy case you've posted, all you have to do is correctly add the submodule, using the public URL:
and everything will work fine. If you host the thing that you're trying to add as a submodule in a similar way, then the appropriate version of this command will work for you.
将子模块的 URL 设置为指向子模块存储库所在的位置。之后不要调用子模块 init,因为它会将其重置到没有它的位置。
Set the URL for the submodule to point to where the submodule repo exists. Don't call submodule init after that as it will reset it to the place that doesn't have it.