Різниця між git pull і git pull --подання


311

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

Будь ласка, допоможіть мені зрозуміти різницю.



3
Можливий дублікат git pull VS git fetch git rebase
TJ

Відповіді:


326

git pull= git fetch+ git mergeпроти відстеження гілки за течією

git pull --rebase= git fetch+ git rebaseпроти відстеження гілки за течією

Якщо ви хочете знати, як git mergeі чим git rebaseвідрізнятися, прочитайте це .


12
Варто зазначити, що висловлювання git pull --rebase- це те саме, що є, git fetchі git rebaseв основному є таким, як воно є, але це не зовсім семантично рівнозначно. Є деякі відмінності, деякі з яких пояснені тут. gitolite.com/git-pull--rebase
w0rp

8
Це я б назвав "зручною брехнею", щоб запозичити фразу у Скотта Майєрса. Це хороший спосіб пояснити це незалежно.
w0rp

Дуже коротко. Я не можу зрозуміти різницю. Що так важливого fetch?
Зелений

240

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

Магія є git pull --rebase

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

# assume current checked out branch is "foo"
git fetch origin
git merge origin/foo

На перший погляд ви можете подумати, що git pull --rebase робить саме це:

git fetch origin
git rebase origin/foo

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

Що означає git pull --rebase має зробити трохи більше, ніж це. Ось пояснення, що це робить і як.

Скажімо, ваш вихідний пункт такий:

a---b---c---d---e  (origin/foo) (also your local "foo")

Час минає, і ви зробили деякі зобов’язання на додаток до свого "foo":

a---b---c---d---e---p---q---r (foo)

Тим часом, в розпалі антисоціальної люті, обслуговуючий вгору за течією не тільки переосмислив своє "foo", він навіть використав сквош-два. Зараз його ланцюг фіксацій виглядає приблизно так:

a---b+c---d+e---f  (origin/foo)

Потяг кишки в цей момент призведе до хаосу. Навіть git fetch; git rebase origin / foo не вирізало б це, тому що виконує "b" і "c" з одного боку, а виконувати "b + c" з іншого, буде конфліктувати. (І аналогічно з d, e і d + e).

Що git pull --rebaseв цьому випадку означає:

git fetch origin
git rebase --onto origin/foo e foo

Це дає вам:

 a---b+c---d+e---f---p'---q'---r' (foo)

Ви все ще можете отримати конфлікти, але вони будуть справжніми конфліктами (між p / q / r та a / b + c / d + e / f), а не конфліктами, спричиненими b / c, що конфліктують з b + c тощо.

Відповідь, отримана з (і трохи змінена):
http://gitolite.com/git-pull--rebase


9
Це найкраща відповідь. Можливо, ви захочете змінити кінцевий результат, a---b+c---d+e---f---p'---q'---r' (foo)оскільки хеш змін змінюється.
Бастієн

22
Ця відповідь була скопійована і вставлена дословно з gitolite.com/git-pull--rebase і повинна містити атрибуцію відповідно до ліцензії на цій сторінці.
Wildcard

Це чудове пояснення. Але у мене виникла ситуація, коли я взяв на себе зобов’язання A, і я направив піар на репо вгору за течією, який був прийнятий. Тоді, коли я виступив git pull --rebaseпроти репо за течією, я не отримав нової A'комісії поверх витягнутого репо. Насправді їх взагалі A'не було. Це тому, що Aбуло об'єднано в систему? Або це тому, що між верхнім потоком та моєю перезавантаженою версією не було різниці?
CMCDragonkai

Я зараз переглядаю підручник з Git і використовував цю відповідь для подальшого розуміння git pull --rebase. Але одне, що мене бентежить у цій гіпотетичній ситуації, - це те, що сервіс, що обслуговує верхній потік, змінив історію проектів, яка вже потрапила в сховища місцевих розробників. Це взагалі не погана практика? Якби він хотів розпочати / переписати історію, це потрібно було зробити перед тим, як інтегрувати її в центральне сховище, щоб уникнути подібних конфліктів.
bmcentee148

44

Припустимо, у вас є два комітети у місцевій філії:

      D---E master
     /
A---B---C---F origin/master

Після "git pull", буде:

      D--------E  
     /          \
A---B---C---F----G   master, origin/master

Після "git pull --rebase" не буде точки злиття G. Зауважте, що D і E стають різними комітами:

A---B---C---F---D'---E'   master, origin/master

1
чи не A --- B --- C --- D '--- E' - F?
prgmrDev

5
@prgmrDev Чому D і E будуть вставлені перед F?
Jon

1
Чи не саме це git rebaseробить? Але ми говоримо про git pull --rebase. І це різні речі.
Зелений

10

У самому простому випадку жодних зіткнень

  • з базою даних: відновлює ваші локальні зобов'язання на віддаленій HEAD і не створює об'єднання / злиття
  • без / нормального: зливається і створює комісію злиття

Дивись також:

man git-pull

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

Дивіться також:
Коли я повинен використовувати git pull --rebase?
http://git-scm.com/book/en/Git-Branching-Rebasing


3
А в разі зіткнень?
Rndm

1
Вам буде запропоновано вирішити їх вручну, а потім - продовжити з rebase: git sdd modified-file; git rebase --continueабо merge: git add modified-file; git commit;де modified-fileваш локальний файл, який ви змінили вручну / mergetool
drahnr

Що такого особливого fetch? Чому вони створили два rebaseпотоки? 1) git rebaseі 2) git pull --rebase?
Зелений

7

Для цього важливо зрозуміти різницю між об'єднанням та Rebase.

Знижки - це те, як зміни повинні проходити від верхівки ієрархії вниз, а злиття - як вони протікають назад вгору.

Докладніше див. - http://www.derekgourlay.com/archives/428


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