Почему глобальный git config "remote.origin.push" переопределяет локальный "remote.origin.push"? - PullRequest
2 голосов
/ 15 июня 2019
# 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

Ожидается, что локальный refspec 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 config?

1 Ответ

4 голосов
/ 15 июня 2019

В этом случае конфигурация не читается в другом порядке, а push-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/*, то оба вступят в силу, посколькуони не пересекаются.

Если вам нужно другое поведение в этом случае, вам нужно либо удалить глобальную и системную конфигурацию, либо переключить удаленное имя в локальном репозитории.

...