Ответ 1
Короткий ответ
Да, один из нажатий будет отклонен - в зависимости от того, что будет позже, даже если это будет всего на микросекунду, как упоминает Джефри в своем комментарии. Тем не менее, он будет отклонен, поскольку удаленный репозиторий видит, что история более позднего нажатия не включает историю более раннего, а не потому, что он видит какой-либо конфликт в том, что нажимается.
Более подробный ответ
Обычно нажатие будет отклонено, если оно не будет "ускорять" ветвь в терминологии Git. Это означает, что если ваш мастер находится в A, а удаленный репозиторий - в B, то нажатие будет выполнено только в том случае, если B является предком A. (я говорю "обычно", потому что вы можете добавить опции для "принудительного" нажатия, если удаленный репозиторий позволяет это, но это не типичный случай.)
В описанном вами случае, если все три хранилища изначально имеют одну и ту же историю:
P -- Q -- R
И вы добавили фиксацию S:
P -- Q -- R -- S
... а кто-то добавил добавление т:
P -- Q -- R -- T
Если этот другой человек попадает туда первым при нажатии (то есть Git на сервере обрабатывает их нажатие первым), то их push будет принят, потому что R
является предком T
, поэтому удаленный репозиторий будет также иметь историю P -- Q -- R -- T
. Если впоследствии попытаться нажать, вы получите сообщение об ошибке, потому что T
не является предком S
. Как правило, при обнаружении ошибки ! [rejected]
вы либо запускаете git pull
, либо git pull --rebase
, чтобы убедиться, что вы находитесь впереди мастера в удаленном репозитории.
git pull
создаст фиксацию слияния M
, чтобы ваша история выглядела следующим образом:
P -- Q -- R -- T -- M
\ /
-- S -
... в то время как git pull --rebase
повторно применит изменения, которые вы ввели поверх T
, чтобы создать новый фиксатор, S'
:
P -- Q -- R -- T -- S'
В любом из этих случаев вы сможете снова нажать, потому что T
является предком как M
, так и S'
. (Это предполагает, что никто другой не подтолкнул еще раз)!
Если только для быстрого перехода вперед никогда не должно быть разрешения конфликтов на удаленной стороне - если есть какие-либо конфликты, вам будет предложено разрешить их локально при запуске git pull
.
Возможно, стоит отметить, что обновление, применяемое к удаленному репозиторию в ответ на push, является атомарным, поэтому в описанной выше ситуации примера, где S
и T
толкаются одновременно, всегда будет так, что один из них будет полностью применен, а другой - недействителен.
Заметка о вашей точке хранения ключа/значения
В то время как база данных объектов Git реализована как хранилище ключей/значений, которое сопоставляет имена объектов (также называемые хэшами или SHA1sums) с содержимым объектов, по моему опыту, людям легко научиться Git делать запутанные предположения о том, как Git ведет себя, когда они слышат "это как хранилище значений ключей" - это звучит так, как будто это может происходить в вашем случае, поэтому я бы предположил, что думать о Git на этом уровне не является наиболее полезный подход для понимания этой проблемы.