В чем разница между объединением мастера в ветку и объединением ветки в мастер?

У меня есть ветвь с именем master, а другая - dev. Обычно я выполняю тесты и улучшения на dev, и, когда было решено, что все в порядке, я объединять его в master, а затем помечать и выпускать новую версию приложения. Я встретил два случая слияния:

  • merge master в dev и
  • merge dev в master,

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

Ответ 1

TL; DR

Основное различие заключается в том, что ветки master и dev в конечном итоге указывают. enter image description here

Полное объяснение

Объединение одной ветки в другую не является симметричной операцией:

  • слияние dev в master и
  • слияние master в dev,

вообще говоря, не эквивалентны. Вот иллюстративный пример, объясняющий разницу между ними. Пусть ваше репо выглядит следующим образом:

enter image description here

Если вы объедините dev в master

Если master выгружено (git checkout master),

enter image description here

и затем вы слейте dev (git merge dev), вы попадете в следующую ситуацию:

enter image description here

Теперь ветвь master указывает на новое объединение слиянием (F), тогда как dev все еще указывает на тот же commit (E), что и до слияния.

Если вы объедините master в dev

Если, с другой стороны, dev проверяется (git checkout dev),

enter image description here

и затем вы слейте master (git merge master), вы попадете в следующую ситуацию:

enter image description here

Теперь ветвь dev указывает на новую фиксацию слияния (F', тогда как master все еще указывает на то же самое, что и до слияния (D)).

Объединяя все вместе

enter image description here

Ответ 2

Ответ @jubobs хорошо объясняет, но кроме того, что код будет одинаковым, хэши двух возможных слияний будут другими.

Кроме того, важно отметить, что если две ветки разошлись, вам придется объединить все наоборот, если вы хотите продолжить работу оттуда или если вы хотите опубликовать ветку. Если вы сделали

git checkout master
git merge dev

Вы бы не увидели различий с git diff dev но "странные" различия появились бы с git checkout dev; git diff master git checkout dev; git diff master потому что dev все еще указывает на свою оригинальную версию и ничего не знает о происходящих слияниях. Указатели не вызывают неинтуитивных ситуаций только в языках программирования (см. Пример ссылочной прозрачности).

Если вместо этого вы сделали...

git checkout dev
git merge master

С git diff master вы не увидите никаких отличий, но с git checkout master; git diff dev вы увидите различия git checkout master; git diff dev git checkout master; git diff dev.