Git pull - это комбинация из 2 команд
- git fetch (синхронизирует локальное репо с новейшими материалами на пульте)
- git merge (объединяет изменения из удаленной ветви, если они есть, с вашей локальной ветвью отслеживания)
git rebase является лишь грубым эквивалентом git merge. Он ничего не извлекает удаленно. Фактически, он также не выполняет надлежащего слияния, он воспроизводит коммиты ветви, на которой вы находитесь, после новых коммитов из второй ветви.
Его цель - дать вам более чистую историю. Многим людям не нужно много слияний, прежде чем история в gitk станет ужасно похожей на спагетти.
Лучшее графическое объяснение можно увидеть в первых 2 графиках здесь . Но позвольте мне объяснить здесь на примере.
У меня есть 2 филиала: мастер и филиал. Стоя на ветке я могу бегать
git rebase master
и я получу что-нибудь новое в master до того, как мои последние коммиты будут в mybranch. Это прекрасно, потому что, если я теперь сливаю или перебазирую материал из mybranch в master, мои новые коммиты добавляются линейно сразу после самых последних коммитов.
Проблема, на которую вы ссылаетесь, возникает, если я перебазирую в «неправильном» направлении. Если я только что получил самый последний мастер (с новыми изменениями) и от мастера я перебазировался следующим образом (перед синхронизацией своей ветви):
git rebase mybranch
Теперь я только что вставил свои новые изменения где-то в прошлом мастера. Основная линия коммитов изменилась. А благодаря тому, как git работает с идентификаторами коммитов, все коммиты (от мастера), которые были только что воспроизведены поверх моих новых изменений, имеют новые идентификаторы.
Ну, это немного сложно объяснить только словами ... Надеюсь, это имеет смысл: -)
В любом случае, мой собственный рабочий процесс такой:
- 'git pull' новые изменения с пульта
- переключиться на mybranch
- 'git rebase master', чтобы внести новые изменения мастера в мою историю коммитов
- переключиться обратно на мастер
- 'git merge mybranch', который ускоряется только тогда, когда все в master также находится в mybranch (таким образом, избегая проблемы переупорядочения коммитов в публичной ветви)
- 'git push'
Последнее слово. Я настоятельно рекомендую использовать rebase, когда различия тривиальны (например, люди, работающие с разными файлами или по крайней мере с разными строками). У него есть то, что я пытался объяснить, но это делает историю намного чище.
Как только могут возникнуть значительные конфликты (например, коллега переименовал что-то в кучу файлов), я настоятельно рекомендую объединить. В этом случае вам будет предложено разрешить конфликт, а затем зафиксировать разрешение. С положительной стороны, слияние гораздо проще разрешить при наличии конфликтов. Недостатком является то, что вашей истории может стать трудно следить, если много людей все время сливается: -)
Удачи!