Команда git rebase: что делает, особенности и преимущества

    Команда Simple-Server
    03.06.2026
    11 мин

    Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.

    Кратко о задаче

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

    Предположим мы создали репозиторий с единственной веткой master, в которую сделали только один коммит. Ветка master приобрела следующий вид:

    После этого на основе master мы создали новую ветку hypothesis, внутри который решили протестировать некоторые фичи. Внутри новой ветки мы сделали несколько коммитов, улучшающих кодовую. Ветка приобрела такой вид:

    • hypothesis
    * `commit_4` * `commit_3` * `commit_2` * `commit_1`

    А уже потом мы добавили еще один коммит в ветку master, исправив некоторую уязвимость в срочном порядке. Таким образом, ветка master стала выглядеть так:

    Теперь наш репозиторий имеет структуру из двух веток:

    • hypothesis
    * `commit_4` * `commit_3` * `commit_2` * `commit_1`

    Ветка master является основной, а hypothesis — второстепенной (производной). Поздние коммиты указываются выше ранних, подобно тому, как их выводит команда git log.

    Предположим, мы хотим продолжить работу над улучшением фичи, под которую ранее выделили отдельную ветку hypothesis. Однако эта ветка не содержит жизненно важное исправление уязвимости, которое мы сделали в ветке master.

    Поэтому нам хотелось бы «синхронизировать» состояние ветки hypothesis с веткой master так, чтобы коммит исправления оказался в ветке с фичей. То есть мы хотим получить примерно такую структуру репозитория:

    • hypothesis
    * `commit_4` * `commit_3` * `commit_2` * `commit_5` * `commit_1`

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

    Чтобы получить такой результат, необходимо выполнить ребазирование с помощью команды git rebase.

    Впоследствии изменения, сделанные в hypothesis, можно будет объединить с веткой master с помощью классической команды git merge, создающей коммит слияния.

    Тогда структура репозитория станет такой:

    • master
    * `commit_merge` * `commit_5` * `commit_1`
    * `commit_4` * `commit_3` * `commit_2` * `commit_5` * `commit_1`

    Более того, выполнение git merge после команды git rebase может снизить вероятность возникновения конфликтов.

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

    Для начала создадим отдельную директорию, в которой будет размещаться репозиторий:

    После чего перейдем в нее:

    Теперь можно инициализировать репозиторий:

    В консольном терминале должно вывестись стандартное информационное сообщение:

    hint: Using 'master' as the name for the initial branch. This default branch name hint: is subject to change. To configure the initial branch name to use in all hint: of your new repositories, which will suppress this warning, call: ...

    А в текущей директории появится скрытый каталог .git, который можно увидеть с помощью соответствующей команды:

    Флаг -a означает all и позволяет просматривать файловую систему в расширенном режиме. Ее содержимое будет таким:

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

    git config --global user.name "ИМЯ" git config --global user.email "ИМЯ@ХОСТ.COM"

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

    Создадим файл импровизированной функции:

    И наполним его содержимом:

    Теперь проиндексируем изменения, сделанные в репозитории:

    На всякий случай можно проверить статус индексации:

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

    On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file:   function_1

    Теперь можно выполнить коммит:

    После этого в консольном терминале выведется сообщение об успешном внесении изменений в ветку master:

    [master (root-commit) 4eb7cc3] commit_1 1 file changed, 1 insertion(+) create mode 100644 function_1

    Наполнение ветки hypothesis

    Теперь необходимо создать новую ветку hypothesis:

    git checkout -b hypothesis

    Флаг -b необходим, чтобы сразу переключиться на созданную ветку.

    В консольном терминале появится сообщение об успешном переключении на новую ветку:

    Switched to a new branch 'hypothesis'

    Теперь необходимо последовательно выполнить три коммита с тремя файлами по аналогии с веткой master:

    • commit_2 с файлом function_2 и содержимым Функция 2

    • commit_3 с файлом function_3 и содержимым Функция 3

    • commit_4 с файлом function_4 и содержимым Функция 4

    commit_2 с файлом function_2 и содержимым Функция 2

    commit_3 с файлом function_3 и содержимым Функция 3

    commit_4 с файлом function_4 и содержимым Функция 4

    Если после этого просмотреть список всех коммитов:

    То в консольном терминале появится такая последовательность:

    d3efb82 (HEAD -> hypothesis) commit_4 c9f57b7 commit_3 c977f16 commit_2 4eb7cc3 (master) commit_1

    В этой команде флаг --oneline необходим для вывода информации о коммитах в сжатом формате одной строки.

    Последнее, что нужно сделать, — добавить еще один коммит в основную ветку master. Переключимся на нее:

    В консольном терминале должно появится соответствующее сообщение:

    Switched to branch 'master'

    После этого создадим еще один файл импровизированной функции:

    Содержимое будет следующим:

    Теперь можно проиндексировать изменения:

    И выполнить очередной коммит:

    Если проверить текущий список коммитов:

    То в ветке master их будет всего два:

    3df7a00 (HEAD -> master) commit_5 4eb7cc3 commit_1

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

    Для выполнения перебазирования сперва необходимо перейти в ветку hypothesis:

    И выполнить ребазирование:

    После этого в консольном терминале появится сообщение об успешном ребазировании:

    Successfully rebased and updated refs/heads/hypothesis.

    Теперь можно проверить список коммитов:

    В консольном терминале появится список, содержащий коммиты обоих веток в оригинальном порядке:

    8ecfd58 (HEAD -> hypothesis) commit_4 f715aba commit_3 ee47470 commit_2 3df7a00 (master) commit_5 4eb7cc3 commit_1

    Теперь ветка hypothesis содержит общую историю всего репозитория.**
    **

    Как и в случае с git merge, при использовании команды git rebase могут возникать конфликты, требующие ручного разрешения.

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

    Создадим в ветке hypothesis еще один файл:

    И запишем в него следующий текст:

    Тут должен быть конфликт!

    Проиндексируем изменения:

    И выполним очередной коммит:

    git commit -m "conflict_1"

    Теперь переключимся на ветку master:

    Создадим аналогичный файл:

    И наполним его следующим содержимым:

    Тут НЕ должен быть конфликт!

    Аналогично, выполняем индексацию:

    git commit -m "conflict_2"

    Заново откроем созданный файл:

    И изменим его содержимое на следующий текст:

    Тут точно НЕ должен быть конфликт! git commit -m "conflict_3"

    Теперь можно обратно переключиться на ветку hypothesis:

    А далее выполнить еще одно ребазирование:

    В консольном терминале появится сообщение о конфликте:

    Auto-merging conflict CONFLICT (add/add): Merge conflict in conflict error: could not apply 6003ed7... conflict_1 hint: Resolve all conflicts manually, mark them as resolved with hint: "git add/rm <conflicted_files>", then run "git rebase --continue". hint: You can instead skip this commit: run "git rebase --skip". hint: To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply 6003ed7... conflict_1

    Git предлагает отредактировать файл conflict, проиндексировать изменения с помощью команды git add, после чего продолжить ребазирование, указав флаг --continue.

    Именно так мы и поступим:

    Файл будет содержать две конфликтующие версии файла, обрамленные специальными символами:

    <<<<<<< HEAD Тут точно НЕ должен быть конфликт! ======= Тут должен быть конфликт! >>>>>>> 6003ed7 (conflict_1)

    Наша задача убрать всё лишнее, наполнив файл итоговым вариантом произвольного текста:

    Тут однозначно точно единогласно НЕ должен быть никакого конфликта!

    Теперь индексируем изменения:

    И продолжаем процесс ребазирования:

    После этого в консольном терминале откроется текстовый редактор, предлагающий изменение оригинальное название того коммита, в котором возник конфликт:

    conflict_1 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # interactive rebase in progress; onto bd7aefc # Last commands done (4 commands done): #    pick 8ecfd58 commit_4 #    pick 6003ed7 conflict_1 # No commands remaining. # You are currently rebasing branch 'hypothesis' on 'bd7aefc'. # # Changes to be committed: #       modified:   conflict #

    В консольном терминале появится сообщение об успешном завершении процесса ребазирования:

    [detached HEAD 482db49] conflict_1 1 file changed, 1 insertion(+), 1 deletion(-) Successfully rebased and updated refs/heads/hypothesis.

    Теперь если проверить список коммитов в ветке hypothesis:

    Можно увидеть оригинальную последовательность всех сделанных изменений:

    482db49 (HEAD -> hypothesis) conflict_1 bd5d036 commit_4 407e245 commit_3 948b41c commit_2 bd7aefc (master) conflict_3 d98648d conflict_2 3df7a00 commit_5 4eb7cc3 commit_1

    Обратите внимание, что коммиты conflict_2 и conflict_3, сделанные в ветке master, располагаются в истории изменений раньше, чем коммит conflict_1. Впрочем, это касается любых коммитов, сделанных в ветке master.**
    **

    Ребазирование удаленного репозитория

    Помимо работы с локальными ветками, ребазирование можно выполнить в момент подтягивания изменений из удаленного репозитория. Для этого к стандартной команде pull необходимо добавить флаг --rebase:

    git pull --rebase remote branch
    • remote. Удаленный репозиторий.

    • branch. Удаленная ветка.

    remote. Удаленный репозиторий.

    branch. Удаленная ветка.

    По сути, такая конфигурация команды pull является эквивалентом git rebase за исключением того, что применяемые к текущей ветки изменения (коммиты) берутся из удаленного репозитория.

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

    Такая последовательность и отсутствие ветвления делает историю проще для восприятия и понимания.**
    **

    • Снижение количества конфликтов

    Предварительно выполненная команда git rebase может существенно снизить вероятность возникновения конфликтов при объединении веток с помощью git merge.

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

    В отличие от слияния, ребазирование частично переписывает историю целевой ветки. При этом лишние элементы истории удаляются.**
    **

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


    Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.

    VPS для проекта

    VPS с root-доступом, NVMe и поддержкой 24/7 на Simple-Server.

    StarterVDS

    490₽

    в месяц

    1 ядро

    1 ГБ RAM

    20 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Безлимитный трафик
    Заказать VPS
    Рекомендуем

    PerformanceVDS

    1190₽

    в месяц

    2 ядра

    4 ГБ RAM

    60 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Базовая DDoS-защита
    Заказать VPS

    Нужна другая конфигурация или чистый VPS без панели?

    Все тарифы VPS

    Похожие статьи, которые могут быть вам интересны