git pull VS git fetch Vs git rebase

294

Другой вопрос сказал git pull, как git fetch+git merge .

Но в чем разница между git pullVS git fetch+ git rebase?

Майкл
источник
2
кто-то должен очистить ссылку ... и я поражен тем, сколько голосов получил другой вопрос.
ксенотеррацид
13
@xeno: Я думаю, это просто подсчет того, сколько людей говорят: «У меня тоже был этот вопрос»
bobobobo
45
Когда-нибудь я найду время, чтобы действительно прочитать документацию по git, но до тех пор я добавляю свои голоса к этим типам вопросов
Эран Медан

Ответы:

336

Из вашего вопроса должно быть совершенно очевидно, что вы на самом деле просто спрашиваете о разнице между git mergeи git rebase.

Итак, давайте предположим, что вы находитесь в общем случае - вы проделали некоторую работу над вашей основной веткой, и вы извлекли из исходного, который также проделал некоторую работу. После получения вещи выглядят так:

- o - o - o - H - A - B - C (master)
               \
                P - Q - R (origin/master)

Если вы объединитесь в этот момент (поведение git pull по умолчанию), предполагая, что нет никаких конфликтов, вы получите следующее:

- o - o - o - H - A - B - C - X (master)
               \             /
                P - Q - R --- (origin/master)

Если, с другой стороны, вы сделали соответствующую перебазировку, вы бы получили следующее:

- o - o - o - H - P - Q - R - A' - B' - C' (master)
                          |
                          (origin/master)

Содержимое вашего рабочего дерева должно быть одинаковым в обоих случаях; Вы только что создали другую историю, ведущую к этому . Перебазирование переписывает вашу историю, создавая впечатление, что вы зафиксировали поверх новой главной ветки origin ( R), а не там, где вы изначально фиксировали ( H). Вы никогда не должны использовать подход rebase, если кто-то уже извлек из вашей основной ветки.

Наконец, обратите внимание, что вы можете настроить git pullдля данной ветви использование rebase вместо слияния, установив для параметра config branch.<name>.rebaseзначение true. Вы также можете сделать это за одно нажатие git pull --rebase.

Cascabel
источник
39
Что произойдет, если вы сделаете ребаз после того, как кто-то уже вытащил из вашей главной ветки? Это сломает репо?
Дидье А.
12
Как вы знаете, если кто-то вытащил из вашей главной ветви?
Фрэнк
29
Если вы не знаете наверняка , что кто - то не имеет , то следует считать , что у них есть.
Крис Даун
4
Я просто подумал, что если вы не продвигаете изменения где-либо, кроме origin / master, я не вижу, чтобы кто-то сталкивался с проблемой, когда кто-то подталкивал эти изменения, потому что, если вы уже выдвинули эти изменения в origin / мастер, не было бы ничего, чтобы перебазировать в первую очередь. Мне кажется, что предупреждение действительно имеет значение только в тех случаях, когда у вас есть что-то более сложное, чем X -> origin / X, но я могу ошибаться. Если кто-то знает о сценарии, который я пропускаю, пожалуйста, поделитесь.
neverfox
1
@ SteveChambers Нет, это не результат. Линии просто представляют происхождение коммита, то есть A является родителем B. Нет никакого смысла в том, был ли Q или B первым во времени. Все эти операции основаны на графиках фиксации, а не на времени. Rebase просто трансплантирует некоторые коммиты, и результат, как я показал, не имеет значения, какие есть временные метки коммита.
Каскабель
9

TLDR:

git pullкак бегать git fetchто git merge
git pull --rebaseкак git fetchпотомgit rebase

В ответ на ваше первое заявление,

git pullэто как git fetch+ git merge.

«В режиме по умолчанию git pull - это сокращение, за git fetchкоторым следует git mergeFETCH_HEAD.« Точнее, git pullработает git fetchс заданными параметрами, а затем вызывает, git mergeчтобы объединить полученные заголовки веток с текущей веткой »

(Ссылка: https://git-scm.com/docs/git-pull )


Для вашего второго утверждения / вопроса:

«Но в чем разница между git pull VS git fetch+ git rebase»

Опять же из того же источника:
git pull --rebase

«С помощью --rebase он запускает git rebase вместо git merge».


Теперь, если вы хотели спросить

'разница между merge и rebase»

здесь тоже есть ответ:
https://git-scm.com/book/en/v2/Git-Branching-Rebasing
(разница между изменением способа записи истории версий)

harshvchawla
источник
2
Я хотел бы отметить, что «git pull --rebase» в большинстве случаев похож на «git fetch затем git rebase» - но не всегда. В некоторых ситуациях «git pull --rebase» делает немного больше. Смотрите этот часто упоминаемый пример здесь: gitolite.com/git-pull--rebase
Даниэль К.
1
Большое спасибо за ваш ответ. Я действительно понимаю, как git fetch + git rebaseкоманды теперь работают. На нашем
Travis Le