Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.50.1 → 2.51.0 no changes
-
2.50.0
2025-06-16
- 2.49.1 no changes
-
2.49.0
2025-03-14
- 2.46.2 → 2.48.2 no changes
-
2.46.1
2024-09-13
- 2.45.1 → 2.46.0 no changes
-
2.45.0
2024-04-29
- 2.44.1 → 2.44.4 no changes
-
2.44.0
2024-02-23
- 2.43.3 → 2.43.7 no changes
-
2.43.2
2024-02-13
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.42.2 → 2.42.4 no changes
-
2.42.1
2023-11-02
- 2.41.1 → 2.42.0 no changes
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 no changes
-
2.40.0
2023-03-12
- 2.39.4 → 2.39.5 no changes
-
2.39.3
2023-04-17
- 2.39.1 → 2.39.2 no changes
-
2.39.0
2022-12-12
- 2.38.1 → 2.38.5 no changes
-
2.38.0
2022-10-02
- 2.37.3 → 2.37.7 no changes
-
2.37.2
2022-08-11
- 2.36.3 → 2.37.1 no changes
-
2.36.2
2022-06-23
- 2.35.1 → 2.36.1 no changes
-
2.35.0
2022-01-24
- 2.34.1 → 2.34.8 no changes
-
2.34.0
2021-11-15
- 2.33.2 → 2.33.8 no changes
-
2.33.1
2021-10-12
- 2.32.1 → 2.33.0 no changes
-
2.32.0
2021-06-06
- 2.31.1 → 2.31.8 no changes
-
2.31.0
2021-03-15
- 2.30.1 → 2.30.9 no changes
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 no changes
-
2.29.0
2020-10-19
- 2.28.1 no changes
-
2.28.0
2020-07-27
- 2.27.1 no changes
-
2.27.0
2020-06-01
- 2.26.1 → 2.26.3 no changes
-
2.26.0
2020-03-22
- 2.25.1 → 2.25.5 no changes
-
2.25.0
2020-01-13
- 2.24.1 → 2.24.4 no changes
-
2.24.0
2019-11-04
- 2.23.1 → 2.23.4 no changes
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 no changes
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 no changes
-
2.21.0
2019-02-24
- 2.20.1 → 2.20.5 no changes
-
2.20.0
2018-12-09
- 2.19.3 → 2.19.6 no changes
-
2.19.2
2018-11-21
- 2.19.1 no changes
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 no changes
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 no changes
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
-
2.15.4
2019-12-06
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
-
2.12.5
2017-09-22
- 2.10.5 → 2.11.4 no changes
-
2.9.5
2017-07-30
-
2.8.6
2017-07-30
- 2.7.6 no changes
-
2.6.7
2017-05-05
- 2.5.6 no changes
-
2.4.12
2017-05-05
-
2.3.10
2015-09-28
-
2.2.3
2015-09-04
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
СИНОПСИС
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> буде поточною гілкою.
ІНТЕРАКТИВНИЙ РЕЖИМ
Інтерактивне перебазування означає, що у вас є можливість редагувати перебазовані коміти. Ви можете змінювати порядок комітів та видаляти їх (відсіюючи погані або небажані латки).
Інтерактивний режим призначений для такого типу робочого процесу:
-
маю чудову ідею
-
зламати код
-
підготувати серію до подання
-
подати
де пункт 2. складається з кількох випадків
a) regular use
-
завершити щось гідне зобов’язання
-
коміт
b) незалежний ремонт
-
усвідомити, що щось не працює
-
виправити це
-
зафіксувати це
Іноді виправлене у 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 See original version for this content. |
Warning
|
Missing See original version for this content. |
GIT
Частина набору git[1]