українська мова ▾ Topics ▾ Latest version ▾ git-rebase last updated in 2.53.0

НАЗВА

git-rebase — Повторне застосування комітів поверх іншої базової вершини

СИНОПСИС

git rebase [-i | --interactive] [<options>] [--exec <cmd>]
	[--onto <newbase> | --keep-base] [<upstream> [<branch>]]
git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
	--root [<branch>]
git rebase (--continue|--skip|--abort|--quit|--edit-todo|--show-current-patch)

ОПИС

Перенесення послідовності комітів на іншу початкову точку. Ви також можете використовувати git rebase для перестановки або обʼєднання комітів: див. ІНТЕРАКТИВНИЙ РЕЖИМ нижче, щоб дізнатися, як це зробити.

Наприклад, уявіть, що ви працювали з гілкою topic у цій історії, і хочете "надолужити" роботу, виконану в гілці master.

          A---B---C topic
         /
    D---E---F---G master

Ви хочете перенести коміти, які ви зробили в гілці topic, оскільки вона відхиляється від master (тобто A, B та C), поверх поточної master. Ви можете зробити це, запустивши git rebase master, поки гілка topic є поточною. Якщо ви хочете перебазувати topic, перебуваючи на іншій гілці, git rebase master topic — це скорочення для git checkout topic && git rebase master.

                  A'--B'--C' topic
                 /
    D---E---F---G master

Якщо під час цього процесу виникне конфлікт злиття, git rebase зупиниться на першому проблемному коміті та залишить маркери конфлікту. Якщо це станеться, ви можете зробити одне з наступного:

  1. Розвʼязати конфлікт. Ви можете скористатися командою git diff, щоб знайти маркери (<<<<<<) та внести зміни для розвʼязання конфлікту. Для кожного файлу, який ви редагуєте, вам потрібно повідомити Git, що конфлікт розвʼязано. Ви можете позначити конфлікт як розвʼязані за допомогою команди git add <імʼя-файлу>. Після розвʼязання всіх конфліктів ви можете продовжити процес перебазування за допомогою команди

    git rebase --continue
  2. Зупинити git rebase та повернути гілку до початкового стану за допомогою

    git rebase --abort
  3. Пропустити коміт, який спричинив конфлікт злиття командою

    git rebase --skip

Якщо ви не вкажете <upstream> для перебазування, буде використано upstream, налаштований у опціях branch.<name>.remote та branch.<name>.merge (докладніше див. git-config[1]), і передбачається опція --fork-point. Якщо ви наразі не перебуваєте на жодній гілці або якщо поточна гілка не має налаштованого upstream, перебазування буде перервано.

Ось спрощений опис того, що робить git rebase <upstream>:

  1. Створює список усіх комітів у вашій поточній гілці, починаючи з моменту відгалуження від <upstream>, які не мають еквівалентного коміту в <upstream>.

  2. Переходить на <upstream> за допомогою еквівалента git checkout --detach <upstream>.

  3. Повторно застосовує коміти один по одному. Це схоже на виконання git cherry-pick <commit> для кожного коміту. Дивіться ПЕРЕБАЗУВАННЯ ЗЛИТТЯ, щоб дізнатися, як обробляються злиття.

  4. Оновлює свою гілку, щоб вона вказувала на фінальний коміт, за допомогою еквівалента git checkout -B <гілка>.

Note
Під час запуску перебазування ORIG_HEAD встановлюється так, щоб вказувати на коміт на вершині гілки, що підлягає перебазуванню. Однак не гарантується, що ORIG_HEAD і надалі вказуватиме на цей коміт після завершення перебазування, якщо під час перебазування будуть використані інші команди, що змінюють ORIG_HEAD (наприклад, git reset). Проте до попередньої вершини гілки можна отримати доступ за допомогою reflog поточної гілки (тобто @{1}, див. gitrevisions[7]).

ПЕРЕНЕСЕННЯ ТЕМАТИЧНОЇ ГІЛКИ ЗА ДОПОМОГОЮ --ONTO

Ось як можна перенести тематичну гілку, створену на основі однієї гілки, на іншу, щоб створити враження, ніби ви відгалужили цю гілку від останньої, використовуючи команду rebase --onto.

Спочатку припустимо, що ваша гілка «topic» базується на гілці «next». Наприклад, функція, робота над якої велась в «topic», залежить від деякої функціональності, яка знаходиться в «next».

    o---o---o---o---o  master
         \
          o---o---o---o---o  next
                           \
                            o---o---o  topic

Ми хочемо створити гілку «topic» на основі гілки «master»; наприклад, тому що функціонал, від якого залежить «topic», було об’єднано з більш стабільною гілкою «master». Ми хочемо, щоб наше дерево виглядало так:

    o---o---o---o---o  master
        |            \
        |             o'--o'--o'  topic
         \
          o---o---o---o---o  next

Ми можемо отримати це за допомогою наступної команди:

git rebase --onto master next topic

Іншим прикладом використання опції --onto є перебазування частини гілки. Якщо у нас така ситуація:

                            H---I---J topicB
                           /
                  E---F---G  topicA
                 /
    A---B---C---D  master

тоді команда

git rebase --onto master topicA topicB

призведе до:

                 H'--I'--J'  topicB
                /
                | E---F---G  topicA
                |/
    A---B---C---D  master

Це корисно, коли topicB не залежить від topicA.

За допомогою rebase також можна видалити цілий ряд комітів. Якщо у нас така ситуація:

    E---F---G---H---I---J  topicA

тоді команда

git rebase --onto topicA~5 topicA~3 topicA

призведе до видалення комітів F та G:

    E---H'---I'---J'  topicA

Це корисно, якщо F і G містять якісь помилки або не повинні входити до складу topicA. Зверніть увагу, що аргументом для --onto та параметром <upstream> може бути будь-який дійсний комміт.

ОПЦІЇ РЕЖИМУ

Опції в цьому розділі не можна використовувати разом з будь-якими іншими опціями, зокрема й одна з одною:

--continue

Перезапустити процес перебазування після розвʼязання конфлікту злиття.

--skip

Перезапустити процес перебазування, пропустивши поточну латку.

--abort

Перервати операцію перебазування та скинути HEAD до початкової гілки. Якщо <branch> було надано під час початку операції перебазування, то HEAD буде скинуто до <branch>. В іншому випадку HEAD буде скинуто до того місця, де він був під час початку операції перебазування.

--quit

Перервати операцію перебазування, але значення HEAD не скидати до початкової гілки. Індекс та робоче дерево також залишаються незмінними в результаті. Якщо тимчасовий елемент сховку було створено за допомогою --autostash, він буде збережений у списку сховку.

--edit-todo

Редагувати список завдань під час інтерактивного перебазування.

--show-current-patch

Показувати поточну латку під час інтерактивного перебазування або коли перебазування зупинено через конфлікти. Це є еквівалентом git show REBASE_HEAD.

ОПЦІЇ

--onto <newbase>

Початкова точка для створення нових комітів. Якщо опція --onto не вказана, початковою точкою є <upstream>. Може бути будь-який дійсний коміт, а не лише назва наявної гілки.

В окремому випадку можна використовувати «A...B» як скорочений запис для бази злиття A та B, якщо така база існує лише одна. Можна опустити щонайбільше один із елементів A та B; у такому разі зазвичай буде використовуватися HEAD.

Див. приклади вище в розділі ПЕРЕНЕСЕННЯ ТЕМАТИЧНОЇ ГІЛКИ ЗА ДОПОМОГОЮ --ONTO.

--keep-base

Встановлює початкову точку, з якої потрібно створювати нові коміти для бази злиття <upstream> та <branch>. Виконання git rebase --keep-base <upstream> <branch> еквівалентне виконанню git rebase --reapply-cherry-picks --no-fork-point --onto <upstream>...<branch> <upstream> <branch>.

Ця опція корисна у випадках, коли розробка нової функції ведеться на основі гілки upstream. Під час роботи над функцією гілка upstream може оновлюватися, і в такому разі не завжди доцільно виконувати перебазування на основі upstream, а краще залишити базовий коміт без змін. Оскільки базовий коміт залишається незмінним, ця опція передбачає використання --reapply-cherry-picks, щоб уникнути втрати комітів.

Хоча і ця опція, і --fork-point знаходять базу злиття між <upstream> та <branch>, ця опція використовує базу злиття як відправну точку, з якої будуть створені нові коміти, тоді як --fork-point використовує базу злиття для визначення набору комітів, які будуть перебазовані.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

<upstream>

Гілка upstream, з якою потрібно проводити порівняння. Це може бути будь-який дійсний коміт, а не лише наявна назва гілки. Стандартно використовується налаштована гілка upstream для поточної гілки.

<branch>

Робоча гілка; зазвичай HEAD.

--apply

Використовувати стратегії apply для перебазування (внутрішньо викликаючи git-am). Ця опція може стати неактивною в майбутньому, коли механізм злиття почне виконувати всі функції, які зараз виконує apply.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--empty=(drop|keep|stop)

Як поводитися з комітами, які спочатку не є порожніми і не є чистими вибраними (cherry-pick) комітами будь-якого коміту upstream, але стають порожніми після перебазування (оскільки містять підмножину змін, що вже є в upstream):

drop

Коміт буде відкинуто. Це стандартна поведінка.

keep

Коміт буде збережено. Ця опція мається на увазі, коли вказано --exec, якщо також не вказано -i/--interactive.

stop
ask

Перебазування зупиниться після застосування коміту, що дозволить вам вибрати, чи відкинути його, редагувати файли далі, чи просто зафіксувати порожні зміни. Ця опція мається на увазі, коли вказано -i/--interactive. ask є застарілим синонімом stop.

Зверніть увагу, що коміти, які спочатку були порожніми, зберігаються (якщо не вказано параметр --no-keep-empty), а коміти, які є чистими cherry-pick-ами (як це визначається командою git log --cherry-mark ...), виявляються та відкидаються на попередньому етапі (якщо не вказано параметри --reapply-cherry-picks або --keep-base).

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--no-keep-empty
--keep-empty

Не зберігати у підсумковому результаті коміти, які перед перебазуванням були порожніми (тобто не містили змін порівняно з батьківським комітом). Стандартним є збереження порожніх комітів, оскільки для їх створення потрібно передати прапорець перевизначення --allow-empty команді git commit, що свідчить про те, що користувач цілком свідомо створює такий коміт і, отже, бажає його зберегти.

Цей прапорець, ймовірно, використовуватимуть рідко, оскільки позбутися комітів, що починаються з порожнього вмісту, можна просто запустивши інтерактивне перебазування та видаливши рядки, що відповідають непотрібним комітам. Цей прапорець існує як зручний швидкий спосіб, наприклад, для випадків, коли зовнішні інструменти генерують багато порожніх комітів, і ви хочете видалити їх усі.

Для комітів, які не починаються з порожніх, але стають порожніми після перебазування, дивіться прапорець --empty.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--reapply-cherry-picks
--no-reapply-cherry-picks

Повторно застосувати всі чисті вибіркові зміни (cherry-picks) будь-якого upstream-комміту замість того, щоб попередньо їх видаляти. (Якщо після перебазування ці комміти стануть порожніми, оскільки містять підмножину змін, що вже є в upstream, поведінка щодо них визначається прапорцем --empty.)

Якщо не вказано параметр --keep-base (або якщо вказано --no-reapply-cherry-picks), ці коміти будуть автоматично відкинуті. Оскільки для цього потрібно прочитати всі коміти з upstream, це може бути ресурсоємним у репозиторіях із великою кількістю комітів в upstream, які необхідно прочитати. При використанні бекенду «merge» для кожного відкинутого коміту видаватимуться попередження (якщо не вказано --quiet). Також видаватимуться поради, якщо advice.skippedCherryPicks не встановлено на false (див. git-config[1]).

--reapply-cherry-picks дозволяє rebase відмовитися від читання всіх комітів в upstream, що потенційно покращує продуктивність.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--allow-empty-message

Без змін. Раніше перебазування комітів із порожнім повідомленням завершувався з помилкою, а ця опція скасовувала таку поведінку, дозволяючи виконувати перебазування комітів із порожнім повідомленням. Тепер коміти з порожнім повідомленням не призводять до зупинки перебазування.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

-m
--merge

Використання стратегій обʼєднання для перебазування (стандартно).

Зверніть увагу, що злиття з перебазуванням працює шляхом повторного виконання кожного коміту з робочої гілки поверх гілки <upstream>. Через це, коли виникає конфлікт злиття, стороною, позначеною як «наша» (ours), є послідовністю, що на цей момент вже перебазувалася, починаючи з <upstream>, а «їхньою» (theirs) — робоча гілка. Іншими словами, сторони міняються місцями.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

-s <strategy>
--strategy=<strategy>

Використовувати вказану стратегію злиття замість стандартної ort. Мається на увазі --merge.

Оскільки git rebase відтворює кожен коміт з робочої гілки поверх гілки <upstream>, використовуючи вказану стратегію, використання стратегії ours просто очищає всі латки з <branch>, що не має сенсу.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

-X <strategy-option>
--strategy-option=<strategy-option>

Передати <strategy-option> до стратегії злиття. Це означає --merge, а якщо стратегія не вказана, то -s sort. Зверніть увагу на інвертування ours та heirs, як зазначено вище для опції -m.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--rerere-autoupdate
--no-rerere-autoupdate

Після того, як механізм rerere повторно використає записане розвʼязання поточного конфлікту для оновлення файлів у робочому дереві, дозвольте йому також оновити індекс результатом розвʼязання. --no-rerere-autoupdate — це гарний спосіб перевірити, що зробив rerere, та виявити потенційні помилки злиття, перш ніж занести результат до індексу за допомогою окремого git add.

-S[<keyid>]
--gpg-sign[=<keyid>]
--no-gpg-sign

Підписувати коміти за допомогою GPG. Аргумент keyid є необов’язковим, а стандартним значенням є ідентифікатор автора коміту; якщо його вказано, він повинен бути вказаний безпосередньо після опції без пробілу. Опція --no-gpg-sign дозволяє скасувати дію як конфігураційної змінної commit.gpgSign, так і раніше вказаної опції --gpg-sign.

-q
--quiet

Придушувати повідомлення. Мається на увазі --no-stat.

-v
--verbose

Докладніший вивід. Мається на увазі --stat.

--stat

Показувати diffstat із зазначенням змін, що відбулися в upstream з моменту останнього перебазування. Роботу diffstat також регулює параметр конфігурації rebase.stat.

-n
--no-stat

Не показувати diffstat як частину процесу перебазування.

--no-verify

Цей параметр дозволяє оминути гачок pre-rebase. Див. також githooks[5].

--verify

Дозволяє виконуватися гачку pre-rebase, що є стандартним значенням. Цей параметр можна використовувати для перевизначення --no-verify. Див. також githooks[5].

-C<n>

Дозволяє переконатися, що перед і після кожної зміни збігається принаймні <n> рядків супутнього контексту. Якщо супутнього контексту менше, то всі ці рядки мають збігатися. Типово контекст ніколи не ігнорується. Мається на увазі --apply.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--no-ff
--force-rebase
-f

Окремо відтворювати всі перебазовані коміти замість перемотування вперед по незмінних. Це гарантує, що вся історія перебазованої гілки складається з нових комітів.

Це може стати в нагоді після скасування злиття тематичної гілки, оскільки ця опція відтворює тематичну гілку з новими комітами, що дозволяє успішно виконати злиття знову без необхідності «скасовувати відкат» (детальніше див. посилання: howto/revert-a-faulty-merge.html[Посібник зі скасування помилкового злиття]).

--fork-point
--no-fork-point

Використовувати reflog, щоб знайти кращого спільного предка між <upstream> та <branch> під час обчислення, які коміти були внесені гілкою <branch>.

Коли активна опція --fork-point, для обчислення набору комітів для перебазування використовуватиметься fork_point замість <upstream>, де fork_point — це результат виконання команди git merge-base --fork-point <upstream> <branch> (див. git-merge-base[1]). Якщо fork_point виявиться порожнім, <upstream> буде використано як резервний варіант.

Якщо в командному рядку вказано <upstream> або --keep-base, то стандартним значенням є --no-fork-point, інакше — --fork-point. Див. також rebase.forkpoint у git-config[1].

Якщо ваша гілка базувалася на <upstream>, але <upstream> було відмотано назад, і ваша гілка містить коміти, які були видалені, цю опцію можна використовувати разом з --keep-base, щоб видалити ці коміти з вашої гілки.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--ignore-whitespace

При узгодженні розбіжностей ігнорувати розбіжності у пробілах. Наразі кожен бекенд реалізує наближену версію цієї поведінки:

бекенд застосування (apply backend)

Під час застосування латки ігнорувати зміни в пробілах у рядках контексту. На жаль, це означає, що якщо «старі» рядки, які замінюються латкою, відрізняються від наявного файлу лише пробілами, замість успішного застосування латки ви отримаєте конфлікт злиття.

бекенд злиття (merge backend)

Під час злиття вважати рядки, в яких змінено лише пробіли, незміненими. На жаль, це означає, що будь-які фрагменти латок, призначені виключно для зміни пробілів, будуть відкинуті, навіть якщо в іншому коді не було змін, що конфліктують з ними.

--whitespace=<option>

Цей прапорець передається програмі git apply (див. git-apply[1]), яка застосовує латку. Мається на увазі --apply.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--committer-date-is-author-date

Замість того, щоб використовувати поточний час як дату комітера, використовати дату автора коміту, що перебазується, як дату комітера. Ця опція передбачає використання --force-rebase.

Warning
Механізм відстеження історії припускає, що мітки часу комітів не зменшуються. Вам слід подумати, чи дійсно вам потрібно використовувати цю опцію. Використовувати цю опцію слід лише для того, щоб замінити дату коммітера при перебазуванні комітів на базу, коміт якої є старішим (за датою коміту) за найстаріший коміт, який ви застосовуєте (за датою автора).
--ignore-date
--reset-author-date

Замість використання дати авторства оригінального коміту, використовуйте поточний час як дату авторства перебазованого коміту. Ця опція передбачає --force-rebase.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--signoff

Додає трейлер Signed-off-by до всіх перебазованих комітів. Зверніть увагу, що якщо вказано --interactive, то трейлер буде додано лише до відібраних (picked) комітів, комітів позначених для редагування (edited) або зміни повідомлення коміту (reworded).

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

-i
--interactive

Створює список комітів, які будуть перебазовані. Дозволяє користувачу редагувати цей список перед перебазуванням. Цей режим також можна використовувати для розділення комітів (див. РОЗДІЛЕННЯ КОМІТІВ нижче).

Формат списку комітів можна змінити, встановивши параметр конфігурації rebase.instructionFormat. Налаштований формат інструкції автоматично матиме хеш коміту на початку формату.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

-r
--rebase-merges[=(rebase-cousins|no-rebase-cousins)]
--no-rebase-merges

Стандартно rebase просто видаляє коміти злиття зі списку завдань і розміщує коміти, що підлягають перебазуванню, в єдиній лінійній гілці. З опцією --rebase-merges rebase, навпаки, намагатиметься зберегти структуру гілок у комітах, що підлягають перебазуванню, шляхом відтворення комітів злиття. Будь-які розвʼязані конфлікти злиття або ручні виправлення в цих комітах злиття доведеться розвʼязувати/застосовувати заново вручну. --no-rebase-merges можна використовувати для скасування як опції конфігурації rebase.rebaseMerges, так і попереднього --rebase-merges.

Під час перебазування злиття існує два режими: rebase-cousins та no-rebase-cousins. Якщо режим не вказано, за звичай використовується no-rebase-cousins. У режимі no-rebase-cousins коміти, які не мають <upstream> як прямого предка, збережуть свою оригінальну точку відгалуження, тобто коміти, які були б виключені опцією --ancestry-path у git-log[1], стандартно збережуть свого оригінального предка. У режимі rebase-cousins такі коміти натомість перебазуються на <upstream> (або <onto>, якщо вказано).

Наразі можливо відтворити коміти злиття лише за допомогою стратегії злиття ort; різні стратегії злиття можна використовувати лише за допомогою явних команд exec git merge -s <strategy> [...].

Див. також ПЕРЕБАЗУВАННЯ ЗЛИТТЯ та НЕСУМІСНІ ОПЦІЇ нижче.

-x <cmd>
--exec <cmd>

Додає "exec <cmd>" після кожного рядка, що створює коміт, у фінальній історії. <cmd> буде інтерпретовано як одна або декілька команд оболонки. Будь-яка команда, яка завершиться невдачею, перерве перебазування з кодом виходу 1.

Ви можете виконати кілька команд, використовуючи один екземпляр --exec з кількома командами:

git rebase -i --exec "cmd1 && cmd2 && ..."

або, вказавши більше одного --exec:

git rebase -i --exec "cmd1" --exec "cmd2" --exec ...

Якщо використовується --autosquash, рядки exec не будуть додаватися для проміжних комітів і зʼявлятимуться лише в кінці кожної серії squash/fixup.

Ця команда внутрішньо використовує механізм --interactive, але її можна запустити і без явного вказівки --interactive.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--root

Перебазовує всі коміти, доступні з <branch>, замість того, щоб обмежувати їх за допомогою <upstream>. Це дозволяє перебазувати кореневі коміти у гілці.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--autosquash
--no-autosquash

Автоматично обʼєднувати коміти зі спеціально відформатованими повідомленнями з попередніми комітами, що перебазуються. Якщо повідомлення коміту починається з «squash!», «fixup!» або «amend!», решта заголовка розглядається як специфікатор коміту, який співпадає з попереднім комітом, якщо збігається з його заголовком або хешем. Якщо жоден коміт не збігається повністю, враховуються збіги специфікатора з початком заголовків комітів.

У списку завдань для перебазування дії «squash», «fixup» та «amend» змінюються з pick на squash, fixup або fixup -C відповідно, і переміщуються безпосередньо після коміту, який вони модифікують. Для перегляду та редагування списку завдань перед продовженням можна скористатися опцією --interactive.

Рекомендований спосіб створення комітів з маркерами squash — це використання опцій --squash, --fixup, --fixup=amend: або --fixup=reword: у git-commit[1], які приймають цільовий коміт як аргумент і автоматично заповнюють заголовок нового коміту з нього.

Встановлення змінної конфігурації rebase.autoSquash на true вмикає автоматичне стискання для інтерактивного перебазування. Опцію --no-autosquash можна використовувати для перевизначення цього налаштування.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

--autostash
--no-autostash

Автоматично створювати тимчасовий запис stash перед початком операції та застосовувати його після її завершення. Це означає, що ви можете виконати перебазування на зміненому але ще не збереженому робочому дереві. Однак використовуйте обережно: остаточне застосування stash після успішного перебазування може призвести до нетривіальних конфліктів.

--reschedule-failed-exec
--no-reschedule-failed-exec

Автоматично перезапускати команди exec, виконання яких завершилося з помилкою. Це доцільно лише в інтерактивному режимі (або якщо вказано параметр --exec).

Цей параметр застосовується після запуску перебазування. Він зберігається протягом усього процесу перебазування відповідно до наступного порядку: параметр командного рядка, вказаний у початковій команді git rebase; параметр конфігурації rebase.rescheduleFailedExec (див. git-config[1] або розділ «КОНФІГУРАЦІЯ» нижче); у разі відсутності зазначених параметрів застосовується стандартне значення — false.

Запис цього параметра для всього перебазування є зручною функцією. В іншому випадку явне значення --no-reschedule-failed-exec на початку буде перевизначено наявністю конфігурації rebase.rescheduleFailedExec=true під час виклику git rebase --continue. Наразі ви не можете передавати --[no-]reschedule-failed-exec до git rebase --continue.

--update-refs
--no-update-refs

Автоматично примусово оновлювати будь-які гілки, що вказують на коміти, що перебазуються. Будь-які гілки, що витягуються з робочого дерева, не оновлюються таким чином.

Якщо встановлено змінну конфігурації rebase.updateRefs, то цей параметр можна використовувати для перевизначення та вимкнення цього налаштування.

Див. також НЕСУМІСНІ ОПЦІЇ нижче.

НЕСУМІСНІ ОПЦІЇ

Наступні варіанти:

  • --apply

  • --whitespace

  • -C

несумісні з такими опціями:

  • --merge

  • --strategy

  • --strategy-option

  • --autosquash

  • --rebase-merges

  • --interactive

  • --exec

  • --no-keep-empty

  • --empty=

  • --[no-]reapply-cherry-picks у разі використання без --keep-base

  • --update-refs

  • --root при використанні без --onto

Крім того, такі пари опцій несумісні:

  • --keep-base і --onto

  • --keep-base і --root

  • --fork-point і --root

ВІДМІННОСТІ У ПОВЕДІНЦІ

git rebase має два основні бекенди: apply та merge. (Бекенд apply раніше був відомий як бекенд am, але ця назва призводила до плутанини, оскільки він виглядає як дієслово, а не іменник. Також бекенд merge раніше був відомий як інтерактивний бекенд, але тепер він використовується і для неінтерактивних випадків. Обидва були перейменовані на основі низькорівневої функціональності, на якій вони базувалися.) Існують деякі тонкі відмінності у поведінці цих двох бекендів:

Порожні коміти

На жаль, бекенд «apply» навмисно видаляє порожні коміти, тобто коміти, які починалися з порожнього стану, хоча на практиці це трапляється рідко. Він також видаляє коміти, які стають порожніми, і не має можливості контролювати цю поведінку.

Бекенд «merge» зазвичай навмисно зберігає порожні коміти (хоча з опцією -i вони позначаються як порожні в редакторі списку завдань, або їх можна автоматично видалити за допомогою --no-keep-empty).

Подібно до бекенду «apply», бекенд «merge» стандартно видаляє коміти, які стають порожніми, якщо не вказано -i/--interactive (у цьому випадку він зупиняється та запитує користувача, що робити). Бекенд «merge» також має опцію --empty=(drop|keep|stop) для зміни поведінки обробки комітів, які стають порожніми.

Виявлення перейменування тек

Через відсутність точної інформації про дерево (що виникає внаслідок побудови фіктивних попередників на основі обмеженої інформації, доступної в латках) виявлення перейменування тек у бекенді «apply» вимкнено. Вимкнене виявлення перейменування тек означає, що якщо одна сторона історії перейменує теку, а інша додасть нові файли до старої теки, то нові файли залишаться у старій теці без будь-якого попередження під час перебазування про те, що вам, можливо, варто перемістити ці файли до нової теки.

Виявлення перейменування тек працює разом з бекендом «merge», щоб надсилати вам попередження в таких випадках.

Контекст

Бекенд «apply» працює, створюючи послідовність латок (шляхом внутрішнього виклику format-patch), а потім застосовуючи латки по черзі (внутрішній виклик am). Латки складаються з кількох фрагментів, кожен з яких має номери рядків, область контексту та фактичні зміни. Номери рядків потрібно брати з деяким зміщенням, оскільки інша сторона, ймовірно, раніше вставила або видалила рядки у файлі. Область контексту призначена для того, щоб допомогти знайти спосіб налаштувати номери рядків, щоб застосувати зміни до правильних рядків. Однак, якщо кілька областей коду мають однакові навколишні рядки контексту, може бути вибрано неправильну. Є реальні випадки, коли це призводило до неправильного повторного застосування комітів без повідомлення про конфлікти. Встановлення більшого значення diff.context може запобігти таким проблемам, але збільшує ймовірність помилкових конфліктів (оскільки для застосування знадобиться більше рядків відповідного контексту).

Бекенд «merge» працює з повною копією кожного відповідного файлу, що запобігає таким проблемам.

Маркування маркерів конфліктів

Коли виникають конфлікти контенту, механізм злиття намагається анотувати маркери конфлікту кожної сторони з комітами, з яких походить контент. Оскільки бекенд «apply» видаляє оригінальну інформацію про перебазовані коміти та їхні батьківські коміти (і натомість генерує нові фальшиві коміти на основі обмеженої інформації у згенерованих латках), ці коміти неможливо ідентифікувати; натомість він повинен повернутися до підсумку комітів. Також, коли merge.conflictStyle встановлено на diff3 або zdiff3, бекенд «apply» використовуватиме «сконструйовану базу злиття» для позначення контенту з бази злиття, і таким чином не надаватиме жодної інформації про коміт бази злиття.

Бекенд «merge» працює з повними комітами з обох боків історії і тому не має таких обмежень.

Гачки

Бекенд «apply» традиційно не викликає гачок post-commit, тоді як бекенд «merge» викликає. Обидва викликають гачок post-commit хоча бекенд «merge» придушує його вивід. Крім того, обидва бекенди викликають гачок post-commit лише з початковим комітом перебазування, а не з проміжними комітами чи кінцевим комітом. У кожному випадку виклик цих гачків був випадковим через реалізацію, а не задумом (обидва бекенди спочатку були реалізовані як скрипти оболонки та викликали інші команди, такі як git checkout або git commit, які викликали хуки). Обидва бекенди повинні мати однакову поведінку, хоча не зовсім зрозуміло, яка з них, якщо така є, є правильною. Ми, ймовірно, зробимо так, щоб перебазування припинило викликати будь-який з цих гачків у майбутньому.

Можливість переривання

Бекенд «apply» має проблеми з безпекою через несвоєчасне переривання; якщо користувач натискає Ctrl-C у невідповідний момент, щоб спробувати перервати перебазування, перебазування може перейти в стан, коли його неможливо перервати з подальшою командою git rebase --abort. Бекенд «merge», схоже, не страждає від такого ж недоліку. (Див. https://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ для отримання детальнішої інформації.)

Зміна повідомлення коміту

Коли під час перебазування виникає конфлікт, перебазування зупиняється та запитує у користувача про його розʼязання. Оскільки користувачу може знадобитися внести помітні зміни під час розвʼязання конфліктів, після розвʼязання конфліктів та виконання користувачем команди git rebase --continue, перебазування має відкрити редактор і запитати у користувача оновити повідомлення коміту. Це робить бекенд merge, тоді як бекенд apply сліпо застосовує оригінальне повідомлення коміту.

Різні відмінності

Є ще кілька відмінностей у поведінці, які більшість людей, ймовірно, вважатимуть несуттєвими, але які згадані для повноти картини:

  • Reflog: Два бекенди використовуватимуть різні формулювання для опису змін, внесених до reflog, хоча обидва використовуватимуть слово «rebase».

  • Повідомлення про хід виконання, інформаційні повідомлення та повідомлення про помилки: Два бекенди надають дещо різні повідомлення про хід виконання та інформаційні повідомлення. Крім того, бекенд «apply» записує повідомлення про помилки (наприклад, «Ваші файли будуть перезаписані…​») в stdout, тоді як бекенд «merge» виводить їх в stderr.

  • Теки стану: обидва бекенди зберігають свої дані стану в різних теках у теці .git/

СТРАТЕГІЇ ЗЛИТТЯ

Механізм злиття (команди git merge та git pull) дозволяє вибирати бекенд-«стратегії злиття» за допомогою опції -s. Деякі стратегії також можуть приймати власні опції, які можна передати, надаючи аргументи -X<опція> командам git merge та/або git pull.

ort

Це стандартна стратегія злиття при витягуванні або злитті однієї гілки. Ця стратегія дозволяє об’єднати лише дві вершини за допомогою алгоритму тристороннього злиття. Коли існує більше ніж один спільний предок, який можна використати для тристороннього злиття, вона створює злите дерево спільних предків і використовує його як дерево-орієнтир для тристороннього злиття. За результатами тестів, проведених на реальних комітах злиття, взятих з історії розробки ядра Linux 2.6, це призводить до меншої кількості конфліктів злиття без створення помилкових злиттів. Крім того, ця стратегія може виявляти та обробляти злиття, що містять перейменування. Вона не використовуватиме виявлені копії. Назва цього алгоритму є акронімом («Ostensibly Recursive’s Twin») і походить від того, що він був написаний як заміна попереднього стандартного алгоритму, recursive.

Якщо шлях вказує на субмодуль, і коміт субмодуля, який використовується в одній частині злиття, є нащадком коміту субмодуля, що використовується в іншій частині злиття, Git намагається виконати швидкий перехід до цього нащадка. В іншому випадку Git розглядає цю ситуацію як конфлікт і пропонує в якості розвʼязання коміт субмодуля, який є нащадком комітів, що конфліктують, якщо такий існує.

Стратегія ort може приймати такі варіанти:

ours

Ця опція змушує систему автоматично розвʼязувати конфлікти між фрагментами коду, надаючи перевагу «нашій» версії. Зміни з іншого дерева, які не суперечать нашій версії, враховуються в результаті злиття. У випадку з бінарним файлом весь вміст береться з нашої версії.

Це не слід плутати зі стратегією злиття ours, яка взагалі не враховує вміст іншого дерева. Вона відкидає всі зміни, внесені в іншому дереві, і вважає, що «наша» історія містить усе, що там відбувалося.

theirs

Це протилежність параметру ours; зверніть увагу, що, на відміну від ours, не існує стратегії злиття theirs, з якою можна було б сплутати цей параметр злиття.

ignore-space-change
ignore-all-space
ignore-space-at-eol
ignore-cr-at-eol

Для цілей тристороннього злиття рядки, що містять вказаний тип змін пробілів, розглядаються як незмінені. Зміни пробілів, що поєднуються з іншими змінами в рядку, не ігноруються. Див. також git-diff[1] -b, -w, --ignore-space-at-eol та --ignore-cr-at-eol.

  • Якщо «їхня» версія передбачає лише зміну пробілів у рядку, використовується «наша» версія;

  • Якщо «наша» версія містить зміни пробілів, але «їхня» версія містить суттєві зміни, використовується «їхня» версія;

  • В іншому випадку обʼєднання відбувається у звичайному порядку.

renormalize

Ця опція виконує перевірку та реєстрацію всіх трьох стадій будь-якого файлу, який потребує тристороннього злиття. Цю опцію слід використовувати під час злиття гілок із різними фільтрами очищення або правилами нормалізації кінців рядків. Детальніше див. розділ «Злиття гілок із різними атрибутами checkin/checkout» у статті gitattributes[5].

no-renormalize

Вимикає опцію renormalize. Це замінює змінну конфігурації merge.renormalize.

find-renames[=<n>]

Вимкає виявлення перейменувань, за бажанням встановивши поріг схожості. Це значення є типовим. Воно має пріоритет над змінною конфігурації merge.renames. Див. також git-diff[1] --find-renames.

rename-threshold=<n>

Застарілий синонім до find-renames=<n>.

no-renames

Вимикає виявлення перейменування. Перевизнає змінну конфігурації merge.renames. Див. також git-diff[1] --no-renames.

histogram

Застарілий синонім до diff-algorithm=histogram.

patience

Застарілий синонім до diff-algorithm=patience.

diff-algorithm=(histogram|minimal|myers|patience)

Під час злиття використовувати інший алгоритм порівняння, що допоможе уникнути помилкових злиттів, які виникають через неважливі збіги рядків (наприклад, дужки з різних функцій). Див. також git-diff[1] --diff-algorithm. Зверніть увагу, що для ort стандартним значенням є diff-algorithm=histogram, тоді як для звичайних порівнянь наразі використовується значення параметра конфігурації diff.algorithm.

subtree[=<path>]

Цей варіант є вдосконаленою формою стратегії subtree, за якої стратегія робить припущення щодо того, як слід змістити два дерева, щоб вони збігалися під час об’єднання. Натомість до вказаного шляху додається префікс (або з його початку видаляється частина), щоб форми двох дерев збігалися.

recursive

Тепер це синонім до ort. Це стратегія була альтернативною реалізацією до версії 2.49.0, але була перенаправлена на ort у версії 2.50.0. Попередня рекурсивна стратегія була стандартною стратегією для розвʼязання для двох вершин з Git версії 0.99.9k до версії 2.33.0.

resolve

Може розвʼязувати лише дві гілки (тобто поточну гілку та іншу гілку, з якої було виконано злиття) за допомогою алгоритму тристороннього злиття. Намагається ретельно виявляти неоднозначності, пов’язані з перехресним злиттям. Не підтримує перейменування.

octopus

Ця стратегія розвʼязує випадки, коли є більше двох вершин, але відмовляється виконувати складне злиття, яке потребує ручного втручання. Вона призначена насамперед для обʼєднання вершин гілок тем. Це стратегія злиття є стандартною під час злиття або об’єднання кількох гілок.

ours

Ця стратегія дозволяє обʼєднати будь-яку кількість вершин, але отримане в результаті злиття дерево завжди відповідає вершині поточної гілки, фактично ігноруючи всі зміни з усіх інших гілок. Вона призначена для заміни старої історії розробки бічних гілок. Зверніть увагу, що вона відрізняється від опції -Xours стратегії злиття ort.

subtree

Це модифікована стратегія ort. Під час обʼєднання дерев A та B, якщо B відповідає піддереву A, B спочатку коригується відповідно до структури дерева A, замість того, щоб зчитувати дерева на одному рівні. Це коригування також виконується для дерева спільного предка.

У стратегіях, що використовують тристороннє злиття (включно зі стандартною стратегією ort), якщо зміна була внесена в обох гілках, але згодом скасована в одній із них, ця зміна все одно буде присутня в результаті злиття; деякі користувачі вважають таку поведінку заплутаною. Це відбувається тому, що під час злиття враховуються лише кінцеві точки гілок та базова точка злиття, а не окремі коміти. Тому алгоритм злиття розглядає скасовану зміну як відсутність будь-якої зміни взагалі і замінює її зміненою версією.

ПРИМІТКИ

Ви повинні розуміти наслідки використання git rebase на репозиторії, яким ви користуєтеся. Дивіться також ВІДНОВЛЕННЯ З ВИСХІДНОГО ПЕРЕБАЗУВАННЯ нижче.

Під час запуску перебазування спочатку виконається гачок pre-rebase, якщо такий існує. Ви можете використовувати цей гачок для перевірки справності та щоб відхилити перебазування, якщо воно є невідповідним. Будь ласка, дивіться шаблон сценарію гачка pre-rebase для прикладу.

Після завершення, <branch> буде поточною гілкою.

ІНТЕРАКТИВНИЙ РЕЖИМ

Інтерактивне перебазування означає, що у вас є можливість редагувати перебазовані коміти. Ви можете змінювати порядок комітів та видаляти їх (відсіюючи погані або небажані латки).

Інтерактивний режим призначений для такого типу робочого процесу:

  1. є ідея

  2. пишемо (змінюємо) код

  3. готуємо серію робіт до публікації

  4. публікуємо

де пункт 2. складається з кількох випадків

a) звичайне використання

  1. завершення чогось гідного, що варто зафіксувати

  2. створення коміту

b) незалежне виправлення

  1. усвідомити, що щось не працює

  2. виправити це

  3. зафіксувати це

Іноді помилку, виправлену в b.2, неможливо внести до неідеального коміту, який вона виправляє, оскільки цей коміт загубився десь у глибині серії латок. Саме для цього і призначене інтерактивне перебазування: використовуйте його після численних «a» та «b», перегруповуючи та редагуючи коміти, а також об’єднуючи кілька комітів в один.

Почніть з останнього коміту, який ви хочете зберегти таким як є:

git rebase -i <after-this-commit>

Відкриється редактор із усіма комітами у вашій поточній гілці (за винятком комітів злиття), які йдуть після вказаного коміту. Ви можете змінювати порядок комітів у цьому списку на свій розсуд, а також видаляти їх. Список виглядає приблизно так:

pick deadbee Один рядок цього коміту
pick fa1afe1 Один рядок наступного коміту
...

Однорядкові описи призначені виключно для вашої зручності; команда «git rebase» не враховуватиме їх, а керуватиметься назвами комітів (у цьому прикладі — «deadbee» та «fa1afe1»), тому не видаляйте й не редагуйте ці назви.

Замінивши команду "pick" на команду "edit", ви можете наказати git rebase зупинитися після застосування цього коміту, щоб ви могли редагувати файли та/або повідомлення коміту, виправляти коміт та продовжувати перебазування.

Щоб перервати перебазування (як це зробила б команда "edit", але без попереднього вибору будь-якого коміту), використовуйте команду "break".

Якщо ви просто хочете змінити повідомлення коміту, замініть команду "pick" на команду "reword".

Щоб видалити коміт, замініть команду "pick" на "drop" або просто видаліть відповідний рядок.

Якщо ви хочете обʼєднати два або більше комітів в один, замініть команду «pick» для другого та наступних комітів на «squash» або «fixup». Якщо коміти мали різних авторів, обʼєднаний коміт буде приписаний автору першого коміту. Пропонований текст повідомлення для обʼєднаного коміту — це обʼєднання тексту першого коміту з текстами, позначеними командами «squash», з пропуском текстів комітів, позначених командами «fixup», якщо не використовується «fixup -c». У цьому випадку пропонований текст повідомлення — це лише текст коміту «fixup -c», і відкривається редактор, що дозволяє вам редагувати повідомлення. Вміст (латка) коміту «fixup -c» все одно включається до згорнутого коміту. Якщо є більше ніж один коміт «fixup -c», використовується повідомлення з останнього. Ви також можете використовувати «fixup -C», щоб отримати таку саму поведінку, як і «fixup -c», але без відкриття редактора.

git rebase зупиниться, коли "pick" буде замінено на "edit" або коли команда завершиться невдачею через помилки злиття. Після завершення редагування та/або розвʼязання конфліктів ви можете продовжити за допомогою git rebase --continue.

Наприклад, якщо ви хочете змінити порядок останніх 5 комітів таким чином, щоб те, що було HEAD~4, стало новим HEAD. Для цього вам слід викликати git rebase ось так:

$ git rebase -i HEAD~5

І перемістіть першу латку в кінець списку.

Можливо, вам знадобиться відтворити коміти злиття, наприклад, якщо у вас така історія:

           X
            \
         A---M---B
        /
---o---O---P---Q

Припустимо, ви хочете перебазувати бічну гілку, починаючи з "A" на "Q". Переконайтеся, що поточний HEAD має значення "B", і викличте

$ git rebase -i -r --onto Q O

Зміна порядку та редагування комітів зазвичай створює непротестовані проміжні кроки. Ви можете перевірити, чи ваше редагування історії нічого не порушило, виконавши тест, або принаймні перекомпілювавши проміжні точки історії за допомогою команди "exec" (скорочення "x"). Ви можете зробити це, створивши список справ, подібний до цього:

pick deadbee Implement feature XXX
fixup f1a5c00 Fix to feature XXX
exec make
pick c0ffeee Один рядок наступного коміту
edit deadbab Один рядок коміту після
exec cd subdir; make test
...

Інтерактивне перебазування зупиниться, коли команда завершиться невдало (тобто завершиться зі статусом, відмінним від 0), щоб дати вам можливість виправити проблему. Ви можете продовжити за допомогою git rebase --continue.

Команда "exec" запускає команду в оболонці (стандартно, зазвичай /bin/sh), тому ви можете використовувати функції оболонки (такі як "cd", ">", ";" …​). Команда виконується з кореня робочого дерева.

$ git rebase -i --exec "make test"

Ця команда дозволяє перевірити, чи проміжні коміти компілюються. Список справ буде виглядати так:

pick 5928aea one
exec make test
pick 04d0fda two
exec make test
pick ba46169 three
exec make test
pick f4593f9 four
exec make test

РОЗДІЛЕННЯ КОМІТІВ

В інтерактивному режимі ви можете позначати коміти дією "edit". Однак це не обовʼязково означає, що git rebase очікує, що результатом цього редагування буде саме один коміт. Насправді, ви можете скасувати коміт або додати інші коміти. Це можна використовувати для розділення коміту на два:

  • Запустіть інтерактивне перебазування за допомогою git rebase -i <commit>^, де <commit> — це коміт, який ви хочете розділити. Фактично, підійде будь-який діапазон комітів, якщо він містить цей коміт.

  • Позначте коміт, який ви хочете розділити, дією "edit".

  • Щоб відредагувати цей коміт, виконайте команду git reset HEAD^. У результаті покажчик HEAD буде переміщений на один крок назад, і індекс буде відповідно змінений. При цьому робоче дерево залишиться без змін.

  • Тепер додайте зміни до індексу, які ви хочете мати в першому коміті. Ви можете використовувати git add (можливо, інтерактивно) або git gui (або обидва), щоб зробити це.

  • Зафіксуйте поточний індекс з будь-яким доречним на даний момент повідомленням коміту.

  • Повторюйте останні два кроки, доки ваше робоче дерево не стане чистим.

  • Продовжте перебазування за допомогою git rebase --continue.

Якщо ви не зовсім впевнені, що проміжні ревізії є узгодженими (вони компілюються, проходять тестування тощо), вам слід використовувати git stash, щоб зберігати ще не зафіксовані зміни після кожного коміту, тестувати та виправляти коміт, якщо необхідні виправлення.

ВІДНОВЛЕННЯ З ВИСХІДНОГО ПЕРЕБАЗУВАННЯ

Перебазування (або будь-яка інша форма перезапису) гілки, на якій базується робота інших, — погана ідея: будь-хто, хто базується на цій гілці, змушений вручну виправляти свою історію. У цьому розділі пояснюється, як зробити виправлення з їх точки зору. Однак справжнім виправленням було б уникнути перебазування виісхідної (upstream) гілки.

Для ілюстрації, припустимо, що ви перебуваєте в ситуації, коли хтось працює з гілкою «subsystem», а ви працюєте з «topic», яка залежить від цієї «subsystem». Ви можете отримати історію, подібну до наступної:

    o---o---o---o---o---o---o---o  master
	 \
	  o---o---o---o---o  subsystem
			   \
			    *---*---*  topic

Якщо «subsystem» перебазується відносно «master», відбувається наступне:

    o---o---o---o---o---o---o---o  master
	 \			 \
	  o---o---o---o---o	  o'--o'--o'--o'--o'  subsystem
			   \
			    *---*---*  topic

Якщо ви тепер продовжите розробку як зазвичай і зрештою обʼєднаєте гілку «topic» з гілкою «subsystem», коміти з гілки «subsystem» назавжди залишаться дубльованими:

    o---o---o---o---o---o---o---o  master
	 \			 \
	  o---o---o---o---o	  o'--o'--o'--o'--o'--M	 subsystem
			   \			     /
			    *---*---*-..........-*--*  topic

Такі дублікати, як правило, не схвалюються, оскільки вони захаращують історію, ускладнюючи її відстеження. Щоб навести лад, потрібно перенести коміти з гілки «topic» на вершину нової гілки «subsystem», тобто виконати перебазування гілки «topic». Це спричиняє ланцюгову реакцію: усі, хто використовує гілку «topic» як джерело, також змушені виконати перебазування, і так далі!

Існує два види виправлень, які розглядаються в наступних розділах:

Простий випадок: зміни буквально однакові.

Це трапляється, якщо перебазування «subsystem» було простим перебазуванням і не мало конфліктів.

Складний випадок: зміни не однакові.

Це трапляється, якщо під час перебазування «subsystem» виникали конфлікти або використовувався параметр --interactive для пропускання, редагування, стискання або виправлення комітів; або якщо в основній розробці використовувався один із параметрів commit --amend, reset або команда повного перезапису історії, як-от filter-repo.

Простий випадок

Працює лише тоді, коли зміни (ідентифікатори латок на основі вмісту diff) у «subsystem» буквально однакові до та після перебазування «subsystem».

У такому випадку виправлення просте, оскільки git rebase знає, що потрібно пропускати зміни, які вже присутні в новому upstream (якщо не вказано --reapply-cherry-picks). Тож, якщо ви кажете (припускаючи, що ви на topic)

    $ git rebase subsystem

у підсумку ви отримаєте виправлену історію

    o---o---o---o---o---o---o---o  master
				 \
				  o'--o'--o'--o'--o'  subsystem
						   \
						    *---*---*  topic

Складний випадок

Ситуація ускладнюється, якщо зміни в "subsystem" не зовсім відповідають тим, що були до перебазування.

Note
Хоча «простий випадок відновлення» іноді здається успішним навіть у складному випадку це може мати непередбачені наслідки. Для прикладу, коміт, який було видалено через git rebase --interactive стане воскреслим!

Ідея полягає в тому, щоб вручну вказати команді git rebase, «де закінчувалася стара гілка «subsystem» і починалася ваша гілка «topic», тобто яка була стара база злиття між ними. Вам доведеться знайти спосіб позначити останній коміт старої гілки «subsystem», наприклад:

  • Щодо reflog «subsystem»: після команди git fetch стара вершина «subsystem» знаходиться за адресою subsystem@{1}. Наступні операції fetch збільшуватимуть це число. (Див. git-reflog[1].)

  • Щодо вершини «topic» — знаючи, що «topic» має три коміти, колишня вершина «subsystem» має бути topic~3.

Потім ви можете перенести старий subsystem..topic у нову вершину, виконавши наступну команду (у випадку з reflog та припускаючи, що ви вже перебуваєте в «topic»):

    $ git rebase --onto subsystem subsystem@{1}

Ланцюговий ефект від відновлення «складного випадку» є особливо негативним: тепер «всі» користувачі, що базуються на «topic», також змушені будуть виконати відновлення «складного випадку»!

ПЕРЕБАЗУВАННЯ ЗЛИТТЯ

Команда interactive rebase спочатку була створена для обробки окремих серій латок. Тому доцільно виключити коміти злиття зі списку завдань, оскільки розробник міг злити на той момент актуальну гілку master під час роботи над гілкою, щоб зрештою виконати перебазування всіх комітів на master (пропустивши коміти злиття).

Однак існують обґрунтовані причини, через які розробник може захотіти відтворити коміти злиття: щоб зберегти структуру гілок (або «топологію комітів») під час роботи з декількома взаємопов’язаними гілками.

У наведеному нижче прикладі розробник працює над тематичною гілкою, в якій відбувається рефакторинг способу визначення кнопок, а також над іншою тематичною гілкою, в якій цей рефакторинг використовується для реалізації кнопки «Повідомити про помилку». Результат команди git log --graph --format=%s -5 може виглядати так:

*   Обʼєднання гілки 'report-a-bug'
|\
| * Додавання кнопки зворотного звʼязку
* | Гілка обʼєднання 'refactor-button'
|\ \
| |/
| * Використання класу Button для всіх кнопок
| * Витягти загальний клас Button з класу DownloadButton

Розробник може захотіти перебазувати ці коміти на новіший master, зберігаючи при цьому топологію гілок, наприклад, коли очікується, що перша тематична гілка буде інтегрована в master набагато раніше, ніж друга, скажімо, для розвʼязання конфліктів злиття зі змінами в класі DownloadButton, які перетворили його на master.

Це перебазування можна виконати за допомогою опції --rebase-merges. Це згенерує список завдань, який виглядатиме так:

label onto

# Гілка: refactor-button
reset onto
pick 123456 Витягти загальний клас Button з класу DownloadButton
pick 654321 Використання класу Button для всіх кнопок
label refactor-button

# Гілка: report-a-bug
reset refactor-button # Використання класу Button для всіх кнопок
pick abcdef Додавання кнопки зворотного звʼязку
label report-a-bug

reset onto
merge -C a1b2c3 refactor-button # Обʼєднання 'refactor-button'
merge -C 6f5e4d report-a-bug # Обʼєднання 'report-a-bug'

На відміну від звичайного інтерактивного перебазування, крім команд pick, існують ще й команди label, reset та merge.

Команда label пов’язує мітку з поточним HEAD під час її виконання. Ці мітки створюються як локальні refs робочого дерева (refs/rewritten/<label>) і видаляються після завершення перебазування. Таким чином, операції перебазування в декількох робочих деревах, пов’язаних з одним і тим самим репозиторієм, не заважають одна одній. Якщо виконання команди label завершується з помилкою, вона негайно переплановується, а користувачеві надається корисна підказка щодо подальших дій.

Команда reset скидає HEAD, індекс та робоче дерево до вказаної ревізії. Вона подібна до команди exec git reset --hard <label>, але не перезаписує файли, що не відстежуються. Якщо виконання команди reset завершується з помилкою, вона негайно повторно запускається з корисним повідомленням про те, як відредагувати список завдань (зазвичай це трапляється, коли команда reset була додана до списку завдань вручну і містить помилку).

Команда merge обʼєднає вказані ревізії з тим, що на той момент є HEAD. При використанні параметра -C <original-commit> буде використано повідомлення про коміт, вказане у зазначеному коміті злиття. Якщо замість -C вказати малу літеру -c, після успішного злиття повідомлення відкриється в редакторі, щоб користувач міг його відредагувати.

Якщо виконання команди merge завершується з помилкою з будь-якої причини, окрім конфліктів злиття (тобто коли операція злиття навіть не розпочалася), її виконання негайно переплановується.

Стандартно команда merge використовує стратегію злиття ort для звичайних злиттів та octopus для злиттів за алгоритмом Octopus. Можна вказати стандартну стратегію для всіх злиттів за допомогою аргументу --strategy під час виклику rebase, або замінити її для окремих злиттів у інтерактивному списку команд, використовуючи команду exec для явного виклику git merge з аргументом --strategy. Зверніть увагу, що при явному виклику git merge, як показано вище, ви можете скористатися тим, що мітки є локальними посиланнями робочого дерева (наприклад, посилання refs/rewritten/onto відповідатиме мітці onto), щоб вказати гілки, які ви хочете злити.

Примітка: перша команда (label onto) позначає ревізію, на яку перебазовуються коміти; назва onto — це лише умовність, як натяк на опцію --onto.

Також можна створювати абсолютно нові коміти злиття з нуля, додавши команду у вигляді merge <merge-head>. Ця форма генерує попереднє повідомлення про коміт і завжди відкриває редактор, щоб користувач міг його відредагувати. Це може бути корисно, наприклад, коли тематична гілка, як виявляється, стосується не однієї проблеми, і її потрібно розділити на дві або навіть більше тематичних гілок. Розглянемо такий список завдань:

pick 192837 Перехід з GNU Makefile на CMake
pick 5a6c7e Документуйте перехід на CMake
pick 918273 Виправлено виявлення OpenSSL у CMake
pick afbecd http: додати підтримку TLS версії 1.3
pick fdbaec Виправлено виявлення cURL у CMake на Windows

Єдиний коміт у цьому списку, який не повʼязаний із CMake, цілком міг бути спричинений роботою над виправленням усіх тих помилок, що виникли внаслідок переходу на CMake, але він стосується іншої проблеми. Щоб розділити цю гілку на дві тематичні гілки, список завдань можна відредагувати таким чином:

label onto

pick afbecd http: додати підтримку TLS версії 1.3
label tlsv1.3

reset onto
pick 192837 Перехід з GNU Makefile на CMake
pick 918273 Виправлено виявлення OpenSSL у CMake
pick fdbaec Виправлено виявлення cURL у CMake на Windows
pick 5a6c7e Документуйте перехід на CMake
label cmake

reset onto
merge tlsv1.3
merge cmake

КОНФІГУРАЦІЯ

Все, що знаходиться нижче цього рядка в цьому розділі, вибірково включено з документації git-config[1]. Вміст такий самий, як і там:

Warning

Missing uk/config/rebase.adoc

See original version for this content.

Warning

Missing uk/config/sequencer.adoc

See original version for this content.

GIT

Частина набору git[1]