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

Я начал использовать git когда-нибудь назад и не полностью понимаю тонкости. Мой основной вопрос здесь заключается в том, чтобы узнать разницу между git pull и git pull --rebase, поскольку добавление опции --rebase не похоже на что-то совсем другое: просто делает pull.

Пожалуйста, помогите мне с пониманием разницы.

Ответ 1

git pull= git fetch + git merge против отслеживания ветки вверх.

git pull --rebase= git fetch + git rebase против отслеживания ветвей upstream

Если вы хотите узнать, как отличаются git merge и git rebase, прочитать это.

Ответ 2

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

Магия git pull --rebase

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

A git pull в этой точке приведет к хаосу. Даже 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

Ответ 3

Предположим, что у вас есть две коммиты в локальной ветке:

      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

Ответ 4

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

  • с rebase: восстанавливает локальные транзакции на удаленной HEAD и не создает фиксацию слияния/слияния
  • без /normal: слияние и создание объединения слиянием

См. также:

man git-pull

Точнее, git тянет запускает git fetch с заданными параметрами и        вызывает git merge, чтобы объединить полученные ветки ветки в текущий        филиал. С помощью --rebase выполняется git rebase вместо git merge.

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

Ответ 5

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

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

Подробнее см. http://www.derekgourlay.com/archives/428