Git pull призводить до сторонніх повідомлень "Об'єднання гілки" у журналі фіксування


110

Я працюю з іншим розробником над проектом, і ми використовуємо Github як наш віддалений репо. Я на Mac, що використовує git 1.7.7.3, він у Windows використовує git 1.7.6.

Це те, що відбувається

  1. Один з нас (назвемо його розробником A, але не важливо, який саме) передає набір GitHub набору зобов'язань.
  2. Інший (розробник B) робить деякі локальні зобов'язання.
  3. Б робить а git pull.
  4. Б робить а git push.
  5. Дивлячись на журнал історії комісій , я бачу "майстер" відділення "Об'єднання" github.com:foo/bar

Журнал комісій з часом засмічується повідомленнями "Об'єднати гілку", а також показує розробнику B як внесення змін, внесених розробником A. Єдиний спосіб, який ми виявили, щоб запобігти цій проблемі, - це зробити git pull --rebaseна кроці 3, але я не знаю, які побічні ефекти запровадять. Це мій перший раз, коли я працюю над git repo на багато розробників, тож це просто нормальна поведінка? Будь-які думки, як вирішити це питання?


2
Ви можете переглянути журнал без злиття зgit log --no-merges
wjandrea

Відповіді:


88

Виконання, яке ви бачите, - це прекрасно. pullЕфективно працює , git fetchа потім git mergeтак злиття зазвичай відбувається під час запуску git pull.

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

Комісії, які ви бачите, є для об'єднання двох (або більше) гілок. Це цілком чудово, щоб зробити комісію, яка не робить нічого іншого, як об’єднання декількох гілок. Насправді це дає зрозуміти, коли у вас є злиття, яке поєднує гілки при перегляді історії. На відміну від перезавантаження, об'єднання також дозволяє ефективно бачити оригінальну історію, яку вона розробляла, включаючи фактичні гілки, які співіснували.

Отже, довга історія: Так, об'єднання фільмів - це цілком чудово, і вам не слід про них хвилюватися.


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

2
@sTodorov Якщо нових змін не буде, то частина витягування нічого не зробить, але злиття все ще виконується. Отже, якщо ваша поточна локальна філія не є сучасною, вона змінить нові зміни у вашу філію. І якщо він не може здійснити швидке злиття вперед (якщо у вас розходяться коміти), то він створить об'єднання об'єднання.
ткнути

28
Ця відповідь дозволяє здатись, що використання бази даних, як описала ОП, небезпечно, але це не так. Повторне звільнення на кроці 3 не переписує всю історію. Лише місцеві комітети, які не були висунуті, переписуються шляхом повторного застосування поверх нової HEAD (остання фіксація, що надсилається до цієї гілки). Це запобігає стороннім злиттям і не має інших побічних ефектів.
bob esponja

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

1
@bobesponja Так, якщо ви публікуєте свою галузь функцій рано (тому що інші працюють над нею, або просто як резервна копія), вам не слід її перезавантажувати, тому що інші вже могли її отримати. Тоді звільнення - як ви самі кажете - суперечить рекомендаціям про звільнення, які я висловив у своїй відповіді. Однак якщо ви не публікуєте свої зобов’язання, то повторне звільнення добре, якщо ви хочете і не заперечуєте над лінійною історією. Але це залежить від того, як ви працюєте, тому загальною відповіддю є уникати цього, якщо це справді не безпечно. Btw. Я переглянув свою відповідь, тож якщо проблема буде вирішена, я буду вдячний, якщо ви вилучите свій потік.
ткнути

48

Ця відповідь була переглянута, оскільки моє розуміння, діаграми та висновки були невірними.


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

Наприклад, двоє людей працюють в одній галузі. Відділення починається як:

...->C1

Перша людина закінчує свою роботу і підштовхується до гілки:

...->C1->C2

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

...->C1->C3

Якщо витяг встановлений для злиття, сховище інших осіб виглядатиме так.

...->C1->C3->M1
      \      /
       ->C2->

Де M1 - це об'єднання об'єднань. Ця нова галузева історія буде висунута до репо. Якщо замість цього, витяг встановлений для відновлення локального репо, виглядатиме так:

...->C1->C2->C3

Немає зобов'язань щодо злиття. Історія стала більш лінійною.

Обидва варіанти відображають історію галузі. git дозволяє вибрати, яку історію ви віддаєте перевагу.

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

Ви можете встановити branch.autosetuprebase = завжди, щоб git автоматично встановлював віддалені гілки як rebase замість master.

git config --global branch.autosetuprebase always

Цей параметр змушує git автоматично створювати конфігураційні налаштування для кожної віддаленої гілки:

branch.<branchname>.rebase=true

Ви можете встановити це самостійно для віддалених гілок, які вже налаштовані.

git config branch.<branchname>.rebase true

Я хотів би подякувати @LaurensHolst за запитання та переслідування моїх попередніх заяв. Я, безумовно, дізнався більше про те, як git працює з функціями pull і merge.

Для отримання додаткової інформації про об'єднання з’єднань ви можете ознайомитись зі сприянням проекту в ProGit-Book . У розділі " Приватна мала команда " показано об'єднання об'єднань.


7
"Використання rebase замість злиття під час витягування забезпечує правильну історію спільного сховища. Використання об'єднання надає помилкову історію. " - Яке обґрунтування підтверджує це досить сміливе твердження? Немає можливості, щоб історія зі злиттями була «хибною історією». Це точне зображення порядку, в якому відбувалися речі. Те, що ви робите за допомогою звільнення, насправді змінює історію, щоб створити трохи більш лінійну її версію. Ви жертвуєте точністю для естетики. Можливо, щось ви віддаєте перевагу робити, але ні в якому разі не правдивіше.
Лорен Холст

2
Використання rebase замість злиття не приносить жертви точності естетиці. Ми використовуємо --no-ff для злиття, тому естетика не є вимогою. Точність - це бажання. База даних забезпечує таку точність.
Білл-двері

2
Наскільки точніша історія за версією? Ви цього не уточнюєте, і я не бачу, як би це було.
Лорен Холст

1
Історія - це відображення часу, за який відбувалися комітети у спільному репо. Одного дня 1, спільне репо побачило вчинення С2. На другий день спільне репо вважає, що виконується С3. Якби С3 прийшов раніше С2, то відображення часу було б не правильним. С3 не прийшов до С2. Все, що робить ребаза, - це переорганізувати коміти в локальному сховищі, щоб правильно відобразити історію, показану спільним сховищем.
Білл Двері

6
Ваші запитання змусили мене переглянути своє розуміння об'єднань. Моя діаграма неправильна. Я переглядаю дискусію. Мої висновки також невірні. Історія відновлення та об'єднання однаково правильна. Ви можете зробити власний вибір.
Білл Двері

11

Ви можете зробити:

git pull --rebase

Однак це завжди змінить ваші зміни над вашими колегами. Але ви не отримаєте жодних забруднюючих повідомлень про злиття.


9

На це насправді набагато простіша відповідь. Просто запропонуйте розробнику B перед тим, як взяти на себе зобов'язання. Це запобіжить цим об'єднанням об'єднань, оскільки вони спричинені історією, яку ви створили на локальному репо-сервері, з місцевого комітету, який намагається об'єднатись з історією комітетів на віддаленому репо. Якщо у вас з’являється повідомлення про те, що щось відбувається, замінюючи «зміни будуть перезаписані» під час витягування, це просто означає, що ви обидва торкнулися одного файлу, так що:

git stash
git pull
git stash pop

то ви можете вирішити будь-які конфлікти злиття, якщо такі є.


Більшість дратівливих і тривожних - це саме злиття конфліктів. Я скоріше цього уникаю
Зелений

1
@Green Якщо ви турбуєтесь про конфлікти злиття, то навіть git pull не відрізняється.
Зосо

За винятком того разу, коли ти забудеш stashперед собою pull. Тьху git вимагає, щоб я постійно був на вершині моєї гри.
linuxNoob

Необхідно git pull --rebaseінтегрувати віддалені зміни перед локальними, незалежно.
фонбранд

7

Здійснивши потягнення git, ви вставите повідомлення "Об'єднати гілку", саме це і робиться. Зробивши git pull, ви об’єднали віддалену гілку у свою місцеву гілку.

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

Наскільки я знаю, саме так працює git, і це не обійти шлях.

Повторне звільнення знищить історію git, тому ви не зможете побачити, коли відбулося злиття.

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