git rebase upstream / master vs git pull --rebase upstream master

Есть ли разница между git rebase upstream/master и git pull --rebase upstream master, и если да, то какая? Пульт может быть любым, не обязательно восходящим.


person Dennis    schedule 24.03.2013    source источник


Ответы (1)


git pull --rebase сначала будет fetch (git fetch), обновив upstream/master коммиты.

Если вы просто переустановите без первого обновления upstream/master, вы не получите того же результата.

Я проиллюстрировал это на примере master ветки и «origin/master» разошлись, как «разделить» ветки?


SnakE упоминает в комментариях, что git pull --rebase не точно git fetch && git rebase origin/master.
См. что делает git pull --rebase?

(origin/master)
   |
A--B--C (master)
 \ 
  B'--D (actual origin/master after changing B and force pushing)

В этом случае git pull --rebase делает следующее:

git fetch origin
git rebase --onto origin/master B master

Здесь:

  • origin / master - это новый обновленный origin/master (B')
  • B - старый origin/master (до того, как он был обновлен при загрузке)
  • master - ветка для воспроизведения поверх origin/master

Это отличается от git fetch + git rebase origin/master тем, что команда pull --rebase пытается выяснить, какие коммиты являются действительно вашими локальными, а какие были получены из восходящего потока в более ранней выборке.

Для этого он просматривает журнал ссылок ветки удаленного отслеживания (в данном случае origin/master). Этот журнал ссылок представляет собой подсказки по последовательным git fetch операциям на origin в самом последнем первом порядке.

Для каждой записи reflog (origin/master@{1}, затем ...{2} и так далее) он проверяет, является ли эта фиксация предком текущей заголовка ветки master. Как только он находит его, он выбирает его в качестве отправной точки для перебазирования (B в приведенном выше примере).

person VonC    schedule 24.03.2013
comment
Итак, git pull --rebase upstream master аналог git fetch upstream && git rebase upstream/master? - person Dennis; 10.05.2013
comment
Вообще-то, нет. Представьте, что вы вытащили историю A-B и внесли в нее изменения, A-B-C. Затем кто-то другой изменил B на B' и внес свои изменения так, что теперь источником является A-B'-D. Теперь, если вы сделаете git fetch && git rebase origin/master, перебазирование завершится ошибкой с конфликтами. Однако git pull --rebase разберется и в итоге получит A-B'-D-C. Какая-то магия определенно творится под ковром в pull --rebase. Изменить: prooflink - person SnakE; 17.03.2015
comment
@SnakE хорошая мысль, что ты. Я включил алгоритм pull --rebase в ответ для большей наглядности. - person VonC; 17.03.2015
comment
Магия доступна прямо в git merge-base --fork-point - person jthill; 18.03.2015
comment
Я полагаю, что с тех пор @jthill получил 1.9.0+, поскольку я задокументировал там точку разветвления: stackoverflow.com/a/20423029/6309 < / а> - person VonC; 18.03.2015
comment
@VonC Какая польза от аргумента B в git rebase --onto origin/master B master? В руководстве Git указано, что это <upstream>, но что это будет означать, если указана опция --onto? - person stillanoob; 31.07.2018
comment
@ ibrahim5253 B - это первая фиксация (включенная), которую вы переустанавливаете поверх ветки, на которую ссылается --onto. - person VonC; 31.07.2018