指定为相对路径时无法添加git子模块

zu0ti5jz  于 2023-06-28  发布在  Git
关注(0)|答案(3)|浏览(91)

我尝试在git repo中添加一个子模块,结果返回了以下错误:

remote origin does not have a url defined in .git/config

知道这是什么吗我试着在谷歌上搜索,但只有一个模糊的链接出现。
我在做这个:

git submodule add ../extern/Lib1 lib

我希望这会创建一个子模块lib/Lib1
我知道这只会创建一个引用,然后我必须更新/init(这部分不是很清楚,还没有到那一步;我正在学习submodule命令)。

pcww981p

pcww981p1#

../extern/Lib1是否引用Git存储库?
如果不这样做,Git就不知道如何将Git存储库URL指向其.gitmodule
另外,试试:

  • 目标libnot 已经存在(甚至为空)
  • 使用绝对路径而不是相对路径(您可以使用相对路径,但以防万一,这里值得一试)

关于子模块的一些好的源代码是:

当然

由于这里只有绝对路径起作用,这意味着相对路径需要一个引用来进行比较。
该引用是“remote origin”,应该在DirName/NewRepo_withSubmodules/.git/config文件中,如下所示:

$ cat .git/config
    ...
    [remote "origin"]
    url = /path/to/DirName/NewRepo_withSubmodules/.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    ...

如果在../DirName/NewRepo_withSubmodules/.git/config文件中确实有该部分,则应该能够使用相对路径将../Extern/Lib1添加为子模块。
以上所有内容的灵感都来自git submodule手册页的以下部分:
<repository>是新子模块的原始存储库的URL。
这可以是一个绝对URL,或者(如果它以./../开头),相对于超级项目的 * origin * 存储库的位置
因此,如果NewRepo_withSubmodules是一个刚刚创建的本地Git仓库(当然没有“origin”),那么应该定义一个人工的“远程origin”(即使origin指向它自己),如果只允许使用其他子模块仓库的相对URL。
Git 2.13(Q2 2017)将改进子模块默认来源的检测。
参见commit d1b3b81(2017年2月25日),作者Stefan Beller ( stefanbeller )
(由Junio C Hamano -- gitster --合并至commit ae900eb,2017年3月10日)

submodule init:警告回退到本地路径

如现在记录的:
<repository>是新子模块的原始存储库的URL。
这可以是绝对URL,或者(如果以./../开头)相对于超级项目的默认远程存储库的位置
(请注意,要指定位于超级项目'bar.git'旁边的存储库'foo.git',您必须使用'../foo.git'而不是'./foo.git' -这可能是在遵循相对URL规则时所期望的-因为Git中相对URL的评估与相对目录的评估相同)。
默认远程是当前分支的远程跟踪分支的远程。
如果不存在此类远程跟踪分支或HEAD已分离,则“origin”将被假定为默认远程。
如果超级项目没有配置默认的远程,那么超级项目就是它自己的权威上游和当前。而是使用工作目录。
Git 2.20(Q4 2018)改进了子模块的本地路径支持。
参见commit e0a862f(2018年10月16日),作者Stefan Beller ( stefanbeller )
(由Junio C Hamano -- gitster --合并于commit 3fc8522,2018年11月6日)

submodule helper:如果需要,将相对URL转换为绝对URL

由“git submodule update“调用的子模块helper update_clone在需要时克隆子模块。
由于子模块通常具有指示它们是否处于活动状态的URL,因此解析相对URL的步骤在“submodule init”步骤中完成。如今,子模块可以配置为活动,而无需调用显式的init,例如通过配置submodule.active
当尝试获取以这种方式设置为活动的子模块时,我们将回退到.gitmodules中找到的URL,该URL可能与超级项目相关,但我们尚未解析它:

git clone https://gerrit.googlesource.com/gerrit
cd gerrit && grep url .gitmodules
  url = ../plugins/codemirror-editor
  ...
git config submodule.active .
git submodule update
  fatal: repository '../plugins/codemirror-editor' does not exist
  fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
  Failed to clone 'plugins/codemirror-editor'. Retry scheduled
  [...]
  fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
  Failed to clone 'plugins/codemirror-editor' a second time, aborting
  [...]

要解决此问题,请在“git submodule init”(在init_submodule函数的子模块helper中)中找出解析相对URL的函数,并在update_clone helper中的适当位置调用它。
git submodule“(man)代码太信任来自配置(和树中的.gitmodules文件)的数据而不进行验证,如果用户与存储库(例如当submodule.<name>.url被移除时)。
Git 2.42(Q3 2023)已更正此问题。
参见commit fbc806a(2023年5月24日)由Taylor Blau ( ttaylorr )
(由Junio C Hamano -- gitster --合并于commit 9cd234e,2023年6月20日)

builtin/submodule--helper.c:处理丢失的子模块URL

报告人:特里博达尔
签字人:泰勒·布劳
e0a862f(“submodule helper:convert relative URL to absolute URL if needed”,2018-10-16,Git v2.20.0-rc0 -- merge listed in batch #9),prepare_to_clone_next_submodule() lost the ability to handle URL-less submodules,due to a change from:

if (repo_get_config_string_const(the_repostiory, sb.buf, &url))
    url = sub->url;

if (repo_get_config_string_const(the_repostiory, sb.buf, &url)) {
    if (starts_with_dot_slash(sub->url) ||
        starts_with_dot_dot_slash(sub->url)) {
            /* ... */
        }
}

,当sub->urlNULL时,它将segfault,因为两个starts_with_dot_slash()都不将其参数保护为非NULL。
通过首先检查sub->url是否为非NULL来保护对上述两个函数的检查。
不需要检查sub本身是否是NULL,因为我们已经在prepare_to_clone_next_submodule()中执行了这个检查。
通过在sub->url上添加NULL检查,我们将进入'else'分支,将url设置为sub->url(即NULL)。
在尝试调用git submodule--helper clone之前,检查url是否是NULL,如果是,则检查die()

gdrx4gfi

gdrx4gfi2#

我也在尝试同样的事情,发现下面的“似乎起作用了:
我有(在Windows上):``

D:/phd/analyses
    /analysis1/ #This is an existing repository
    /analysis2/ #another existing repository
    /analysis3.tex
    /analysis4.tex
    ...
    /analysisN.tex

analysis1.tex ... analysisN.tex包含我还没有工作过的想法(比如说,存根),analysis1/analysis2/是我正在工作的东西(因此有代码,tex,...一旦我开始处理其他的分析,它们就会被移到自己的文件夹中,从而移到自己的存储库中。
我所做的是(在git bash中分析):

git init
git add *.tex
git remote add self .
git submodule add self:/analysis2/.git analysis2
git submodule add self:/analysis5/.git analysis5
git commit -m "Initial commit"

这似乎起了作用。
D:/phd/analyses/.git/config看起来应该是这样,而.gitmodules看起来应该是这样:

[submodule "analysis2"]
    path = analysis2
    url = self:analysis2/.git
[submodule "analysis5"]
    path = analysis5
    url = self:analysis5/.git

问候,西蒙·纳普

yvgpqqbh

yvgpqqbh3#

  • (我在这里只总结了解决方案。信贷归于VonC。)*

在包含的存储库(比如containing.git/)中,git将相对路径解释为相对于origin远程的路径,而origin远程没有定义。我们希望它是相对于containing.git/目录的,所以运行

git remote add origin ..

(Not为什么是..而不是.
现在您可以添加子模块:

git submodule add ../extern/Lib1 lib

相关问题