В этом репозитории, когда я открываю запрос на слияние и объединяю его, GitHub создает 2 коммита слияния, в примере изображения я решил некоторые конфликты и объединил. Я не делал сквош или перебазирование на ветке alteracoesPequenas
. Почему это происходит?
Изображение двух коммитов слияния в дереве git
@TTT Да, я сделал все через пользовательский интерфейс GitHub. Раньше я переустанавливал свои ветки перед запросом на вытягивание, но коммиты в дереве коммитов всегда оказывались «дублированными».
Если вы решите разрешать конфликты, перемещая свою ветку на master
, то вы «переписываете» коммиты в своей ветке и меняете их идентификаторы коммитов. Если вы затем попытаетесь обновить свой PR, отправив свою ветку, вы получите сообщение об ошибке, говорящее что-то вроде «кончик вашей ветки находится за ее удаленным аналогом», и Git предлагает сначала вытащить, а затем нажать. Если вы сделаете то, что предлагает Git, и вытащите, это объединит старую версию вашей ветки с вашей новой и вызовет дублирование идентификаторов. Вместо этого в этом случае вы должны принудительно нажать свою ветку.
Небольшая поправка может сделать это намного яснее:
когда я открываю запрос на слияние и объединяю его, GitHub создает 2 коммита слияния...
На самом деле, вы сделали первый коммит слияния, когда объединили master
в свою ветку для разрешения конфликтов, а GitHub сделал второй коммит слияния, когда вы выполнили запрос на извлечение. Это обычное явление, и не о чем беспокоиться.
Примечание из комментариев, подтверждающих, что вы разрешили конфликты в пользовательском интерфейсе GitHub:
Если вы сделали это в пользовательском интерфейсе, я могу понять, как может показаться, что GitHub сделал первое слияние, но на самом деле вы сделали это слияние, а GH просто помог вам это сделать. Это то же самое, что произошло бы, если бы вы объединили master в свою ветку локально на своей машине и вытолкнули ее обратно.
Если вас это беспокоит, вы, вероятно, можете избежать первого коммита слияния, который вы сделали. Чтобы разрешить конфликты в вашей ветке до завершения PR, вы можете либо слить целевую ветку, как вы это сделали, либо перебазировать свою ветку на целевую ветку. С помощью rebase вы переписываете свою ветку так, как будто вы прямо сейчас отделились от последней master
, а затем сделали все свои коммиты поверх этого. (Кстати, именно поэтому мы говорим, что вы перебазируете «на» master
вместо слияния master
«в» свою ветку.) С перебазированием ваша ветка будет линейной и не будет иметь начального коммита слияния.
Что касается коммита слияния, который GitHub создает после завершения PR, это связано с выбранной стратегией слияния, а «слияние» является параметром по умолчанию (и, возможно, предпочтительным вариантом для большинства проектов для слияний в долгоживущие общие ветки). GitHub предлагает 2 других варианта: «сквош, слияние», которые объединят все изменения в одну линейную фиксацию, а также «перебазирование, слияние»1, которые еще раз перебазируют вашу ветку на мастер, как вы потенциально сделали для разрешить конфликты. Обратите внимание, что если вы выберете эту опцию, GitHub снова изменит базу ваших коммитов, даже если ваша ветка уже обновлена до master
и не нуждается в ней. Я предполагаю, что они делают это, чтобы избежать путаницы, вызванной тем, что иногда ваши идентификаторы коммитов меняются, а иногда нет. Здесь они всегда будут меняться.
Итак, подытоживая все это:
Лично я предпочитаю перебазировать, чтобы избежать первого коммита слияния, но по-прежнему использовать слияние при завершении PR, чтобы иметь один коммит слияния в master
.
1 ИМХО, "rebase, merge" действительно нужно называть "rebase, fast-forward". Использование слова «слияние» подразумевает полулинейное слияние, которое может быть достигнуто путем перебазирования, а затем слияния с помощью --no-ff
, чтобы принудительно выполнить фиксацию слияния. Я предполагаю, что GH использует здесь «слияние» в значении по умолчанию для быстрой перемотки вперед, если это возможно, и в этом случае это всегда будет возможно. Этот выбор формулировки, вероятно, был бы более очевидным, если бы GH предлагал оба варианта, как это делает Bitbucket.
То, что вы видите, правильно и нормально. Слияние делает фиксацию слияния; вот что такое слияние. Так:
alteracoesPequenas
в master
, закрыв запрос на включение; но GitHub не стал бы этого делать из-за конфликтов слияния.master
в alteracoesPequenas
. (слияние фиксации)alteracoesPequenas
в master
, что и было вашей целью. (слияние фиксации)Все очень хорошо и правильно и полностью стандартно. Не переживай, будь счастлив.
ПРИМЕЧАНИЕ Другой психологической проблемой здесь может быть способ представления GitHub того, что произошло. Это не топологическая диаграмма, это просто плоский список коммитов, доступных из master
. Первый коммит слияния, который вы сделали, на самом деле не включен master
в том смысле, в каком вы, вероятно, думаете об этом; это "включено" alteracoesPequenas
. Только одна фиксация слияния включена master
, а именно фиксация слияния, которая закрыла запрос на извлечение.
Вы разрешили конфликты слияния локально или в пользовательском интерфейсе GitHub? Если вы сделали это в пользовательском интерфейсе, я могу понять, как может показаться, что GitHub сделал первое слияние, но на самом деле вы сделали это слияние, а GH просто помог вам это сделать. Это то же самое, что произошло бы, если бы вы объединили
master
в свою ветку локально на своем компьютере и вытолкнули ее обратно. Вот почему я сформулировал свой ответ так, как я это сделал, подчеркнув тот факт, что тот, кто разрешил конфликты, создал первый коммит слияния.