Git branch --merged / --no-merged и опция --squash
git branch --merged
Похоже, не очень хорошо играть с --squash.
Если вы делаете нормальный git merge
, затем git branch --merged
говорит вам, какие ветви были объединены. Однако это не тот случай, если используется опция --squash, даже если результирующее дерево одно и то же.
Я сомневаюсь, что это дефект мерзавца, и хотел бы знать, есть ли какой-то мерзавец, которого я пропускаю, или я что-то неправильно понял.
Короче говоря: я хочу использовать --squash, но также хочу, чтобы git сообщал мне, была ли ветвь, в которую я врезался, в другую.
1 ответ
Вы не можете добраться туда отсюда (как сказал парень, дающий указания). Точнее, это не имеет смысла.
Проблема в том, что git merge --squash
на самом деле не делает слияние. Предположим, например, что история вашей ветки выглядит так (с ветками topic
а также devel
):
H ⬅ I ⬅ J <-- topic
⬋
⬅ F ⬅ G
⬉
K ⬅ L <-- devel
Если вы проверите devel
и объединить topic
Вы получаете новый коммит слияния M
который содержит результат слияния, и M
имеет двух родителей:
H ⬅ I ⬅ J <-- topic
⬋ ⬆
⬅ F ⬅ G ⬆
⬉ ⬆
K ⬅ L ⬅ M <-- devel
Но если вы используете git merge --squash topic
вместо этого вы получаете новый коммит S
для сквоша):
H ⬅ I ⬅ J <-- topic
⬋
⬅ F ⬅ G
⬉
K ⬅ L ⬅ S <-- devel
где (как вы уже отметили) содержимое (дерево) коммита S
делает все файлы такими же, как и при коммите M
, Но нет обратной ссылки (родительской стрелки) от S до topic
, Это не слияние, а просто принятие всех изменений topic
объединяя их в одно изменение, и добавляя это как совершенно независимый коммит.
Теперь другая вещь о git merge --squash
в том, что он не делает окончательный коммит. Таким образом, вы могли бы создать .git
файлы, которые git будет выполнять при "обычном" слиянии, и делать коммит с двумя родителями, которых вы получите при "реальном" слиянии. И тогда вы получите... именно то, что вы получите, если запустить git merge topic
, коммит (пометить его S
или же M
, это не имеет значения), которое имеет то же самое дерево снова, но теперь имеет две родительские стрелки, указывающие на L
а также J
, как M
,
На самом деле, работает git merge --squash
почти точно так же, как работает git merge --no-commit
за исключением файлов трассировки, оставленных после слияния (git commit
использует некоторые из них, чтобы настроить родителей). squash
версия не пишет в .git/MERGE
, .git/MERGE_HEAD
, а также .git/MERGE_MODE
, (Это создает .git/MERGE_MSG
, такой же как git merge --no-commit
и это также создает .git/SQUASH_MSG
.)
Таким образом, в основном у вас есть выбор: реальное слияние (два или более родителей на последнем коммите) или сквош (те же механизмы объединения деревьев, но только один родитель на последнем коммите). И с тех пор git branch --merged
работает, глядя на "родительские стрелки" каждого коммита, хранящегося в репозитории, только реальное слияние - это действительно слияние, поэтому только реальное слияние может быть обнаружено позже git branch
,