Что происходит, когда два разработчика вносят несовместимые изменения в master? - PullRequest
0 голосов
/ 24 января 2020

Мы оба начинаем с коммита в мастере. Я заменяю мастера на 1039 *, затем другой разработчик подталкивает его к мастеру. Скажем, у нас другой код в строках 1-10. Я не замечаю, а затем внести незначительное изменение в другом месте, совершить это. Другой разработчик делает то же самое.

Для несовместимого кода в строках 1-10, это просто чередование? Так сказать, кто-то еще тянет от мастера. Получают ли они другую строку 1-10 только на основании того, кто совершил последний? Так что теперь нам нужно правильно слиться в этой точке; мы объединяем его «мастер» и мой «мастер»?

Если так, то почему история изменений не показывает эти изменения как чередующиеся? В истории, даже несмотря на то, что код отличается, нет никаких признаков того, что это имеет место с красной / зеленой подсветкой.

Обратите внимание, что этот вопрос задает вопрос «что происходит?», А не « как избежать этой проблемы? "

Редактировать: видеть, что люди думают, что это не может произойти. Я не знаю, что тогда. Ни один из нас не разветвился, но все-таки вот так выглядела история

pic of branching

В коммите 283ab9ef Я совершил смену мастера.

Другой разработчик передал c4e654fb мастеру, в котором не было моего нового кода

Я дал d29e2fad мастеру, который снова получил эти изменения с 283ab9ef, несовместимые с его коммитом.

Позже я объединил их, разрешив конфликт. С нашей точки зрения, мы оба давили на мастера.

Редактировать 2:

Исходя из того, что я вижу из ответов ниже, все вопросы сводятся к как он pu sh c4e654 без получения ошибки конфликта? c4e654 имеет родителя a26bd4, но он подтолкнул к мастеру без ошибки, которая игнорирует изменения, которые я сделал в 283ab9

Ответы [ 4 ]

2 голосов
/ 24 января 2020

коммитов имеют идентификаторы ha sh. (Запустите git log, чтобы увидеть их.) Идентификатор ha sh - это истинное имя каждого коммита, поэтому легко определить, есть ли у вас какой-либо коммит: у вас есть этот идентификатор ha sh? Если так, у вас есть этот коммит. Если нет, вы можете получить этот коммит из любого репозитория Git, который показал, что у вас есть sh ID.

Когда вы или кто-либо другой делаете коммит новый , этот новый коммит получает новый уникальный идентификатор ha sh. Ни один другой коммит нигде не может использовать этот га sh ID. Этот ha sh ID теперь предназначен для вашего коммита. (На самом деле, если мы заранее точно знали, что вы собираетесь добавить в свой коммит - ваше имя, адрес электронной почты, метки даты и времени, сообщение журнала, снимок источника, родительский коммит ha sh ID, et c. - мы могли бы сказать вам, что будет ha sh ID . Конечно, мы никогда не сможем заранее знать, в какое время вы сделаете свой коммит или какое сообщение в журнале вы введите * et c.)

Но каждый коммит также хранит необработанный идентификатор ha sh своего непосредственного родительского коммита. Итак, вы и этот другой разработчик начинаете работать. Давайте дадим вам два имени, чтобы сделать это проще. Я буду называть тебя "ты", а он / она / они "они". Вы делаете свой коммит; его родитель - какой-то большой уродливый га sh ID, a123456... или что-то еще. Они делают их коммит; его родитель тоже a123456.... Вы и они запускаете git push origin master.

. На этом этапе мы должны сделать дополнительное замечание: внутри каждого коммита полный и полный снимок всех файлов . Ваш снимок имеет полную копию файла с тем, что вы сделали в этих строках. Их снимок имеет полную копию файла с тем, что они сделали в этих строках. Родительский коммит, a123456..., имеет полную копию того, что было в файле ранее. Это не имеет прямого отношения к этому вопросу, но поможет позже, когда вы подумаете о процессе объединения.

В любом случае, вы и они оба запускаете git push origin master. Один из вас «выигрывает гонку», потому что вы не можете одновременно вызвать третий Git на origin: этот третий Git будет удерживать «телефонный звонок», пока один из Вы сделали. Допустим, вы выиграли гонку. Вы отправляете свой новый коммит - давайте назовем его b789abc... - Git на origin, и он говорит мой родительский коммит a123456.... Git в origin имеет свои master в a123456 прямо сейчас. Таким образом, Git в origin видит, что это просто добавляет к его коллекции коммитов: он помещает коммит b789abc в его коллекцию и устанавливает его master для запоминания b789abc.

Теперь, когда ваш pu sh готов, их начинается по-настоящему. Они отправляют свой коммит, с каким бы ни был его sh ID, на Git в origin. Их коммит говорит мой родительский коммит a123456. * * * * * Git в оригинале говорит: Ух ты, подожди, мой master равен b789abc, и если я возьму твой и положу т sh ID как мой master, я полностью забуду совершу b789abc и потеряю его навсегда! Так что нет, я не возьму ваш коммит!

Кто бы ни проиграл эту гонку пу sh, он видит их пу sh rejected как non-fast-forward. Победитель выигрывает, а проигравший должен выполнить больше работы.

В этом случае они - кем бы они ни были - должны использовать git fetch для получения вашего коммита, b789abc..., из Git на origin. (Это Git теперь вызывает этот конкретный коммит своим master.) Теперь они будут иметь в своем хранилище последовательность коммитов, которая выглядит так:

             c987654   <-- master (HEAD)
            /
...--a123456
            \
             b789abc   <-- origin/master

(при условии, что их коммит c987654...) .

Теперь они - а не Git в origin - должны объединить вашу работу и их работу, что они могут сделать любым количеством способов. Они имеют их снимок всех файлов, включая их работу, ваш снимок всех файлов, включая вашу работу, и общий начальный моментальный снимок. Они должны объединить эти три коммита некоторым подходящим способом, чтобы получить четвертый коммит:

             c987654
            /       \
...--a123456         d888888   <-- master (HEAD)
            \       /
             b789abc   <-- origin/master

например, где этот d888888... коммит представляет собой слияние , или, может быть:

             c987654   [abandoned]
            /
...--a123456         edcba98   <-- master (HEAD)
            \       /
             b789abc   <-- origin/master

, где edcba98... коммит происходит от rebase (копировать, но изменять при копировании) коммита c987654....

Теперь они могут git push свой новый коммит, каким бы он ни был, в Git в origin, потому что у них будет их новый коммит, помните, как его родитель, коммит, являющийся коммитом коммита master в origin, так что их новый коммит просто расширяет origin master.

1 голос
/ 24 января 2020

Другой разработчик не может освоить sh до тех пор, пока он не потянет ваши изменения первым. В этот момент, если существуют конфликтующие изменения между вашим коммитом, который собирается получить, и его коммитом, git вызовет конфликт слияния .

Другой разработчик затем должен исправить конфликты, коммит, а потом пу sh. Таким образом, конкретная ситуация, которую вы описываете, не может возникнуть.

Со ссылкой на ваш третий абзац, разрешение конфликта действительно приведет к новому коммиту слияния, который можно увидеть в истории коммитов.

0 голосов
/ 24 января 2020

Предполагая, что PR не участвует ... git отклонит pu sh, который делает другой разработчик. Git заставит их тянуть, после чего конфликты слияния будут реализованы, и разработчик должен будет исправить эти различия в коде, чтобы определить, какой код использовать для их pu sh.

0 голосов
/ 24 января 2020

Не совсем .... git не позволит второму разработчику pu sh, если они не будут принудительно ... поэтому при нормальном рабочем процессе git отклонит pu sh и спросит разработчик должен объединиться ... когда разработчик объединится, он / она получит конфликт, который они должны будут разрешить, чтобы иметь возможность проверить sh.

Любое другое лицо, которое начинает работать из этой ветви. получит любую ревизию в конце ветви, когда они последний раз клонируются или выбираются.

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