В git, в чем разница между слиянием --squash и rebase?

Я новичок в git, и я пытаюсь понять разницу между squash и rebase. Насколько я понимаю, вы выполняете сквош, когда делаете rebase.

Ответ 1

И git merge --squash, и git rebase --interactive могут создавать "сдавленный" коммит.
Но они служат разным целям.

создаст сжатый коммит в ветки назначения, не помечая никаких отношений слияния.
(Примечание: он не производит коммит сразу: вам нужен дополнительный git commit -m "squash branch")
Это полезно, если вы хотите полностью удалить исходную ветку, начиная с (схема взята из ТАКОГО вопроса):

 git checkout stable

      X                   stable
     /                   
a---b---c---d---e---f---g tmp

в:

git merge --squash tmp
git commit -m "squash tmp"

      X-------------------G stable
     /                   
a---b---c---d---e---f---g tmp

и затем удаляем ветку tmp.


Примечание: git merge имеет параметр --commit, но его нельзя использовать с --squash. Никогда нельзя было использовать --commit и --squash вместе.
Начиная с Git 2.22.1 (Q3 2019), эта несовместимость сделана явной:

Смотрите коммит 1d14d0c (24 мая 2019 г.) от Вишала Вермы (reloadbrain).
(Merged by Junio C Hamano -- [TG413] -- in commit 33f2790, 25 Jul 2019)

merge: отказать --commit с помощью --squash

Ранее, когда --squash был предоставлен, 'option_commit' молча отброшен. Это могло удивить пользователя, который пытался переопределить поведение сквоша без коммитов с использованием --commit в явном виде.

git/git builtin/merge.c#cmd_merge() теперь включает в себя:

if (option_commit > 0)
    die(_("You cannot combine --squash with --commit."));

воспроизводит некоторые или все ваши коммиты на новой базе, позволяя вам раздавить (или совсем недавно "исправить", см. этот SO вопрос), перейдя непосредственно к:

git checkout tmp
git rebase -i stable

      stable
      X-------------------G tmp
     /                     
a---b

Если вы решите раздавить все коммиты tmp (но, в отличие от merge --squash, вы можете выбрать переигрывание одних и подавление других).

Итак, различия:

  • merge не касается ветки вашего источника (здесь tmp) и создает один коммит, где вы хотите.
  • rebase позволяет продолжить работу в той же ветки источника (все еще tmp) с:
    • новая база
    • более чистая история

Ответ 2

Слияние коммитов: сохраняет все коммиты в вашей ветке и чередует их с коммитами на базовой ветке enter image description here

Merge Squash: сохраняет изменения, но пропускает отдельные коммиты из истории enter image description here

Rebase: это перемещает всю ветвь объекта, чтобы начать с кончика мастер-ветки, эффективно объединяя все новые коммиты в master

enter image description here

Больше здесь

Ответ 3

Слияние сквоша объединяет дерево (последовательность коммитов) в единую фиксацию. То есть, он сквозит, все изменения, сделанные в n, совершаются в одном коммите.

Rebasing повторно базируется, то есть выбирает новую базу (parent commit) для дерева. Может быть, для них более ясный термин: они называют это трансплантацией, потому что это только то, что: выбирая новое основание (parent commit, root) для дерева.

При выполнении интерактивной переадресации вам предоставляется возможность либо сквош, выбрать, изменить или пропустить коммиты, которые вы собираетесь переупаковать.

Надеюсь, что это было ясно!