Подтвердить что ты не робот

Как работает git, когда два одноранговых узла одновременно меняют изменения на один и тот же удаленный

Я новичок в git, я обычно использую P4, у которого есть центральный репозиторий, а git - распределенный VCS.

Меня интересует, как работает git, когда два одноранговых узла одновременно меняют изменения на один и тот же удаленный. Предположим, что каждый участник разрешил все конфликты перед нажатием. Я думаю, что более поздний будет отклонен, если git сообщает о конфликтах!

Однако из того, что я понимаю, git является внутренним хранилищем ключей/значений, так же, как и текущая популярная база данных NOSQL, особенно Couch-DB, которая поддерживает репликацию p2p.

На самом деле, я хочу спросить, как конфликтует процесс git в том случае, если клиенты вносят изменения в удаленный репозиторий git? Отклонено ли нажатие кнопки?

От ответа Марка, я думаю, что толчок должен быть отклонен.

4b9b3361

Ответ 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 на этом уровне не является наиболее полезный подход для понимания этой проблемы.