为什么全局 git 配置 "remote.origin.push" 覆盖本地 "remote.origin.push"?

Why does the global git config "remote.origin.push" override the local "remote.origin.push"?

# git version 2.22.0.windows.1

# create simulation repos
git init --bare server
git init client

# set global and local config
git config --global remote.origin.push refs/heads/*:refs/for/*
cd client
git remote add origin ../server
git config remote.origin.push refs/heads/*:refs/heads/*

# create and push "master"
touch a.txt
git add a.txt
git commit -m foo
git push origin master

预计本地参考规范 refs/heads/master:refs/heads/master 会起作用。但是 refs/for/master 被创建了。我删除 refs/for/master 并尝试使用 -c:

git push origin :refs/for/master
git -c remote.origin.push=refs/heads/*:refs/heads/* push origin master

再次创建 refs/for/master 而不是 refs/heads/master

我在全局配置中删除remote.origin.push,然后重试,然后按预期创建了refs/heads/master。我也做了这些测试。

global refs/heads/*:refs/for/*
local  refs/heads/*:refs/hello/*
result refs/for/master

global refs/heads/*:refs/hello/*
local  refs/heads/*:refs/for/*
result refs/hello/master

global refs/heads/*:refs/for/*
local  unset
result refs/for/master

global unset
local  refs/heads/*:refs/hello/*
result refs/hello/master

我什至在系统配置中添加了一个 push refspec,这也导致了意想不到的结果。

system refs/heads/*:refs/world/*
global refs/heads/*:refs/hello/*
local  refs/heads/*:refs/heads/*
result refs/world/master

并测试user.name,

system systemname
global globalname
local  localname
result localname

原来 remote.origin.push 的优先顺序与其他配置变量相反。

我很困惑,因为它并不像我相信的那样有效。这是一个错误还是我错过了 git 配置的任何细微功能?

在这种情况下,并不是配置以不同的顺序读取,而是推送 refspecs 是附加的。换句话说,可以在 remote.<remote>.push 中指定多个 push refspec 选项,它们都按照从配置文件中读取的顺序生效。

但是,Git 只会将一组源引用推送到一个地方。由于您已经为 refs/heads/* 指定了目的地(通过在较早的配置文件中列出它),以后的目的地不会覆盖它。您可以通过在命令行中列出两者来查看:

$ git push $TMP/test-repo refs/heads/*:refs/for/* refs/heads/*:refs/heads/*
Enumerating objects: 105, done.
Counting objects: 100% (105/105), done.
Delta compression using up to 4 threads
Compressing objects: 100% (93/93), done.
Writing objects: 100% (105/105), 32.96 KiB | 3.00 MiB/s, done.
Total 105 (delta 41), reused 0 (delta 0)
remote: Resolving deltas: 100% (41/41), done.
To /tmp/user/1000/test-repo
 * [new branch]      master -> refs/for/master

因此,如果您的全局配置文件指定了 refs/tags/*:refs/tags/* 并且您的本地配置文件指定了 refs/heads/*:refs/for/*,那么两者都会生效,因为它们不重叠。

如果您在这种情况下想要不同的行为,您需要删除全局和系统配置,或者在本地存储库中切换远程名称。