Ну, слияние и перезагрузка - принципиально разные операции. Слияние-я имею в виду регулярные git merge
что создает новое слияние совершить, действительно искать назад через фиксации графика для самого последнего общего фиксации:
...--o--*--o--o--A <-- mainbr
\
B--C--D--E <-- sidebr
Здесь самая последняя общая фиксация будет *
. Затем процесс слияния сравнивается (как в git diff
) с фиксацией *
с фиксацией A
, чтобы узнать, «что мы сделали», и diff *
против фиксации E
, чтобы узнать «что они сделали». Затем он делает новый сингл слияния коммит, с двумя родителями:
...--o--*--o--o--A---M <-- mainbr
\ /
B--C--D--E <-- sidebr
, который соединяет две истории, и сочетает в себе «что мы сделали», и «то, что они сделали», так что сравниваете *
против M
дает «один из каждое изменение ".
Обратите внимание, что здесь нет выбора базы слияния: Git вычисляет это, и все.
С другой стороны, с другой стороны может быть заявлено, что с другой стороны может быть заявлено, что для того, чтобы скопировать, и где их копировать, можно указать отдельно. Это правда, что по умолчанию он снова фиксирует *
-but then копии оригинал фиксирует один за другим, используя git cherry-pick
или его эквивалент; и, наконец, он перемещает ветвь метку, чтобы указать на последнюю скопированную фиксацию.
...--o--*--o--o--A <-- mainbr
\ \
\ B'-C'-D'-E' <-- sidebr
\
B--C--D--E
оригинальная цепь фиксаций (B-C-D-E
, в данном случае) все еще находится в хранилище, и до сих пор обнаружимый: они могут быть найдены с помощью хэш-ID, и в reflog для sidebr
, и если какой-либо другого название ветки или тега делает их доступными, они остаются доступными под этим именем.
Что git merge --squash
делает это просто немного изменить процесс слияния: вместо того, чтобы объединить совершить M
, Git идет через слияние машин как обычно, сравниваете на слияние базы-которой вы не можете выбрать, против текущая фиксация и другая фиксация и объединение изменений в индексе и дереве.Он тогда без всякой видимой причины -stops и заставляет вас работать git commit
совершить результат, и когда вы делаете, это обычное, не слияние совершить, так что весь граф-фрагмент выглядит следующим образом:
...--o--*--o--o--A--F <-- mainbr
\
B--C--D--E <-- sidebr
Теперь, содержание коммиттерских F
-The снимок дерева в результате слияния, так же, как содержание фиксации M
когда мы делаем реальное слияние, и-вот реальный кикер-это также то же, что и содержание фиксации E'
, когда мы делаем rebase.
Кроме того, предположим, что только одна фиксация (B
) на боковой ветке sidebr
. Теперь все три из merge
, merge --squash
и rebase
даст вам картину, которая заканчивается с чем-то мы могли бы просто сделать так:
...--o--*--o--o--A--B' <-- ???
\ ?
B????????? <-- ???
и содержание нового фиксации B'
, т.е. конечный снимок, является то же самое во всех трех случаях. Однако для git merge
новый фиксатор будет находиться на ветке mainbr
и будет указывать на A
и B
, с sidebr
, указывая на B
; для git merge --squash
, новая фиксация будет на mainbr
и укажет только на A
; и git rebase
, новый будет совершать на sidebr
, ни с чем не очевидным, указывающей B
на всех, и мы должны сделать это так:
...--o--*--o--o--A <-- mainbr
\ \
B B' <-- sidebr
так mainbr
будет продолжать указывать на совершение A
.
В конце концов, это выглядит немного больше похоже на слияние, чем на восстановление. (Тем не менее, я был бы счастлив, если бы не были названы «сквош слияние» на всех.)
Метод, с помощью которого Git находит *
несколько иначе: на самом деле это не одно обязательство, а скорее как последний из (обычно) очень большой набор коммитов, а именно всех тех, которые достижимы из аргумента <upstream>
до git rebase
. (Смутно, слияние база также может быть множество фиксаций, но это гораздо более ограниченный набор. Лучше не погружаться в теорию графов еще. :-))
Если мы хотели это чтобы остановить, мы могли бы использовать --no-commit
так же, как и для обычного, без сквоша git merge
. Итак, почему делает автоматически останавливается?
'merge --squash' просто сжимает все коммиты из ветки в одну. Он не изменяет историю. –
Что говорит Энди, так это то, что раздавливание происходит до слияния, поэтому с точки зрения целевой ветви он все еще только видит слияние. –
Моя точка была после регулярного слияния, на графике показаны две ветви, которые были объединены, объединены в один узел слияния, но после слияния --squash & commit график показывает, что две ветви еще раздельны, но с изменениями от mybranch, на текущую ветвь. Для меня это больше похоже на перебазу, которая была сжата в одну фиксацию.Но реальный вопрос, который я задавал, заключался в том, что моя концепция того, что происходит слиянием --squash, была в корне корректной и из расширенного ответа от @torek. Я пришел к выводу, что, хотя есть еще более сложные детали, которые еще предстоит изучить. – JonN