У git, яка різниця між merge --squash та rebase?


363

Я новачок в git і намагаюся зрозуміти різницю між сквош і ребасом. Як я розумію, ви виконуєте сквош, коли робите ребаз.

Відповіді:


360

І те, git merge --squashі git rebase --interactiveінше може призвести до "розбитого" вчинення.
Але вони служать різним цілям.

створить розрізаний комірок на гілці призначення, не відзначаючи жодних зв'язків.
(Примітка: вона не створює зобов'язання відразу: вам потрібна додаткова git commit -m "squash branch")
Це корисно, якщо ви хочете повністю викинути гілку джерела, виходячи з (схема, взята з питання SO ):

 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. Використовувати і разом це ніколи не вдалося . Оскільки Git 2.22.1 (Q3 2019), ця несумісність стає явною:--commit--squash

Див. Комісію 1d14d0c (24 травня 2019 року) від Vishal Verma ( reloadbrain) .
(Об’єднав Хуніо С Хамано - gitster- у комітеті 33f2790 , 25 липня 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."));

відтворює деякі чи всі ваші зобов’язання на новій базі, дозволяючи вам робити сквош (або останнім часом «виправити», див. це питання ТА ), переходячи безпосередньо до:

git checkout tmp
git rebase -i stable

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

Якщо ви вирішите скосити всі комісії tmp(але, всупереч merge --squash, ви можете відтворити одні, а інші - накрутити).

Тож відмінності такі:

  • squashне торкається вашої вихідної гілки ( tmpтут) і створює одиночну комісію там, де ви хочете.
  • rebaseдозволяє продовжувати роботу над тією ж гілкою джерела (досі tmp) з:
    • нова база
    • чистіша історія

11
Gце c--d--e--f--gстисло разом?
Уейн Конрад

8
@Wayne: так, G у цих прикладах представляє tmpкоміти, складені разом.
VonC

3
@ Th4wn: Оскільки причини Git зі знімками всього проекту Gне будуть представляти однаковий вміст, ніж gчерез зміни, внесені користувачем X.
VonC

1
@VonC: не впевнений у цьому останньому коментарі. Якщо у вас git merge --no-ff tempзамість цього git merge --squash temp, ви отримуєте історію месіє, але ви також можете робити такі речі, як git revert eнабагато простіше. Це безладна, але чесна і прагматична історія, і головна гілка все ще залишається досить чистою.
naught101

2
@ naught101 Я згоден. Як пояснено в stackoverflow.com/a/7425751/6309 , мова йде також і про те, щоб не зламати git bisectабо git blameвикористовувати занадто часто (як у git pull --no-ff: stackoverflow.com/questions/12798767/… ). Існує не один підхід в будь-якому випадку, тому в цій статті описані три ( stackoverflow.com/questions/9107861 / ... )
VonC

183

Об'єднати коміти: зберігає всі коміти у вашій філії та перемежовує їх з комітами на базовій гілцівведіть тут опис зображення

Merge Squash: зберігає зміни, але опускає окремі зобов’язання з історії введіть тут опис зображення

Rebase: Це переміщення всієї гілки функцій починається на кінчику гілки master, ефективно включаючи всі нові комісії в master

введіть тут опис зображення

Детальніше тут


81

Об’єднати сквош об’єднує дерево (послідовність комітів) в один коміт. Тобто, вона розбиває всі зміни, внесені в n комітетів, в один комітет.

Rebasing - це повторне базування, тобто вибір нової бази (батьківської комісії) для дерева. Можливо, термін "меркурій" для цього є більш зрозумілим: вони називають це трансплантацією, тому що це просто так: вибір нового ґрунту (батьківська фіксація, корінь) для дерева.

Виконуючи інтерактивну базу даних, вам надається можливість скріншувати, вибирати, редагувати або пропускати комісії, які ви збираєтесь відновити.

Сподіваюся, що це було зрозуміло!


7
Коли я повинен проводити перезавантаження і коли слід робити сквош?
Мартін Тома

31

Почнемо з наступного прикладу:

введіть тут опис зображення

Тепер у нас є 3 варіанти об'єднання змін гілки функцій у головну гілку :

  1. Об’єднання об'єднань Збереже
    всі історії комісій гілки функцій та перемістить їх у головну гілку
    .

  2. Повторне об'єднання та об'єднання Приєднає
    всі історії комісій гілки функції в передній частині головної гілки
    НЕ додасть додаткових фіктивних комітів.

  3. Сквош і злиття
    Згрупуйте всі функції філій, що здійснюють фільтр, в один комітет, а потім додайте його в передній частині головної гілки
    .

Нижче ви можете дізнатися, як буде доглядати головна гілка за кожною з них.

введіть тут опис зображення

У всіх випадках:
Ми можемо безпечно ВИДАЛИТИ галузь функцій .


1
чи можете ви пояснити, що таке манекен чини на другому малюнку ?? Я початківець в git.
Юсуф

1
@Yusuf, це лише додаткова комісія, яка містить оновлення обох гілок, це
зафіксоване
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.