В чем разница между `git fetch` и` git rebase` и `git pull --rebase`? - PullRequest
41 голосов
/ 09 июня 2011

При чтении страницы git pull он выдает это строгое предупреждение о git pull --rebase:

Это потенциально опасный режим работы.Он переписывает историю, которая не сулит ничего хорошего, когда вы уже опубликовали эту историю.Не используйте эту опцию, если вы внимательно не прочитали git-rebase (1).

На странице git rebase она дает много описания, но не предупреждает такого рода.

Кроме того, я видел, как некоторые люди говорили, что

git fetch
git rebase

- это то же самое, что

git pull --rebase

, в то время как другие говорят, что они немного отличаются.

Что правда?

Ответы [ 3 ]

38 голосов
/ 18 июля 2012

Правда в том, что они являются разными.Вот действительно полезная веб-страница, которая прекрасно объясняет это:

http://gitolite.com/git-pull--rebase.html

Так что git pull --rebase обладает некоторой значительной магией над git fetch; git rebase, которую большую часть времени выне заметит, но в тех случаях, когда основной сопровождающий пренебрежительно игнорировал все эти строгие предупреждения и решил переписать историю публичной ветки, он может действительно помочь, проконсультировавшись с вашим локальным reflog и выполнив локальную перебазировку более разумным способом..

Тем не менее, это все еще ребаз, так что вы все еще переписываете историю!Поэтому все стандартные строгие предупреждения все еще применяются.Но если вы работаете над частной (то есть неопубликованной) веткой, тогда все в порядке.

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

  • , если это частная ветвь, перебазируй на то, что душе угодно
  • , если это публичная ветвь, не перебазируй, если ты не действительно должны, и если вы это сделаете, убедитесь, что вы понимаете воздействие, и убедитесь, что каждый, кто может быть затронут, должным образом проинформирован о том, что вы сделали, чтобы он не получил неприятный сюрприз и не потратил впустую грузвремя выяснить, что произошло.

Это так просто.И да, я бы пошел, чтобы активно поощрять людей регулярно git rebase -i в их частных филиалах.Полировка истории перед отправкой куда-нибудь в public / upstream - это хорошая вещь , потому что никто не хочет пробираться по истории проекта, которая полна коммитов типа «упс, исправляя ошибку, которую я сделал 3 коммита назад».(OTOH, не зацикливайтесь на поисках безупречной истории. Мы люди. Мы совершаем ошибки. Разбираемся с этим.)

Последнее замечание относительно магии git pull --rebase.Если вышестоящая публичная ветвь была разумным образом перебазирована (например, сдавить / исправить коммиты или сбросить коммиты, которые не должны были быть там помещены), тогда магия работает в вашу пользу.Однако, если перебазировка вверх по течению случайно drop совершает, тогда магия молча помешает вам вернуть их обратно.В этом случае, если вы хотите вернуть эти пропущенные коммиты, вы должны вместо этого использовать git fetch; git rebase.

30 голосов
/ 09 июня 2011

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

Теперь, к счастью, когда у вас есть типичное развертывание Git сЕдинственный репозиторий (источник), который является источником всего хорошего и истинного во вселенной, вы можете использовать git pull --rebase для вашего сердца, и это будет совершенно безопасно и, на мой взгляд, даст вам гораздо более вменяемый (смысллинейная) история.Я и моя команда используем его постоянно.

Однако, если вы начинаете использовать несколько пультов дистанционного управления и начинаете делать git pull --rebase <arguments>, чтобы вы больше не перебирались на одну и ту же цель каждый раз или начинаете подталкивать свою ветвь к альтернативным репозиториям до запуска git pull --rebase с вашим основным апстримом - тогда вы можете столкнуться с проблемами.

В любое время, когда вы делитесь своими изменениями с другим удаленным / репозиторием, а затем изменяете эти изменения (для значенийизменение равным изменению SHA, родителя и т. д., даже если сообщение / содержимое фиксации не изменилось), вы можете испортить человека, у которого были старые изменения.

Пока вы не упадетевне конверта здравого смысла, git pull --rebase будет очень хорошо для вас.

Это, например, не отвечает на вопрос о разнице между git pull --rebase и git fetch && git rebase @{u}.Я просто продолжу и скажу, что я не знаю ни о какой разнице, и если она есть, она достаточно тонкая, чтобы я не замечал ее в те годы, когда использовал Git.Возможно в том, что система определяет правильный репозиторий, который должна получить ваша ветка, если у вас есть несколько репозиториев, а «origin» не является последним потоком этой ветки?

И даже если вы действительно сильно ошибаетесь с git-rebaseКонечно, вы можете легко вернуться в исходную среду предварительной ребазировки с помощью git log -g и / или git reset --hard ORIG_HEAD.Только не делайте принудительных нажатий (по умолчанию запрещено почти на всех серверах Git), и вы будете счастливы счастливы.

EDITED

Со временем мое понимание расширилось.git pull --rebase призывает git rebase выполнить ребазинг, поэтому в этом смысле между ними нет никакой разницы.Однако git-pull на самом деле вызывает git rebase --onto @{u} $(git merge-base HEAD @{u}@{1})

OK, этот синтаксис ("@ {u} @ {1}"), возможно, немного непрозрачен и упрощает загрузку, но дело в том, что онвыясняет, какая база слияния находилась в восходящем направлении ДО она запустила команду fetch.Вы спрашиваете, какая разница?

Ну, в обычном случае нет.Однако, если вы меняете, куда указывает восходящий поток или если сам восходящий поток был перебазирован, довольно много.Если upstream был переписан, а затем вы сделали git rebase @{u}, вы могли бы быть очень несчастны и могли получить двойные коммиты или конфликты в зависимости от того, сколько было переписано более старых коммитов.

Однако, с магией git pull --rebaseтолько коммиты, которые принадлежат вам и только вам, будут применяться поверх @ {u}.

ОК, это тоже является упрощением.Если восходящий поток сделал ребаз, начинающийся с 100 коммитов назад (но на самом деле 101+ коммитов в истории) и вы сделали git fetch до , выполнив git pull --rebase, тогда Git будетне сможет точно определить, какова была надлежащая историческая база слияния, чтобы выяснить, каковы ваши локальные коммиты.

В результате git fetch считается вредным (если у вас есть локальные коммиты, а апстрим - этопереписано).Однако настоящее практическое правило - «никогда не пытайтесь изменить историю после того, как она была опубликована, опубликована или отправлена», и именно с этого я и начал.

TL; DR:

git fetch считается вредным (поэтому используйте git pull --rebase);и никогда не пытайтесь изменить историю после того, как она будет опубликована, опубликована или отправлена ​​(потому что, помимо прочего, это может нанести вред git fetch).

0 голосов
/ 03 августа 2016

В дополнение к обновлению вашей локальной ветки из удаленной ветки отслеживания, -pull обновляет файлы вашей рабочей области.

Так что, скорее всего, git pull --rebase (или настройка pull для использования rebase по умолчанию) более типично, чем git fetch; git rebase.

...