Разница между git pull и git pull --rebase


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 pull - это, собственно говоря, что-то вроде этого (мы будем использовать пульт с именем origin и ветку 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)

Между тем, в порыве антисоциальной ярости, сопровождающий вверх по течению не только отказался от своего «фу», он даже использовал сквош или два. Его цепочка коммитов теперь выглядит так:

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

Тяга в этой точке может привести к хаосу. Даже мерзкий выбор; 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)так как rebase изменяет хэши.
Бастьен

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?
Джон

1
Разве это не то, что git rebaseделает? Но мы говорим о git pull --rebase. И это разные вещи.
Зеленый

10

В самом простом случае без столкновений

  • with rebase: перебазирует ваши локальные коммиты поверх удаленного HEAD и не создает коммит слияния / слияния
  • без / normal: объединяет и создает коммит слияния

Смотрите также:

man git-pull

Точнее, git pull запускает git fetch с заданными параметрами и вызывает git merge для слияния найденных головок веток с текущей веткой. С --rebase он запускает git rebase вместо git merge.

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


3
А в случае столкновения?
Rndm

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

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

7

Для этого важно понять разницу между Merge и Rebase.

Обоснование - это то, как изменения должны проходить от вершины иерархии вниз, а слияния - то, как они возвращаются вверх.

За подробностями обращайтесь - http://www.derekgourlay.com/archives/428


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