Если несколько пользователей запускают «git push» одновременно, эти команды выполняются на сервере последовательно или одновременно?

У меня есть сценарий, в котором мне нужно создать, добавить и зафиксировать файл в репозитории для каждого добавляемого или изменяемого файла .hbs. Я делаю все это с помощью хука post-receive , потому что требования гласят, что это должно выполняться на стороне сервера.

Для этого я сохраняю рабочая копия репо на сервере (Gitlab), чтобы я мог добавить файл в репо. В моем хуке я генерирую файл, затем выполняю git add , git commit и git push .

Что беспокоит меня в этом подходе, так это то, что произойдет, если многие люди будут толкать одновременно? Если операции push выполняются одновременно, я думаю, это может быть проблематично. Но если они запускаются последовательно, то я не вижу проблем.

Итак, мой вопрос: могу ли я предположить, что git push (особенно post-receive hook) запускать последовательно на сервере?


Короткий ответ — нет: вы не можете сделать это предположение. Однако вы можете создать и другие.

Любой репозиторий Git будет заблокировать любую указанную ссылку при ее обновлении. Это верно даже для чисто локальной операции Git, без каких-либо действий клиент/сервер: если вы запустите один git commit в одном окне, а другой git commit в другом окне, в то же время, в той же ветке, только один за раз действительно может обновить это имя ветки.

Тем не менее, фактическое обновление возникает до запуска обработчика post-receive. Все блокировки (для имен веток и для самого индекса) снимаются после запуска хуков pre-receive и update , до post-update запускается. Таким образом, мы можем построить несколько сценариев гонки, например:

  • Алиса запускает git push (с компьютера Алисы) для отправки фиксации a123456 на сервер и попросить сервер установить master ветвь сервера для идентификации фиксации a123456 .
  • Боб запускает git push (с компьютера Боба), чтобы отправить фиксацию b789abc на сервер и попросить сервер установить функцию сервера для идентификации фиксации b789abc .
  • Кэрол запускает git push для отправки фиксации fedcba9 на сервер и попросить сервер установить master сервера для идентификации фиксации fedcba9.

Один из этих трех «выиграет гонку», чтобы начать обновление. Давайте предположим, без (я надеюсь) потери общности, что это Алиса, и что Боб будет следующим, а Кэрол — третьей. Фиксация Алисы попадает в область карантина, 1 , а обработчики предварительного получения и обновления сервера получают возможность решить, будет ли master идентифицировать a123456 — хорошая идея. Если ее git push не принудительно, сервер Git сначала проверяет, что current значение master является предком этого предлагаемого нового коммита, то есть, что git push — это операция быстрой перемотки вперед.

Если все пойдет хорошо, фиксация Алисы будет перемещена из карантина в основную базу данных репозитория, а master теперь идентифицирует a123456 на сервере. Сервер снимает все блокировки и запускает обработчик post-receive . Поскольку Боб поставлен в очередь, сервер (почти сразу — это отдельный процесс, который ждал) принимает фиксацию Боба b789abc и помещает этот в карантин и запускает процесс проверки для refs/Heads/feature сервера. Если все идет хорошо, фиксация перемещается из карантина в основную базу данных, refs/Heads/feature теперь идентифицирует b789abc , а Git отключает пост-получение крючок. (Если push отклонен, я думаю , что Git по-прежнему запускает обработчик post-receive, но теперь в его потоке stdin нет обновлений. Предположим, что push принят.)

В этот момент можно запустить толчок Кэрол. Ее коммит fedcba9 почти наверняка не имеет a123456 в качестве предка — единственный способ мог есть, если Кэрол получила это от Алисы раньше, поэтому после того, как ее фиксация попадет в карантин, ее попытка установить master будет отклонена, если она не использовала - принудительно . Затем сервер Git запускает обработчик post-receive, но без обновлений в своем потоке stdin. (Возможно, обработчик post-receive не работает вообще.)

Если первый обработчик post-receive все еще работает, на данный момент имеется три запущены обработчики post-receive. У одного есть в своем стандартном вводе обновление до refs/Heads/master из любого хеш-идентификатора, который он держал раньше, до a123456 . У одного есть в своем стандартном вводе обновление до refs/Heads/feature с любого хэш-идентификатора, который он держал ранее, до b789abc . У третьего есть пустой поток stdin: обновлений нет.

Что будет дальше, конечно, зависит от вас, автора ловушки post-receive.


1 Карантинные области были новыми в некоторых версиях Git после 2.0. Эти детали в основном не имеют значения; они действительно важны только в том случае, если ловушка предварительного получения или обновления отклоняет изменение имени.

Оцените статью
Botgadget.ru
Добавить комментарий