Подтвердить что ты не робот

Какая разница между `git fetch` then `git rebase` и` git pull --rebase`?

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

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

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

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

git fetch
git rebase

совпадает с

git pull --rebase

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

Какая правда?

4b9b3361

Ответ 1

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

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

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

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

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

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

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

РЕДАКТИРОВАНИЕ

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

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

Ну, в обычном случае нет. Однако, если вы меняете, куда указывает восходящий поток или если сам восходящий поток был перебазирован, довольно много. Если апстрим был переписан, а затем вы сделали 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).

Ответ 2

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

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

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

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

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

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

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

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

Ответ 3

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

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