我尝试使用子模块和符号链接克隆存储库。 我在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
克隆后创建符号链接。
为什么直接克隆时不起作用?
答案 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 7eae4a3的commit 515be83,commit 3e42cb3,SZEDER 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=val
和git -c var=val clone
期间会忽略通过'fetch
'(或'checkout
')指定的某些配置变量。在“
remote.origin.mirror
”文档中,让用户知道哪些配置变量被忽略(“remote.origin.tagOpt
”和“git clone -c
”),以及使用选项“--mirror
和“--no-tags
”。
由于当前实施的局限性,某些配置变量直到初始获取和签出后才生效。
已知无效的配置变量为:
remote.<name>.mirror
remote.<name>.tagOpt
。请改用相应的
--mirror
和--no-tags
选项。