Як у git, чим вибір відрізняється від "pull" і як "merge" відрізняється від rebase?


160

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

  • git fetch vs pull
  • git merge vs rebase

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

3
Чому б не обрати відповідь на пестицилу як прийняту?
Arashsoft

@Arashsoft тому, що його не бачать з 2013 року
VdeX

Відповіді:


415

витягнути проти тягнути

fetch буде завантажувати будь-які зміни з віддаленої гілки *, оновлюючи ваші дані сховища, але залишаючи вашу локальну * гілку незмінною.

pullвиконає зміни fetchта додатково mergeзміни у вашому місцевому відділенні.

Яка різниця? pullоновлює локальну філію зі змінами на витягнутому відділенні. A fetchне просуває вашу місцеву філію.

злиття vs rebase

Враховуючи таку історію:

          C --- D --- E місцевий
         /
    A --- B --- F --- G пульт

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

Ефект від mergeзаповіту буде:

          C --- D --- E місцевий
         / \
    A --- B --- F --- G --- H пульт

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

Ефект від rebaseзаповіту буде:

                  C '- D' - E 'місцевий
                 /
    A --- B --- F --- G пульт

Яка різниця? А mergeне змінює походження комітетів. А rebase переписується походження ваших місцевих комітетів.

*Це пояснення припускає , що поточна гілка є місцевим відділенням, і що гілка , зазначеної в якості аргументу fetch, pull, merge, або rebaseце віддалений філія. Це звичайний випадок. pull, наприклад, завантажить будь-які зміни із зазначеної гілки, оновить ваше сховище та mergeзміни в поточну гілку.


31
Це, безумовно, найпростіше і найкраще пояснення, не вникаючи в дебати за кожною практикою. Дякую!
Джонатан С. Фішер

3
Абсолютно золота відповідь
ChaseMoskal

5
Хотілося б, щоб я міг "улюбити" цю відповідь. Можливо, я просто роздрукую його і приклеюю на стіну.
LarsH

2
Я б сказав найкращі найкращі відповіді, які я отримав у stackoverflow, дякую
Shahab J

1
Якщо вибираєте лише завантаження змін із віддаленої гілки та оновлює дані сховища, але залишає локальну гілку незмінною, то який сенс отримувати, якщо робочий каталог не відображає / не відображає зміни? Спочатку моє запитання полягало в тому, як я можу побачити зміни, які зробив хтось інший, а потім вирішити, чи хотів би я об'єднати їх у свій робочий каталог (тобто експериментувати зі змінами інших людей, щоб переконатися, що це не порушує мою роботу), але я все одно плутати, як це зробити? Чи варто просто пульсувати та експериментувати / досліджувати, і якщо це було проблематично, зробити жорсткий перезавантаження?

28

Витягнути проти тягнути

Git fetch просто оновлює ваші дані репо, але витягнення git в основному виконує отримання, а потім об'єднає витягнуту гілку

Яка різниця між "git pull" та "git fetch"?


Злиття проти Rebase

з блогу Atlassian SourceTree Blog, Merge або Rebase :

Об'єднання об'єднує дві лінії розвитку разом із збереженням походження кожної історії комісій.

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

Крім того, ознайомтеся з Learn Git Branching - це приємна гра, яка щойно була розміщена на HackerNews ( посилання на пост ) та вчить багато хитрощів із розгалуження та злиття. Я вірю, що це буде дуже корисно в цій справі.


дякую Феліпс .. тож якщо я заробляю з віддаленого мого відділення, майстер не матиме оновлень? також здається, що я повинен робити перезавантаження більше, ніж merga
techsjs2013

rebase vs merge залежить від того, який ви маєте намір, маючи на увазі, що перезапис перезаписує всі історії, що здійснюються. І так, якщо ви отримаєте лише, головна гілка не буде змінена, вам доведеться об'єднати (або потягнути), щоб застосувати віддалені зміни
Феліпе Сабіно

git merge <remote>/<branch>. наприклад, якщо ви є головним відділенням, а ваш пульт називається походженням, ви можете це зробити git merge origin/master.
Феліпе Сабіно

тому звучить так, що я завжди повинен робити git checkout master git fetch git diff origin / master git rebase origin master
techsjs2013

8

тягнути проти отримання :

Те, як я це розумію, - git pullце просто git fetchслідування git merge. Тобто ви отримуєте зміни з віддаленої гілки, а потім об'єднуєте їх у поточну гілку.


злиття та відновлення :

Злиття зробить так, як каже команда; об'єднати відмінності між поточною гілкою та вказаною гілкою (у поточну гілку). Тобто команда git merge another_branchзлиється another_branchв поточну гілку.

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

Однак не обійшлося без підводних каменів! Оскільки історія версій "переписана", ви повинні робити це лише в тому випадку, якщо комісії існують лише у вашому локальному git repo. Тобто: Ніколи цього не робіть, якщо ви перенесли комісії на віддалений репо.

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


тягнути з відсіканням замість злиття

Я фактично використовую rebase досить багато, але зазвичай це в поєднанні з pull:

git pull --rebase

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


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

Я все ще не знаходжуся в стані merge vs
rebase

Я думаю, що ілюстрації, представлені у відповіді від пестушки, досить різко показують різницю. Також перевірте: git-scm.com/book/en/Git-Branching-Rebasing - що робить досить пристойну роботу з його поясненням (те саме посилання, що і у відповіді, але подане ще раз для ледачих).
Стейнар

0

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

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

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

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