GIT обновляет рабочее дерево с помощью receive.denyCurrentBranch = updateInstead даже для отклоненных нажатий (receive.denyNonFastForwards = true) - PullRequest
0 голосов
/ 18 октября 2018

Я разместил этот вопрос / ошибку на официальном канале GIT, но не получил ответа.Надеюсь, что кто-то здесь может помочь мне.

Мне кажется, что приведенное ниже поведение некорректно, когда для receive.denyCurrentBranch установлено значение updateInstead и receive.denyNonFastForwards установлено на true .Ниже приведены шаги для воспроизведения сценария.

Шаг 1 - Настройка удаленного хранилища (удаленный хост):

git config --global receive.denyCurrentBranch updateInstead
git config --global receive.denyNonFastForwards true
mkdir /tmp/hello
cd /tmp/hello
git init
echo hello > hello.txt
git add . && git commit -m "hello.txt"

Шаг 2 - Создание 2 клонов(локальный хост):

git clone ssh://REMOTEIP/tmp/hello /tmp/hello1
git clone ssh://REMOTEIP/tmp/hello /tmp/hello2

Шаг 3 - выдать коммит из клона 1

cd /tmp/hello1
echo hello1 > hello1.txt
git add . && git commit -m "hello1.txt"
git push

На этом этапе рабочее дерево сервера содержит hello1.ожидаемый текст

Шаг 4: Попробуйте принудительно выдать коммит из клона 2

cd /tmp/hello2
echo hello2 > hello2.txt
git add . && git commit -m "hello2.txt"
git push

Удаленный отклоняет сообщение о том, что удаленный содержит работу, которой у меня нет локальнокоторый действителен.Теперь я принудительно нажимаю.

git push --force

Пульт снова отклоняется с ошибкой: запрещение не-ускоренных пересылок refs / heads / master (вы должны тянуть первым)

На этом этапе, поскольку push-уведомление отклонено, я ожидаю, что рабочее дерево серверов не будет содержать отклоненных изменений.НО обновилось рабочее дерево серверов, чтобы удалить hello1.txt и создать hello2.txt.Push отклонен, но не совсем.

Я также заметил то же поведение (неправильное), когда ловушка обновления отклоняет изменения на сервере (но не ловушка предварительного получения).

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

Я ожидаю, что рабочее дерево серверов не будет содержать отклоненных изменений.НО обновилось рабочее дерево серверов, чтобы удалить hello1.txt и создать hello2.txt.
Push отклонен, но не совсем.

Начиная с Git 2.20 (Q4 2018), push будет действительно будет отклонено.

Ранее кодовый путь receive.denyCurrentBranch=updateInstead включался даже тогда, когда нажатие должно было быть отклонено по другим причинам, например, из-за того, что перемотка вперед не выполнялась, или из-за отказа обновляющего крюкаэто, которое было исправлено.

См. коммит b072a25 (19 октября 2018) Джунио С. Хамано (gitster) .
(Объединено Junio ​​C Hamano - gitster - в коммит 4c7f544 , 30 октября 2018 г.)

receive: denyCurrentBranch=updateinstead не следует обновлять вслепую

Обработка receive.denyCurrentBranch=updateInstead была добавлена ​​к оператору switch, который обрабатывает другие значения переменной, но все остальные команды case только проверяли условие, чтобы отклонить попытку push или разрешить позжелогика в той же функции, чтобы все еще вмешиваться, так что толчок, который не перемотка вперед (который яs проверяется после того, как рассматриваемый оператор switch) все еще отклоняется.

Но обработка updateInstead неправильно вступила в силу немедленно, не давая возможности другим проверкам вмешаться.

Вместо вызова update_worktree(), который немедленно вызывает побочный эффект, просто отметьте тот факт, что нам нужно будет вызвать функцию позже, и сначала дать другим проверкам возможность отклонить запрос.
После того, как update-hook получит возможность отклонить толчок(что происходит как последний шаг в серии проверок), позвоните update_worktree(), когда мы ранее обнаружили необходимость.

В вашем случае ваше рабочее дерево будет , а не содержать отклоненные изменения, как и ожидалось, учитывая, что ваш толчок был отклонен.

0 голосов
/ 18 октября 2018

Проблема заключается в том, что эти две конфигурации находятся в конфликте (хотя я согласен, что в принципе они не должны быть):

receive.denyCurrentBranch установлено на updateInstead

В этом случае во время получения Git замечает, что целью является текущая ветвь, поэтому Git проверяет фиксацию.

и receive.denyNonFastForwards установленына true.

Это происходит отдельно: изменение имени отклонено.Коммит уже был принят, и проверка хранилища произошла, и сейчас отклонение имени отклонено.

Я также заметил такое же поведение (неправильно) когда ловушка обновления отклоняет изменения на сервере (но не ловушка предварительного получения).

Это та же проблема: ловушка предварительного получения запускается один раз, перед любыми обновлениями отдельных ссылок,и может отклонить весь толчок.Затем, если ловушка предварительного получения очистила вещи для продолжения, ловушки обновления могут отклонить любое отдельное обновление ref-name.Однако updateInstead происходит отдельно от того, что обновление имени ветки принято или отклонено.

Вероятно, было бы лучше для Git внутренне избежать изменения рабочего дерева до тех пор, пока после не проверит эталонное обновление,Это потребует некоторых переделок во внутренностях Git.Если это не считается явной ошибкой в ​​Git, это, по крайней мере, довольно удивительно.Фактически, весь этот код нуждается в некоторой работе, потому что если вы используете git worktree add, Git не сможет рассматривать заголовки добавленных рабочих деревьев как текущие ветви.Учитывая все эти предостережения, я бы рекомендовал использовать только голые репозитории в качестве целей push-уведомлений с перехватами после получения для прямого обновления в других репозиториях или рабочих деревьях.


В стороне (это был комментарий,но это было слишком коротко, чтобы выразить это очень хорошо):

git config --global receive.denyCurrentBranch updateInstead
git config --global receive.denyNonFastForwards true

Хотя это не связано с конкретным поведением, которое вы наблюдали, это определенно неправильная вещь.Запуск git config --global устанавливает элементы конфигурации для вас лично.То есть они входят в /home/rajesh (или везде, где находится конфигурация вашего домашнего каталога).Но настройки receive.* должны быть для каждого репозитория .

Поскольку вы используете ssh в качестве самого себя для выполнения push, эти параметры конфигурации действительно вступили в силу, но если бы вы когда-либопротолкнуть каким-либо другим методом, они не могут.Любые настройки для каждого репозитория, сделанные с помощью git config без --global, все равно будут действовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...