git clone -c core.symlinks = true不起作用

时间:2018-04-18 07:16:31

标签: git git-submodules symlink

我尝试使用子模块和符号链接克隆存储库。 我在Windows 10上并克隆到NTFS SSD上。

我用

克隆

$git clone -c core.symlinks=true --recurse-submodules -b develop git@example.com/my-project.git

克隆时,配置包含行symlinks = false,并且不创建符号链接。

我必须使用

$git config core.symlinks true

$git reset --hard

克隆后创建符号链接。

为什么直接克隆时不起作用?

2 个答案:

答案 0 :(得分:2)

git clone代码创建新(空)存储库时,它使用init_db函数,ends with a block including this code

/* Check if symlink is supported in the work tree */
path = git_path_buf(&buf, "tXXXXXX");
if (!close(xmkstemp(path)) &&
    !unlink(path) &&
    !symlink("testing", path) &&
    !lstat(path, &st1) &&
    S_ISLNK(st1.st_mode))
        unlink(path); /* good */
else
        git_config_set("core.symlinks", "false");

由于您收到明确的core.symlinks = false,因此该行必须覆盖您设置core.symlinks = true的请求。请注意,该设置取决于实际的OS支持,而不是任何命令行选项。但是,如果您稍后移动工作树,则显式设置仍保留在.git/config文件中。

与此同时,还有另外两个问题。一个是ElpieKay mentioned in a comment:对于大多数命令,您可以使用git -c name=value subcommand临时覆盖配置,这将是git -c core.symlinks=true clone arguments。如果您的特定Git版本已过期且与我引用和链接到此处的代码不匹配,这是值得尝试的。

但是,git clone非常特殊:它本质上是一个可选的mkdir来创建存储库和工作树目录,然后是git init,然后是一些配置设置,然后是一个git fetch和一个git checkout。这意味着您可以使用git -c name=value clone -c name=value ...。在创建存储库时,即在name=value期间,第一个 git init设置正在使用中。 第二个 name=value是使用this bit of code git clone进入新克隆的 {/ 1>}:

init_db(git_dir, real_git_dir, option_template, INIT_DB_QUIET);

if (real_git_dir)
        git_dir = real_git_dir;

write_config(&option_config);

git_config(git_default_config, NULL);

write_config函数是Git从core.symlinks=true命令写入git clone -c core.symlinks=true ...的地方。理论上应该覆盖core.symlinks=false计算的init_db设置。这是我发现好奇的部分:它

后续git_config调用将读取写入新存储库.git/config的实际配置。这将设置内部has_symlinks变量,该变量将控制git checkout运行的内部git clone。因此,如果这确实覆盖了init_db设置,那么一切都会按照您想要的方式工作。不明显的是为什么它不会覆盖。这里的代码有点曲折,但看起来您的命令行选项应该覆盖init_db设置。

(当然,如果符号链接实际上在工作树中工作,init_db代码不应该首先设置core.symlinks=false!)

答案 1 :(得分:1)

应该在Git 2.21(2019年第一季度)中修复

使用“ git -c var=val clone”配置的参考规范未传播到已得到纠正的结果存储库中。

请参见commit 7eae4a3commit 515be83commit 3e42cb3SZEDER Gábor (szeder)(2018年11月14日)。
(由Junio C Hamano -- gitster --commit 84d1783中合并,2019年1月4日)

  

克隆:在初始提取期间遵守其他已配置的提取refspecs

     

克隆期间的初始fetch不会传输与命令行上作为配置变量提供的其他fetch refspec匹配的refs,例如'-c remote.origin.fetch=<refspec>'。
  这与说明通过以下方式指定配置变量的文档相矛盾。   'git clone -c <key>=<value> ...'“在初始化存储库之后,但在获取远程历史记录之前立即生效”,并且给定的示例特别提及“向源远程添加其他获取refspecs”。

     

此外,虽然未写入新创建的存储库的配置文件,但通过'git -c <key>=<value> clone ...'指定的一次性配置变量在'clone'命令的生存期内一直有效,包括初始提取。

     

所有这些都意味着以这种方式指定的任何获取refspecs应该已经   在初始获取期间应予以考虑。

     

这样做的原因是,初始获取不是完全成熟的'git fetch',而是使用克隆自身的refs-to-refspec匹配逻辑直接调用获取/传输机制。绕过部分“ git fetch”处理过程中配置的提取引用规范
  此逻辑仅考虑单个默认refspec,并可能受“ --single-branch”和“ --mirror”等选项的影响。

     

但是,已正确读取并解析了配置的refspecs   当克隆调用remote.c:remote_get()时,但它永远不会查看生成的'struct remote'中已解析的refspec。

     

修改clone,以考虑远程服务器的配置的获取引用规范,以在初始获取期间获取所有匹配的引用

     

请注意,我们必须将默认的获取refspec显式添加到遥控器的refspec中,因为在那一点上,遥控器仅包括在命令行上指定的获取refspec。

     

添加测试以检查是否同时通过'git clone -c ...和'git -c ... clone'给出的refspecs检索与默认或其他refspecs匹配的所有refs,即使用户指定了其他选项,它也可以正常工作通过“ --origin=<name>”的远程名称。

注意事项:

  

由于当前实施方式的限制,在初始git clone -c var=valgit -c var=val clone期间会忽略通过'fetch'(或'checkout')指定的某些配置变量。

     

在“ remote.origin.mirror”文档中,让用户知道哪些配置变量被忽略(“ remote.origin.tagOpt”和“ git clone -c”),以及使用选项“ --mirror和“ --no-tags”。

man page for git clone现在包括:

  

由于当前实施的局限性,某些配置变量直到初始获取和签出后才生效。

     

已知无效的配置变量为:

     
      
  • remote.<name>.mirror
  •   
  • remote.<name>.tagOpt
  •   
     

请改用相应的--mirror--no-tags选项。