Яка різниця між 'git merge' та 'git rebase'?


499

Яка різниця між git mergeі git rebase?


14
оскільки моя відповідь була видалена, перейдіть за цим посиланням, щоб отримати правильну відповідь на це питання: git-scm.com/book/en/Git-Branching-Rebasing#The-Basic-Rebase
HiB

6
До речі я додам цей сайт. Все, що потрібно знати про git Learn,
Rollyng

Прочитайте спочатку: git-scm.com/book/en/v2/… Потім: git-scm.com/book/en/v2/Git-Branching-Rebasing Ви дійсно зрозумієте.
Liber

Відповіді:


867

Припустимо , що спочатку було 3 фіксацій, A, B, C:

ABC

Тоді розробник Дан створив фіксацію D, а розробник Ед створив фіксацію E:

ABCDE

Очевидно, цей конфлікт треба якось вирішити. Для цього є два способи:

МЕРЕ :

ABCDEM

Обидва здійснюють Dі Eвсе ще є тут, але ми створюємо команду злиття, Mяка успадковує зміни від обох Dі E. Однак це створює форму алмазів , яку багато людей вважають дуже заплутаною.

ПОДАЧА :

ABCDER

Ми створюємо фіксацію R, фактичний вміст файлу якого є ідентичним змісту комісії злиття Mвище. Але ми позбавляємося від прихильності E, як ніколи її не існувало (позначається крапками - зникаюча лінія). Через це знищення Eповинно бути локальним для розробника Еда і ніколи не повинно було переноситись до будь-якого іншого сховища. Перевага ребазу полягає в тому, що форму алмазу уникають, а історія залишається приємною прямою лінією - більшість розробників це люблять!


53
Приємні ілюстрації. Однак я не повністю згоден з позитивним тоном, з яким обробляється база даних. Як у злитті, так і в перезавантаженні можуть виникати конфлікти, які потребують ручного вирішення. І як завжди, коли беруть участь програмісти, є нехтуючий шанс помилок, таких як помилки. Якщо трапляється помилка злиття, вся команда чи спільнота може побачити злиття та перевірити, чи була там введена помилка. Історія відновлення зберігається в репо-програмі 1 розробника, і навіть там вона має обмежений термін експлуатації в рефлогу. Це може виглядати приємніше, але ніхто більше не може так легко зрозуміти, що пішло не так.
Uwe Geuder

> "Однак це створює форму алмазів, яку багато людей вважають дуже заплутаною." Гм ... чи можете ви докладно?
Грег Малетич

@GregMaletic: форма алмазу - нелінійна історія. Я не знаю про вас, але я не люблю нелінійні речі взагалі. Однак це означає, що ви можете використовувати злиття з діамантами, якщо ви дійсно віддаєте перевагу - ніхто не змушує вас.
mvp

1
Хоча ця відповідь надзвичайно корисна, було б краще, якщо ви додали фактичні команди git за допомогою простих файлів foo.txt, щоб відтворити її локально. Як сказав останній користувач, не очевидно, хто робить ребауз.
Vortex

1
@pferrel: Я не думаю, що ти це правильно зрозумів. git mergeне втручається (але це може здатися, переглядаючи git log). Натомість git mergeобидві історії розвитку Дена та Еда зберігаються недоторканими, як це було видно з кожної точки зору одночасно. git rebaseвиглядає так, що Дан спочатку над цим працював, а Ед пішов за ним. В обох випадках (злиття та відновлення) фактичне дерево файлів у результаті абсолютно однакове.
mvp

158

Мені дуже подобається цей уривок з 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 вимагає розуміння засобів, щоб зрозуміти цілі. Саме розуміння засобів робить Git таким важким. Як інструмент, що використовується для спрощення або зменшення зусиль, необхідних для виконання завдань, Git жахливо виходить з ладу. На жаль, занадто багато чортів не вдається цього усвідомити.
ATL_DEV

128

Особисто я не вважаю стандартну техніку діаграми дуже корисною - стрілки завжди, здається, спрямовують неправильний шлях для мене. (Вони, як правило, вказують на "батьків" кожного комітету, який у кінцевому підсумку є відсталим у часі, що дивно).

Щоб пояснити це словами:

  • Коли ви переставляєте свою філію на свою гілку, ви скажете Git, щоб вона виглядала так, ніби ви чисто перевірили її відділення, а потім виконали всю свою роботу, починаючи звідти. Це робить чистий, концептуально простий пакет змін, який хтось може переглянути. Ви можете повторити цей процес ще раз, коли на їхній гілці з’являться нові зміни, і ви завжди закінчитеся чистим набором змін «на кінчику» їх гілки.
  • Коли ви об’єднуєте їх гілку у вашу гілку, ви зв'язати дві історії гілки разом у цей момент. Якщо ви знову зробите це пізніше з більшою кількістю змін, ви почнете створювати переплетену нитку історій: деякі їх зміни, деякі мої зміни, деякі їх зміни. Деякі люди вважають це безладним чи небажаним.

З причин, які я не розумію, інструменти графічного інтерфейсу для 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", про яку йдеться в іншій відповіді )


42

Хоча прийнята і найвигідніша відповідь чудова, я також вважаю корисним намагатися пояснити різницю лише словами:

злиття

  • «Гаразд, у нас є два різні розвинені стани нашого сховища. Давайте об’єднаємо їх разом. Два батьки, одна дитина, що виникла ».

ребаза

  • "Надайте зміни основної гілки (незалежно від її назви) моїй функції функції. Зробіть це, роблячи вигляд, що моя художня робота почалася пізніше, фактично про сучасний стан основної гілки ».
  • "Перепишіть історію моїх змін, щоб це відобразити". (потрібно змусити їх натиснути, тому що зазвичай версія полягає в тому, щоб не підробляти дану історію)
  • "Ймовірно - якщо зміни, які я заграв, мало стосуються моєї роботи - історія насправді не зміниться багато, якщо я подивлюся на свої зобов'язання різними (можна також подумати про" виправлення ")."

Короткий зміст: Коли можливо, перезавантаження майже завжди краще. Полегшити реінтеграцію в основну галузь.

Тому що? ➝ ваша функція може бути представлена ​​як один великий "файл виправлення" (aka diff) щодо основної гілки, не потребуючи "пояснення" декількох батьків: Принаймні двоє, що виходять з одного злиття, але, швидше за все, набагато більше, якщо вони є було кілька злиття. На відміну від об'єднань, кілька повторних баз не складаються. (ще один великий плюс)


18

Редакція Git ближче до злиття. Різниця в базі даних:

  • місцеві комісії тимчасово видаляються з гілки.
  • запустити тягу
  • вставити знову всі ваші місцеві комісії.

Отже, це означає, що всі ваші місцеві комісії переміщені до кінця, після всіх віддалених фіксованих комісій. Якщо у вас є конфлікт злиття, ви також повинні вирішити його.


7

Для легкого розуміння можна побачити мою фігуру.

Rebase змінить хеш комісій, так що якщо ви хочете уникнути великої кількості конфліктів, просто використовуйте rebase, коли ця гілка виконана / завершена як стабільна.

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


0

Я знайшов одну дійсно цікаву статтю про git rebase vs merge , подумав про те, щоб поділитися нею тут

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