Каждый раз, когда вы задаете вопрос , почему вы попадаете в области философии, которые могут быть довольно липкими. Но я все равно могу предложить два ответа (один из которых подтверждается документацией, как в ответе падавина .
Первая заключается в том, что первоначальная идея перебазирования заключается в том, что это то, что индивид сделал бы непосредственно перед или во время слияния с каким-то более авторитетным хранилищем.
Давайте изобретем двух игроков, Алису и Боба. У Алисы есть авторитетная версия: любой, кто хочет самую последнюю и лучшую версию программного обеспечения, идет к Алисе.
В репозитории Алисы есть несколько направлений развития:
...--o--o--o--o--o <-- master
\
o--o--o <-- feature/tall
и т. Д. Боб клонировал хранилище Алисы в какой-то момент, возможно, в этом пункте:
...--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
перед последними двумя коммитами, которые Алиса добавила к своему авторитетному master
.
Затем Боб разработал свою особенность, feature/short
, из его master
, поэтому у него есть:
A--B <-- feature/short
/
...--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
Он думает, что готов передать свой результат Алисе. Таким образом, он запускает git fetch origin
, чтобы получить любое из ее обновлений, и теперь у него есть это:
A--B <-- feature/short
/
...--o--o--o <-- master
|\
| o--o <-- origin/master
\
o--o--o <-- origin/feature/tall
Теперь он может обновить свой собственный master
, чтобы он указывал на тот же коммит, что и его origin/master
(текущий совет Алисы master
):
A--B <-- feature/short
/
...--o--o--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
Прежде чем доставить свою серию коммитов A--B
Алисе, он должен убедиться, что они работают. Таким образом, он может git checkout master && git merge feature/short
, который производит:
A---B
/ \
| M <-- feature/short
| /
...--o--o--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
Боб может проверить M
и убедиться, что он работает - так что теперь безопасно перебазировать A
и B
на вершине master
, давая:
[old commits, no longer in use]
|
| A'-B' <-- feature/short
| /
...--o--o--o--o--o <-- master, origin/master
\
o--o--o <-- origin/feature/tall
Обратите внимание, что коммит M
ушел из перебазированного feature/short
: теперь Боб должен доставить новую и улучшенную цепочку коммитов A'-B'
Алисе, и Алиса может выбрать, объединить их или выполнить быструю перемотку вперед. до B'
или как ей угодно.
Вторая идея заключается в том, что на самом деле невозможно скопировать коммит слияния. Копирование commit A
в A'
- это просто внесение тех же изменений, что и A
, по сравнению с его родителем. Копирование B
в B'
- это просто внесение изменений, которые B
внес в A
. Но вы не можете скопировать слияние; Вы должны сделать совершенно новое слияние. Это, конечно, возможно; и это то, что на самом деле делают старые -p
или новые фантазии --rebase-merges
: они просто определяют, где слияние происходило раньше, и делают новое - с, возможно, совершенно разными результатами, если новая база слияния отличается - везде, где это имеет смысл .
Один из двух родителей нового слияния очевиден: это перебазированный коммит копии из некоторого оригинального коммита, который был родителем исходного слияния. Родитель other - предполагающий слияние с двумя родителями, во всяком случае - на самом деле не так очевиден: иногда это неизменный исходный коммит, а иногда это перебазированный коммит. Так что эта работа сложнее, чем может показаться на первый взгляд. Старый, не -p
код перебазировки просто сказал: Это сложно, и мы в любом случае вообще не хотим делать это вообще, поэтому давайте не будем пытаться.
(Я бы сказал, что это неправильно - если вы наивно перебираете цепочку, включающую слияния, вы, вероятно, тоже хотите скопировать слияния, - но в то же время я бы сказал, что если вы наивно перебираете цепь, которая включает в себя слияния, вы недостаточно задумывались о том, что делаете. Так что поведение по умолчанию имеет смысл. Возможно, имеет смысл, если обнаружит слияния, которое собирается пропустить, и предупредит или потребует флаг. )