Если предположить, что любые перехваты предварительного получения на сервере принимают push, это всегда будет успешным:
git push --force
В то время как перед запуском выполняется специальная проверка на стороне клиента:
git push --force-with-lease
Вы можете запустить конкретную проверку самостоятельно.Вот алгоритм «проверки аренды»:
Определите вашу текущую ветвь.
Выполните git for-each-ref refs/remotes
.Обратите внимание на идентификатор коммита, который, по мнению вашего git-клиента, соответствует исходному состоянию вашей текущей ветки.
Например, если вы находитесь на ветке "foo", запишите фиксациюидентификатор, связанный с "refs / remotes / origin / foo".
Определите фактический идентификатор фиксации удаленной ветви на вышестоящем git-сервере прямо сейчас.
Разрешить «git push» можно только в том случае, если вы подтвердили коммитизвлеченные из шага 2 и 3 согласны.Другими словами, продолжайте, только если представление вашего локального клона git о восходящем потоке согласуется с фактическим восходящим.
Здесь есть печальное следствие: поскольку git fetch
обновляет все ссылки в разделе "refs / remotes /origin / * "для их последних версий, эта комбинация команд по существу идентична git push --force
:
git fetch
# The command below behaves identically to "git push --force"
# if a "git fetch" just happened!
git push --force-with-lease
Чтобы обойти эту врожденную слабость в git push --force-with-lease
, я стараюсь никогда не запускать git fetch
.Вместо этого я всегда запускаю git pull --rebase
всякий раз, когда мне нужно синхронизироваться с апстримом, так как git pull
обновляет только один ref под refs / remotes, сохраняя "аренды" --force-with-lease
полезным.