Создание веток в Git легко и быстро, но в конечном итоге они должны вернуться в мастер. Перебазирование — это и альтернатива, и компаньон для слияния.
Тяга против ветвления
Давайте начнем с простого наблюдения. Когда вы клонируете репо и работаете над собственной копией кода, вы ее разветвляете. Даже если на github нет форка с вашим именем: это естественно, и это было сделано с помощью Subversion или CVS.
Pull и push — это действительно замаскированные слияния : ваш мастер отличается от мастера по происхождению: на самом деле это две разные ветви. Вы можете попробовать выполнить git checkout origin / master, чтобы увидеть, как Git концептуально различает удаленные и локальные ветви с одинаковыми именами.
Таким образом, rebase может быть использован как для вытягивания / подталкивания, так и в целом для согласования двух ветвей, будь то одна удаленная и одна локальная или два локальных.
Как Git работает за минуту
Вы можете думать о GIT фиксаций , как фотографии , сделанные при выполнении команды; у них также есть один или несколько родительских коммитов , которые в линейном случае являются последним коммитом, сделанным с рабочей копией перед выполнением нового git commit .
Ветви — это просто метки , наложенные на определенные коммиты; метка изменяется при создании новых коммитов в соответствии с последним коммитом. Когда вы переходите, в большинстве случаев вы поддерживаете общего предка с исходной веткой:
Каждый коммит в ветви указывает своего родителя, образуя цепочку. При слиянии родителей для нового коммита исключительно два:
Так в чем же разница?
Во время слияния создается новый одиночный коммит с двумя родителями: ветвь, с которой вы объединяете, и текущая ветвь.
Во время перебазирования коммиты в вашей текущей ветке применяются последовательно к ветке, в которую вы перебазируете; родитель вашей ветви становится текущим заголовком цели. Это объясняет название: вместо того, чтобы основывать свою ветвь на том, когда вы ее разветвляете, вы основываете ее на ГОЛОВЕ мастера (если вы отошли от мастера).
В обоих случаях обновляется только метка для текущей ветви.
Метафора слияния заключается в том, что два дерева связаны друг с другом в одной точке: они могут расходиться с другими ветвями, но ваше развитие будет продолжаться, если оба они станут родителями.
Метафора перебазирования заключается в том, что вы обрезаете свою ветвь и снова прикрепляете ее на вершине дерева с помощью некоторого клея Acme . Трудно увидеть реальное дерево, пережившее эту обработку, но, поскольку после ребазинга вы обычно сливаете ветку обратно в master, в результате дерево всегда линейно:
Возможный рабочий процесс, который использует rebase, следующий:
git checkout -b mybranch # fork from master
...do some work and some commits...
...meanwhile master goes on with his life and several new commits are made...
git rebase master # your branch is cut out and applied to the more recent version of master
...resolve possible conflicts created by master... # run unit tests for example)
git checkout master && git merge mybranch # immedita, should be a fast-forward)
В происхождении против местной версии, вы заменяете GIT перебазироваться мастер с мерзавца тяговой —rebase .
Этот конечный результат техники перебазирования плюс слияния такой же, как если бы вы выполнили извлечение, все ваши N фиксируются всего за две секунды, а затем обновили мастер .
Однако оригинальные метаданные коммитов сохраняются. Это означает, что вы можете видеть их во временном порядке в журналах: те, что на master, будут в списке внизу, за ними будут следовать хронологически более старые коммиты, сделанные вами в вашей ветке.
При слиянии вы увидите только один автоматически сгенерированный коммит в git log; с rebase плюс merge вы увидите все различные коммиты, так как вторая операция, merge, становится быстрой перемоткой вперед (поднимая метку HEAD master без каких-либо дальнейших коммитов):
Конечным результатом является то, что история вашего мастера (или любой другой ветви, в которую вы переходите и объединяетесь) всегда линейна. Вы сможете использовать git-bisect, как умно предложено здесь , и продолжать использовать git log вместо визуализации сложного дерева кода.