git rebase continue что делать

Git Rebase: руководство по использованию

Rebase — один из двух способов объединить изменения, сделанные в одной ветке, с другой веткой. Начинающие и даже опытные пользователи git иногда испытывают нежелание пользоваться ей, так как не видят смысла осваивать еще один способ объединять изменения, когда уже и так прекрасно владеют операцией merge. В этой статье я бы хотел подробно разобрать теорию и практику использования rebase.

Теория

Итак, освежим теоретические знания о том, что же такое rebase. Для начала вкратце — у вас есть две ветки — master и feature, обе локальные, feature была создана от master в состоянии A и содержит в себе коммиты C, D и E. В ветку master после отделения от нее ветки feature был сделан 1 коммит B.

После применения операции rebase master в ветке feature, дерево коммитов будет иметь вид:

Обратите внимание, что коммиты C’, D’ и E’ — не равны C, D и E, они имеют другие хеши, но изменения (дельты), которые они в себе несут, в идеале точно такие же. Отличие в коммитах обусловлено тем, что они имеют другую базу (в первом случае — A, во втором — B), отличия в дельтах, если они есть, обусловлены разрешением конфликтных ситуаций, возникших при rebase. Об этом чуть подробнее далее.

Такое состояние имеет одно важное преимущество перед первым, при слиянии ветки feature в master ветка может быть объединена по fast-forward, что исключает возникновение конфликтов при выполнении этой операции, кроме того, код в ветке feature более актуален, так как учитывает изменения сделанные в ветке master в коммите B.

Процесс rebase-а детально

Давайте теперь разберемся с механикой этого процесса, как именно дерево 1 превратилось в дерево 2?

Напомню, перед rebase вы находтесь в ветке feature, то есть ваш HEAD смотрит на указатель feature, который в свою очередь смотрит на коммит E. Идентификатор ветки master вы передаете в команду как аргумент:

Для начала git находит базовый коммит — общий родитель этих двух состояний. В данном случае это коммит A. Далее двигаясь в направлении вашего текущего HEAD git вычисляет разницу для каждой пары коммитов, на первом шаге между A и С, назовем ее ΔAC. Эта дельта применяется к текущему состоянию ветки master. Если при этом не возникает конфликтное состояние, создается коммит C’, таким образом C’ = B + ΔAC. Ветки master и feature при этом не смещаются, однако, HEAD перемещается на новый коммит (C’), приводя ваш репозитарий состояние «отделеной головы» (detached HEAD).

Успешно создав коммит C’, git переходит к переносу следующих изменений — ΔCD. Предположим, что при наложении этих изменний на коммит C’ возник конфликт. Процесс rebase останавливается (именно в этот момент, набрав git status вы можете обнаружить, что находитесь в состоянии detached HEAD). Изменения, внесенные ΔCD находятся в вашей рабочей копии и (кроме конфликтных) подготовлены к коммиту (пунктиром обозначена stage-зона):

Далее вы можете предпринять следующие шаги:

1. Отменить процесс rebase набрав в консоли

При этом маркер HEAD, будет перенесен обратно на ветку feature, а уже добавленные коммиты повиснут в воздухе (на них не будет указывать ни один указатель) и будут вскоре удалены.

При этом, если все конфликты действительно разрешены, будет создан коммит D’ и rebase перейдет к следующему, в данном примере последнему шагу.

После применения изменений ΔDE будет создан последний коммит E’, указатель ветки feature будет установлен на коммит E’, а HEAD станет показывать на ветку feature — теперь, вы находитесь в состоянии на втором рисунке, rebase окончен. Старые коммиты C, D и E вам больше не нужны.

При этом коммиты, созданные в процессе rebase-а, будут содержать данные как об оригинальном авторе и дате изменений (Author), так и о пользователе, сделавшем rebase (Commiter):

С небес на землю — rebase в реальных условиях

На самом деле обычно вы работаете не с двумя ветками, а с четырьмя в самом простом случае: master, origin/master, feature и origin/feature. При этом rebase возможен как между веткой и ее origin-ом, например feature и origin/feature, так и между локальными ветками feature и master.

Rebase ветки с origin-ом

Если вы хотите начать работать с rebase, то лучше всего начать с ребейза своих изменений в ветке относительно ее копии в удаленном репозитарии. Дело в том, что когда вы добавляете коммит, и в удаленном репозитарии добавляется коммит, для объединения изменений по-умолчанию используется merge. Выглядит это примерно так:

Три коммита превратились в 6 (базовый коммит не считаем), история изменений неоправдано запутана, информация об объединении локальных веток с удаленными, на мой взгляд, лишняя. Если масштабировать эту ситуацию на несколько тематических веток и большее количество разработчиков, граф может выглядеть, например, так:

Как поделиться веткой, к которой применен rebase, с коллегой

Тут все просто, наберите в консоли команду:

Читайте также:  mirrorlink skoda что это такое

Force-режим просто копирует отсутствующие родительские коммиты ветки feature на origin и насильно устанавливает указатель ветки на тот же коммит, что и ваш локальный.

Будьте внимательны! Если вы забудете указать идентификатор ветки, то force-push будет выполнен для всех локальных веток, имеющих удаленный оригинал. При этом нужно понимать, что некоторые локальные ветки могут быть в неактуальном состоянии. То есть измененения, которые вы не успели затянуть будут удалены в origin-е. Конечно, сами коммиты не будут удалены — сбросятся только указатели ветки. Эта ситуация поправима — достаточно для каждой ветки найти человека, который последним пушил изменения в нее или уже успел их забрать. Он может сделать обычный push, вновь передав их на origin. Но вся эта морока вам ни к чему, так что лучше просто будьте внимательны.

Реинтеграция тематической ветки в master

Мы рассмотрели все необходимые операции для работы с ветками в стиле rebase. Осталось только переключиться в ветку master и сделать git merge feature. Ветка, подготовленная rebase-ом вольется в master по fast-forward, то есть указатель будет просто перемещен вперед.

В данном случае, на мой взгляд, merge-коммиты полезны и несут в себе информацию о моменте объединения веток. Этот граф выглядит как учебный пример, но такая структура вполне реальна при соблюдении некоторых простых правил всеми членами команды.

Заключение

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

В данной статье сделано одно допущение. Все это верно при простой модели ветвления — есть одна главная ветка master и несколько тематических, которые создаются от нее. Когда от тематической ветки создается другая тематическая ветка, есть свои нюансы при rebase-е первичной и вторичной ветки. О них можно прочитать в том самом официальном руководстве.

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

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

Источник

git rebase

Перебазирование — это один из двух инструментов Git для внедрения изменений из одной ветки в другую. Такие же возможности предоставляет команда git merge (слияние). Операция слияния фиксирует изменения, всегда двигаясь вперед по истории проекта, в то время как перебазирование позволяет эффективно ее переписывать. Подробные сведения об операциях слияния и перебазирования см. в руководстве Сравнение слияния и перебазирования. Перебазирование может выполняться в двух режимах: ручном и интерактивном. Эти режимы будут подробно рассмотрены далее.

Что такое git rebase?

Перебазирование — это процесс перемещения последовательности коммитов к новому базовому коммиту или их объединение. Операцию перебазирования удобнее всего применить и отобразить в контексте создания функциональных веток. В общих чертах процесс можно представить следующим образом:

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

Использование

Перебазирование выполняется прежде всего для обеспечения линейной истории проекта. Представим ситуацию: вы работаете над функциональной веткой feature, при этом код в главной ветке main уже изменился с начала вашей работы. Вам нужно отразить последние изменения ветки main в ветке feature, не засоряя при этом историю вашей ветки, чтобы создать впечатление, что ваша работа велась на основе последней версии ветки main. Впоследствии это позволит выполнить беспроблемное слияние ветки feature с веткой main. Почему не следует засорять историю? Ее аккуратность сыграет решающую роль при поиске в Git коммита, в котором появилась проблема. Можно привести более реалистичный пример.

Узнайте больше о командах git log и git bisect на соответствующих страницах.

Внедрить функцию в главную ветку main можно двумя способами: прямым слиянием или перебазированием с последующим слиянием. Первая операция выполняет трехстороннее слияние и создает коммит слияния, а вторая обеспечивает ускоренное слияние и абсолютно линейную историю. На приведенной ниже схеме показано, как перебазирование на ветку main обеспечивает ускоренное слияние.

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

Читайте также:  к чему снится что растолстела

Не выполняйте перебазирование публичной истории

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

Сравнение стандартного и интерактивного режимов команды git rebase

В стандартном режиме команда git rebase автоматически берет коммиты из текущей рабочей ветки и применяет их в конце переданной ветки.

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

Дополнительные команды перебазирования

Как описано на странице Переписывание истории, с помощью перебазирования можно изменять предыдущие коммиты, группы коммитов, зафиксированные с помощью коммитов файлы и группы сообщений. Существуют и более сложные примеры использования, которые требуют добавления к команде git rebase различных опций.

Обзор

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

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

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

Варианты конфигурации

Останавливает перебазирование и выводит предупреждения о том, что коммиты были удалены.

Расширенные возможности перебазирования

Ветка featureB основана на featureA. При этом мы понимаем, что ветка featureB не зависит ни от одного изменения в ветке featureA, поэтому она могла бы отходить от главной ветки main.

Опасности перебазирования

Сама по себе команда git rebase не сопряжена с серьезной опасностью. Риск возникает, если вы используете интерактивное перебазирование для перезаписи истории и затем принудительно отправляете результаты в удаленную ветку, где работают другие пользователи. Этого делать не стоит, поскольку работа удаленных пользователей может быть перезаписана при осуществлении pull.

Восстановление при перебазировании восходящей ветки

Резюме

Готовы изучить Git?

Ознакомьтесь с этим интерактивным обучающим руководством.

Источник

Переписывание истории с помощью Git Rebase

Russian (Pусский) translation by Sergey Zhuk (you can also view the original English article)

Основной рабочий процесс Git выглядит следующим образом: вы делаете задачу в отдельной ветке, затем по завершению сливаете ее в основную ветку. Это делает git merge неотъемлемым инструментом для объединения веток. Однако это не единственный инструмент, который предлагает Git.

Слияние веток объединением.

Слияние веток с помощью git rebase

Необходимые условия

Эта статья предполагает, что вы знакомы с основами Git. Вы должны уметь сохранять и фиксировать изменения, разработку задач в отдельных ветках, соединять ветки, а так же сливать и заливать ветки из удаленных репозиториев.

1. Сдвиг для получения линейной истории

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

Например, рассмотрим, что произойдет, если вы будете использовать слияние вместо сдвига.

Слияние коммитов, находящихся выше.

Это же можно увидеть при слиянии и в другом направлении. Без использования сдвига, слияние ветки feature в ветку master так же требует коммита слияния. Хотя это и кажется значимым коммитом (он представляет отдельную законченную задачу), в итоге история будет полна ответвлений:

Слияние законченной задачи с помощью merge

Сдвиг перед слиянием

Разрешение конфликтов

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

Визуально вот как выглядит история проекта, когда git rebase обнаруживает конфликт:

Для разрешения конфликта следует открыть файл с конфликтами (в нашем примере это readme.txt), найти затрагиваемые строки, и вручную внести необходимые изменения. Затем сообщить Git, чтобы конфликт разрешен, зафиксировав изменения в файле:

Читайте также:  Мазок на энтеробиоз у детей что показывает

Оставшиеся коммиты по одному будут перемещены, если снова возникнут конфликты, то следует повторить процесс их разрешения.

2. Сдвиг для очищения от локальных коммитов

Этот список показывает, как ветка feature будет выглядеть после перемещения. Каждая строчка представленная отдельный коммитом и командой pick перед каждым хэшем коммита, определяет что будет происходить с коммитом во время сдвига. Обратите внимание, что коммиты перечислены от самого старого к новому. Изменяя этот список, вы получаете полный контроль над историей проекта.

Сжимаем второй коммит с помощью интерактивного сдвига.

3. Опасности сдвига

Когда вы один работаете над проектом, переписывание истории не является очень существенным. Однако, как только вы начинаете работать в среде совместной работы, он может стать очень опасным. Если вы перепишите коммиты, которые используются другими разработчиками (например в ветке master ), то в следующий раз, когда они будут сливать себе ваши изменения, их собственные коммиты исчезнут. Что приведет к неприятных результатам, после которых тяжело будет все восстановить.

Имя это в виду, вам никогда не следует делать сдвиг коммитов, которые были залиты в публичный репозиторий, до тех пор пока вы не будете уверены, что никто их сейчас в своей работе не использует.

Заключение

Источник

Переписывание истории с помощью Git Rebase

В фундаментальном рабочем процессе Git вы разрабатываете новую функцию в отдельной ветке тем, а затем объединяете ее с производственной веткой после ее завершения. Это делает git merge неотъемлемым инструментом для объединения веток. Тем не менее, это не единственный, который предлагает Git.

Объединяя ветви, объединяя их

Объединение веток с git rebase

Предпосылки

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

1. Перебазирование для линейной истории

Первый вариант использования, который мы рассмотрим, связан с расходящейся историей проекта. Рассмотрим репозиторий, в котором ваша производственная ветвь продвинулась вперед, пока вы разрабатывали функцию:

Чтобы переместить ветвь feature в master ветвь, вы должны выполнить следующие команды:

Это трансплантирует ветвь feature от ее текущего местоположения до вершины master ветки:

Например, рассмотрим, что произойдет, если вы объедините восходящие коммиты слиянием вместо ребазирования:

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

Интеграция восходящих коммитов слиянием

Это же преимущество можно увидеть при слиянии в другом направлении. Без перебазирования интеграция готовой ветви feature в master требует фиксации слияния. Хотя на самом деле это значимый коммит слияния (в том смысле, что он представляет завершенную функцию), итоговая история полна разветвлений:

Интеграция завершенной функции с объединением

Перебазирование перед слиянием

Разрешение конфликтов

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

Визуально, вот как выглядит история вашего проекта, когда git rebase сталкивается с конфликтом:

Чтобы разрешить конфликт, откройте конфликтующий файл (readme.txt в приведенном выше примере), найдите затронутые строки и вручную отредактируйте их до нужного результата. Затем скажите Git, что конфликт разрешен путем размещения файла:

Это переместит остальные коммиты, один за другим, и если возникнут какие-либо другие конфликты, вам придется повторить этот процесс снова и снова.

2. Перебазирование для очистки местных комитетов

Откроется редактор, содержащий все коммиты в feature которые собираются переместить:

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

Раздавление 2-го коммита с помощью интерактивной перебазировки

3. Опасности перебазирования

Когда вы работаете в одиночку над проектом, переписывание истории не имеет большого значения. Однако, как только вы начнете работать в среде совместной работы, это может стать очень опасным. Если вы переписываете коммиты, которые используют другие разработчики (например, коммиты в master ветке), это будет выглядеть так, как будто эти коммиты исчезли в следующий раз, когда они попытаются выполнить вашу работу. Это приводит к запутанному сценарию, от которого трудно оправиться.

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

Вывод

Источник

Обзорно-познавательный сайт