українська мова ▾ Topics ▾ Latest version ▾ git-rebase last updated in 2.50.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)

ОПИС

Якщо вказано <branch>, git rebase виконає автоматичне git switch <branch> перед будь-якими іншими діями. В іншому випадку залишається на поточній гілці.

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

Усі зміни, внесені коммітами в поточній гілці, але не в <upstream>, зберігаються у тимчасовій області. Це той самий набір комітів, який буде показано за допомогою git log <upstream>..HEAD; або git log fork_point'..HEAD, якщо --fork-point активний (див. опис --fork-point нижче); або git log HEAD, якщо вказано опцію --root.

Поточна гілка скидається до <upstream> або <newbase>, якщо було вказано опцію --onto. Це має той самий ефект, що й git reset --hard <upstream> (або <newbase>). ORIG_HEAD встановлюється так, щоб вказувати на кінець гілки перед скиданням.

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

Коміти, які раніше були збережені у тимчасовій області, потім повторно застосовуються до поточної гілки, один за одним, по порядку. Зверніть увагу, що будь-які коміти в HEAD, які вносять ті самі текстові зміни, що й коміт у HEAD..<upstream>, пропускаються (тобто патч, який вже прийнято у верхній теці з іншим повідомленням коміту або міткою часу, буде пропущено).

Можливо, що помилка злиття завадить цьому процесу бути повністю автоматичним. Вам доведеться вирішити будь-яку таку помилку злиття та виконати git rebase --continue. Інший варіант — обійти коміт, який спричинив помилку злиття, за допомогою git rebase --skip. Щоб перевірити оригінальну <branch> та видалити робочі файли .git/rebase-apply, скористайтеся командою git rebase --abort.

Припустимо, що існує наступна історія, а поточна гілка — «тема»:

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

З цього моменту результат виконання будь-якої з наступних команд:

git rebase master
git rebase master topic

було б:

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

ПРИМІТКА: Остання форма є скороченим варіантом від git checkout topic, за яким слідує git rebase master. Після завершення rebase topic залишиться гілкою, що завершила роботу.

Якщо гілка upstream вже містить внесені вами зміни (наприклад, через те, що ви надіслали патч, який було застосовано upstream), то цей коміт буде пропущено, і будуть видані попередження (якщо використовується бекенд merge). Наприклад, запуск git rebase master для наступної історії (в якій A' та A вводять однаковий набір змін, але мають різну інформацію про комітера):

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

призведе до:

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

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

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

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

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

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

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

git rebase --onto опануйте наступну тему

Іншим прикладом використання опції --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 мають певні недоліки або не повинні бути частиною теми A. Зверніть увагу, що аргумент --onto та параметра <upstream> може бути будь-яким коректним аргументом, подібним до коміту.

У разі конфлікту, git rebase зупиниться на першому проблемному коміті та залишить маркери конфлікту в дереві. Ви можете використовувати git diff для пошуку маркерів (<<<<<<) та внесення змін для вирішення конфлікту. Для кожного файлу, який ви редагуєте, вам потрібно повідомити Git, що конфлікт вирішено, зазвичай це робиться за допомогою

git add <filename>

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

git rebase --continue

Або ж ви можете скасувати «git rebase» за допомогою

git rebase --abort

ВАРИАНТИ РЕЖИМУ

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

--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.

--keep-base

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

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

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

<upstream>

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

<branch>

Робоча гілка; за замовчуванням HEAD.

--apply

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

--empty=(drop|keep|stop)

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

drop

Коміт буде видалено. Це поведінка за замовчуванням.

keep

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

stop
ask

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

Зверніть увагу, що коміти, які починаються з порожнього стану, зберігаються (якщо не вказано --no-keep-empty), а коміти, які є чистими cherry-picks (як визначено 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

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

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

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

--allow-empty-message

Ніякої операції. Перебазування комітів з порожнім повідомленням раніше призводило до невдачі, і ця опція замінює цю поведінку, дозволяючи перебазувати коміти з порожніми повідомленнями. Тепер коміти з порожнім повідомленням не призводять до зупинки перебазування.

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

-m
--merge

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

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

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

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

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

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

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

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

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

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

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

-q
--quiet

Будь тихим. Мається на увазі --no-stat.

-v
--verbose

Будьте багатослівними. Мається на увазі --stat.

--stat

Показати diffstat щодо змін у вихідному коді з моменту останнього перебазування. 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

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

Вам може бути корисно це після скасування злиття тематичної гілки, оскільки ця опція відтворює тематичну гілку зі новими коммітами, щоб її можна було успішно повторно об’єднати без необхідності "скасувати скасування". revert-a-faulty-merge [Інструкції для отримання детальної інформації).

--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

Ігноруйте відмінності пробілів під час спроби узгодити розбіжності. Наразі кожен сервер реалізує приблизно таку поведінку:

застосувати серверну частину

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

merge backend

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

--whitespace=<option>

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

--committer-date-is-author-date

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

--ignore-date
--reset-author-date

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

--signoff

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

-i
--interactive

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

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

Див. також НЕСУМІСНІ ВАРІАНТИ нижче.

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

За замовчуванням, перебазування просто видаляє коміти злиття зі списку справ і поміщає перебазовані коміти в одну лінійну гілку. За допомогою --rebase-merges, перебазування намагатиметься зберегти структуру розгалуження в комітах, які потрібно перебазувати, шляхом повторного створення комітів злиття. Будь-які вирішені конфлікти злиття або ручні зміни в цих комітах злиття доведеться вирішувати/повторно застосовувати вручну. --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] або "CONFIGURATION" нижче), або значення за замовчуванням має значення 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-]повторно застосувати вибірку вишні при використанні без --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).

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

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

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

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

Контекст

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

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

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

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

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

Гачки

Бекенд «apply» традиційно не викликає хук після фіксації, тоді як бекенд «merge» викликає. Обидва викликають хук після фіксації, хоча бекенд «merge» приглушує його вивід. Крім того, обидва бекенди викликають хук після фіксації лише з початковим комітом перебазування, а не з проміжними комітами чи кінцевим комітом. У кожному випадку виклик цих хуків був випадковим через реалізацію, а не задумом (обидва бекенди спочатку були реалізовані як скрипти оболонки та викликали інші команди, такі як 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 сліпо застосовує оригінальне повідомлення коміту.

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

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

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

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

  • Директорії станів: Два серверні компоненти зберігають свій стан у різних директоріях під назвою .git/

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

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

ort

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

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

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

ours

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

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

theirs

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

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

Це запускає віртуальне отримання та повернення всіх трьох етапів будь-якого файлу, який потребує тристороннього злиття. Цей параметр призначений для використання під час об’єднання гілок з різними фільтрами очищення або правилами нормалізації кінця рядка. Див. "Об’єднання гілок з різними атрибутами реєстрації/вивантаження" в 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>]

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

recursive

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

resolve

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

octopus

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

ours

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

subtree

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

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

НОТАТКИ

Ви повинні розуміти наслідки використання git rebase на репозиторії, яким ви користуєтеся. Дивіться також ВІДНОВЛЕННЯ З UPSTREAM REBASE нижче.

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

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

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

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

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

  1. маю чудову ідею

  2. зламати код

  3. підготувати серію до подання

  4. подати

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

a) regular use

  1. завершити щось гідне зобов’язання

  2. коміт

b) незалежний ремонт

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

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

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

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

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

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

РОЗДІЛ КОМІТІВ

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

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

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

  • Коли справа доходить до редагування цього коміту, виконайте git reset HEAD^. Ефект полягає в тому, що HEAD перемотується на одиницю назад, а індекс перемотується. Однак робоче дерево залишається незмінним.

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

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

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

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

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

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

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

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

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

Якщо «підсистема» перебазується відносно «головної», відбувається наступне:

    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 також змушений перебазувати, і так далі!

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

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

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

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

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

Легкий випадок

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

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

    $ git rebase subsystem

ви отримаєте фіксовану історію

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

Важкий випадок

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

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

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

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

  • Щодо підказки до topic: знаючи, що ваша topic має три коміти, стара підказка до subsystem має бути topic~3.

Потім ви можете пересадити стару subsystem..topic до нової підказки, сказавши (для випадку reflog, і припускаючи, що ви вже на topic):

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

Хвильовий ефект відновлення у "важких випадках" особливо поганий: "всі" нижче за течією від "теми" тепер також повинні будуть виконувати відновлення у "важких випадках"!

Перебазування злиттів

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

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

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

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

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

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

наклеїти

# Гілка: кнопка-рефакторингу
reset onto
pick 123456 Extract a generic Button class from the DownloadButton one
pick 654321 Use the Button class for all buttons
label refactor-button

# Гілка: повідомити-про-помилку
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/rewritten/<label>), які будуть видалені після завершення перебазування. Таким чином, операції перебазування в кількох робочих деревах, пов’язаних з одним репозиторієм, не заважають одна одній. Якщо команда label не виконується, її негайно переплановують, з корисним повідомленням про те, як продовжити.

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

Команда merge об’єднає вказану(і) ревізію(ї) з будь-якою, яка на той момент є HEAD. З -C <оригінальний-комміт> буде використано повідомлення коміту вказаного злиття. Коли -C змінюється на нижній регістр -c, повідомлення буде відкрито в редакторі після успішного злиття, щоб користувач міг редагувати його.

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

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

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

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

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, але він вирішує іншу проблему. Щоб розділити цю гілку на дві тематичні гілки, список справ можна відредагувати так:

наклеїти

pick afbecd http: add support for TLS v1.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]