Яка різниця між git merge
і git rebase
?
Яка різниця між git merge
і git rebase
?
Відповіді:
Припустимо , що спочатку було 3 фіксацій, A
, B
, C
:
Тоді розробник Дан створив фіксацію D
, а розробник Ед створив фіксацію E
:
Очевидно, цей конфлікт треба якось вирішити. Для цього є два способи:
МЕРЕ :
Обидва здійснюють D
і E
все ще є тут, але ми створюємо команду злиття, M
яка успадковує зміни від обох D
і E
. Однак це створює форму алмазів , яку багато людей вважають дуже заплутаною.
ПОДАЧА :
Ми створюємо фіксацію R
, фактичний вміст файлу якого є ідентичним змісту комісії злиття M
вище. Але ми позбавляємося від прихильності E
, як ніколи її не існувало (позначається крапками - зникаюча лінія). Через це знищення E
повинно бути локальним для розробника Еда і ніколи не повинно було переноситись до будь-якого іншого сховища. Перевага ребазу полягає в тому, що форму алмазу уникають, а історія залишається приємною прямою лінією - більшість розробників це люблять!
git merge
не втручається (але це може здатися, переглядаючи git log
). Натомість git merge
обидві історії розвитку Дена та Еда зберігаються недоторканими, як це було видно з кожної точки зору одночасно. git rebase
виглядає так, що Дан спочатку над цим працював, а Ед пішов за ним. В обох випадках (злиття та відновлення) фактичне дерево файлів у результаті абсолютно однакове.
Мені дуже подобається цей уривок з 10 речей, які я ненавиджу про git (він дає коротке пояснення для повторної роботи у другому прикладі):
3. Хитра документація
Сторінки чоловіків - це всемогутнє “f *** ти” 1 . Вони описують команди з точки зору комп’ютера, а не користувача. Справа в точці:
git-push – Update remote refs along with associated objects
Ось опис для людей:
git-push – Upload changes from your local repository into a remote repository
Оновлення, ще один приклад: (спасибі cgd)
git-rebase – Forward-port local commits to the updated upstream head
Переклад:
git-rebase – Sequentially regenerate a series of commits so they can be applied directly to the head node
І тоді ми маємо
git-merge - Join two or more development histories together
що є хорошим описом.
1. Без цензури в оригіналі
Особисто я не вважаю стандартну техніку діаграми дуже корисною - стрілки завжди, здається, спрямовують неправильний шлях для мене. (Вони, як правило, вказують на "батьків" кожного комітету, який у кінцевому підсумку є відсталим у часі, що дивно).
Щоб пояснити це словами:
З причин, які я не розумію, інструменти графічного інтерфейсу для Git ніколи не докладали великих зусиль, щоб представити історію злиття більш чітко, абстрагуючи окремі злиття. Тож якщо ви хочете "чистої історії", вам потрібно використовувати ребазу.
Мені здається, я пам'ятаю, що читав повідомлення в блогах від програмістів, які використовують лише rebase та інших, які ніколи не використовують rebase.
Спробую пояснити це на прикладі просто слів. Скажімо, інші користувачі вашого проекту працюють над користувальницьким інтерфейсом, а ви пишете документацію. Без оновлення ваша історія може виглядати приблизно так:
Write tutorial
Merge remote-tracking branch 'origin/master' into fixdocs
Bigger buttons
Drop down list
Extend README
Merge remote-tracking branch 'origin/master' into fixdocs
Make window larger
Fix a mistake in howto.md
Тобто, зливається і UI здійснює посеред вашої документації.
Якщо ви перезавантажили свій код на головний, а не зливати його, він виглядатиме так:
Write tutorial
Extend README
Fix a mistake in howto.md
Bigger buttons
Drop down list
Make window larger
Усі ваші комітети знаходяться вгорі (новіші), за ними - решта master
гілки.
( Відмова: я автор публікації "10 речей, які я ненавиджу про Git", про яку йдеться в іншій відповіді )
Хоча прийнята і найвигідніша відповідь чудова, я також вважаю корисним намагатися пояснити різницю лише словами:
злиття
ребаза
Короткий зміст: Коли можливо, перезавантаження майже завжди краще. Полегшити реінтеграцію в основну галузь.
Тому що? ➝ ваша функція може бути представлена як один великий "файл виправлення" (aka diff) щодо основної гілки, не потребуючи "пояснення" декількох батьків: Принаймні двоє, що виходять з одного злиття, але, швидше за все, набагато більше, якщо вони є було кілька злиття. На відміну від об'єднань, кілька повторних баз не складаються. (ще один великий плюс)
Редакція Git ближче до злиття. Різниця в базі даних:
Отже, це означає, що всі ваші місцеві комісії переміщені до кінця, після всіх віддалених фіксованих комісій. Якщо у вас є конфлікт злиття, ви також повинні вирішити його.
Я знайшов одну дійсно цікаву статтю про git rebase vs merge , подумав про те, щоб поділитися нею тут