Чому git pull виконує злиття замість повторної бази за замовчуванням?


71

Розглянемо таку ситуацію:

  • У вас є клон сховища git
  • У вас є місцеві коміти (комітети, які ще ніде не були витіснені)
  • У віддаленому сховищі є нові комісії, які ви ще не узгодили

Тож щось подібне:

Безрезультатні зобов’язання

Якщо виконати git pullналаштування за замовчуванням, ви отримаєте щось подібне:

злиття

Це тому, що git виконував злиття.

Однак є й альтернатива. Ви можете сказати тягнути, щоб зробити ребауз замість цього:

git pull --rebase

і ви отримаєте це:

переоформлений

На мою думку, версія, що базується, має численні переваги, які в основному зосереджуються на чистоті вашого коду та історії, тому мене трохи вражає той факт, що git робить злиття за замовчуванням. Так, хеші місцевих комітетів будуть змінені, але це здається невеликою ціною, яку потрібно заплатити за простішу історію, яку ви отримаєте взамін.

Я жодним чином не припускаю, що це якимось чином поганий чи неправильний дефолт. У мене просто виникають проблеми з думкою про причини, чому злиття може бути кращим за замовчуванням. Чи маємо ми зрозуміти, чому його обрали? Чи є переваги, які роблять його більш придатним як за замовчуванням?

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

Було запропоновано, що це питання є дублікатом Чому так багато веб-сайтів віддають перевагу "git rebase" перед "git merge"? ; однак це питання дещо зворотне . У ньому обговорюються достоїнства rebase перед злиттям, тоді як це питання задає переваги злиття над rebase. Відповіді на це відображають це, зосереджуючи увагу на проблемах із об'єднанням та перевагами бази даних.



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

якщо sourcetree коли-небудь змінить свій графічний вигляд, щоб він відображав відміни / злиття по-іншому, ви перейдете до об'єднання?
Еван

1
@Ewan SourceTree не повинен змінювати перегляд цього графіка. Він точно відображає графік.
jpmc26

4
Звертаючи увагу виборців, будь ласка, зауважте, що зміст у відповіді, яку я прийняв, безумовно, немає у запитанні, на яке ви заявляєте, є дублікатом.
jpmc26

Відповіді:


56

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

Ось теорія ...

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

У команді, яка не просто використовує Git для централізованого контролю джерел ...

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

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

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

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

Для підтвердження наміру, ось посилання на добре відомий електронний лист від Лінуса Торвальда з його поглядами на те, коли вони не повинні переглядати дані. Dri-devel git pull email

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

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

Пропозиція. Не проводьте політику щодо зміни за замовчуванням. Кожен раз, коли ви з’єднаєте Git разом із великою групою розробників, деякі розробники не зрозуміють Git все так глибоко (включаючи і мене). Вони перейдуть до Google, ТАК, отримають поради з кулінарної книги, а потім задумаються, чому деякі речі не працюють, наприклад, чому git checkout --ours <path>виходить неправильна версія файлу? Ви завжди можете переглянути місцеве оточення, зробити псевдоніми тощо на ваш смак.


5
+1 за те, що не змінюється типова умова - замість того, щоб прокручувати власний робочий процес git, можливо, краще схопити той, який існує (наприклад, будь-який із тих, що зафіксовано Atlassian atlassian.com/git/tutorials/comparing-workflows/… )
Rob Church

1
Дякую за відповідь. Інформація про тягнути з нижньої течії - це те, чого я бракував. Крім того, що цікаво, посилання, яке ви надали, заохочує саме те, що я хотів би досягти: "Люди можуть (і, мабуть, повинні) переробити свої приватні дерева (власну роботу)".
jpmc26

2
@jpmc Чудово. Справді. Видання приватних дерев може утримати багато відволікаючих сирих у спільній історії. Я роблю це. Чіткість того, коли цього не робити, важливо.
joshp

"деякі розробники не зрозуміють Git все так глибоко". Rebase НЕ надто фантастична ("глибока" тощо) особливість Git. Ви справді вважаєте цю річ важкою для розуміння? Я думаю, що це повинно стати поводом для того, щоб назвати dev некомпетентним.
Віктор Ярема

15

Якщо ви читаєте сторінку git для повторної роботи, вона говорить :

Звільнення (або будь-яка інша форма перезапису) гілки, над якою працюють інші, - погана ідея: будь-хто після неї змушений вручну виправити свою історію. У цьому розділі пояснюється, як зробити виправлення з точки зору нижньої течії. Справжнім виправленням було б у першу чергу уникнути повторного викиду вгору за течією.

Я думаю, що це говорить досить добре, як причина взагалі не використовувати rebase, не кажучи вже про автоматичне виконання кожного підключення. Деякі люди вважають, що база даних є шкідливою . Можливо, його взагалі ніколи не слід було вводити в git, оскільки, як видається, це - це вишукання історії, що не повинно бути необхідним жодному СКМ, єдиною важливою завданням якої є збереження історії.

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


3
@Ewan IMHO "не працює, але виглядає красиво" - це те, що має бути виключно зарезервовано для індустрії моди, а не для ІТ. IMHO git повинен його усунути, оскільки це, очевидно, спонукає занадто багато людей до думки, що стиль важливіший за суть.
gbjbaanb

12
Я б заперечував вашу думку про те, що зберігати історію в чистоті марно. Це не. Історія сховищ призначена для споживання людиною, і тому вона має велику цінність для її читання. У моєму конкретному випадку ми навіть маємо намір, щоб менеджери проектів, які не розробники, мали змогу читати історію. Чиста історія може допомогти лише в цьому, і вона може допомогти новому розробнику, який ніколи не бачив кодову базу і повинен зануритися і виправити помилку, щоб зрозуміти, що сталося в певній області коду.
jpmc26

3
Код існує в першу чергу для виконання машиною (можливо, після його складання). Застосовуючи філософію вище, ми б зробили висновок, що читабельність коду не має значення, оскільки жодна кількість читабельності не вирішить труднощі розуміння коду. Я ніколи не припускав, що що-небудь слід розчавити. Я просто кажу, що складний графік, який розходиться на багато шляхів перетину, важко прослідкувати, тому варто трохи вкласти їх у збереження історії. Зауважимо також, що лінійна історія більше сприяє використанню інструментів git, таких як звинувачення та бісект.
jpmc26

6
Документи не кажуть "не перезавантажувати". У ній сказано, "не перезавантажуйте зміни, що є вище за інших людей ". Між цими двома існує світ різниці. Сам Лінус радить деякі звільнення для організації історії, як це видно за посиланням у прийнятій відповіді. І як би будь-який інструмент знав, які комісії не мають значення (особливо, якщо інструменти мають труднощі з аналізом нелінійної історії!), І як би ви могли знати, з якою командою ви хочете відрізнятись (особливо, не маючи змоги копати історію!)? Ви приймаєте слово обережності щодо конкретної ситуації до догматичної крайності.
jpmc26

4
Ви точно не хочете "зберігати історію ревізій", якщо це включає всі зобов'язання, які розробник коли-небудь робив. Дотримуючись цієї логіки, ми також повинні записувати оригінальну версію коду кожного разу, коли натискається клавіша. Кожна фіксація повинна бути мінімальною і повною зміною, яка все ще підтримує весь проект у стабільному стані. Якщо згодом ваш оригінальний комітет виявляється помилковим, набагато краще перезавантажити / відредагувати / змінити комісію, ніж створити інший. Однак дивіться також mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html
Mikko Rantalainen

12

Ви правильні, припускаючи, що у вас є лише одне локальне / змінене сховище. Однак, розгляньте, наприклад, що існує другий локальний ПК.

Після того, як ваша локальна / модифікована копія буде натиснута кудись інше, повторне видалення копіюватиме ці копії. Звичайно, ви можете натиснути, але це швидко ускладнюється. Що станеться, якщо один або кілька із них мають ще один абсолютно новий поступ?

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


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


1
"Після знижок дуже ймовірно, що старі комісії можуть слідувати новішим змінам", - але це відбувається і з злиттями, саме тому вам (можливо) потрібен гарний графік, щоб зрозуміти це. Час, коли було здійснено зобов’язання, може бути задовго до злиття, яке призвело його до цієї галузі.
Стів Джессоп

6

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

Я використовую git pull --rebaseдосить багато в своєму приватному репо, але навіть там він є потенційним недоліком, який полягає в тому, що історія мого HEADбільше не відображає дерево, як я насправді працював над ним.

Отже, для великого прикладу, припустімо, що я завжди запускаю тести і переконуюсь, що вони проходять, перш ніж виконувати комісію. Це має меншу актуальність після того, як я це роблю git pull --rebase, оскільки це вже неправда, що дерево в кожному з моїх зобов'язань пройшло тести. Поки зміни жодним чином не заважають, і код, який я витягую, був перевірений, то, імовірно, він пройшов би тести, але ми не знаємо, тому що я ніколи його не пробував. Якщо безперервна інтеграція є важливою частиною вашого робочого процесу, то будь-який вид перезавантаження в репо, що проводиться CIed, викликає занепокоєння.

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

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

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