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.54.0
2026-04-20
- 2.39.1 → 2.53.0 no changes
-
2.39.0
2022-12-12
- 2.23.1 → 2.38.5 no changes
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 no changes
-
2.22.0
2019-06-07
- 2.20.1 → 2.21.4 no changes
-
2.20.0
2018-12-09
- 2.16.6 → 2.19.6 no changes
-
2.15.4
2019-12-06
- 2.5.6 → 2.14.6 no changes
-
2.4.12
2017-05-05
- 2.1.4 → 2.3.10 no changes
-
2.0.5
2014-12-17
ОПИСАНИЕ
В рабочем процессе, использующем относительно долгоживущие тематические ветки, разработчику иногда приходится снова и снова разрешать одни и те же конфликты, пока тематические ветки не будут завершены (либо слиты в ветку «release», либо отправлены и приняты вышестоящей веткой).
Эта команда помогает разработчику в этом процессе, записывая конфликтующие результаты автоматического слияния и соответствующие результаты ручного разрешения при первоначальном ручном слиянии и применяя ранее записанные ручные разрешения к соответствующим результатам автоматического слияния.
|
Note
|
Вам необходимо установить переменную конфигурации rerere.enabled, чтобы включить эту команду.
|
КОМАНДЫ
Обычно git rerere запускается без аргументов или вмешательства пользователя. Однако у него есть несколько команд, которые позволяют ему взаимодействовать со своим рабочим состоянием.
- clear
-
Сбрасывает метаданные, используемые rerere, если разрешение слияния должно быть прервано. Вызов git am [--skip|--abort] или git rebase [--skip|--abort] автоматически вызовет эту команду.
- forget <спецификатор-пути>
-
Сбрасывает разрешения конфликтов, которые rerere записал для текущего конфликта в <спецификатор-пути>.
- diff
-
Отображает сравнения для текущего состояния разрешения. Это полезно для отслеживания того, что изменилось, пока пользователь разрешает конфликты. Дополнительные аргументы передаются непосредственно системной команде diff, установленной в PATH.
- status
-
Выводит пути с конфликтами, разрешение слияния которых rerere запишет.
- remaining
-
Выводит пути с конфликтами, которые не были автоматически разрешены rerere. Это включает пути, разрешение которых не может быть отслежено rerere, такие как конфликтующие подмодули.
- gc
-
Подчищает записи о конфликтующих слияниях, которые произошли давно. По умолчанию подчищаются неразрешённые конфликты старше 15 дней и разрешённые конфликты старше 60 дней. Эти значения по умолчанию контролируются переменными конфигурации
gc.rerereUnresolvedиgc.rerereResolvedсоответственно.
ОБСУЖДЕНИЕ
Когда ваша тематическая ветка изменяет перекрывающуюся область, которую ваша ветка master (или вышестоящая) затронула с момента ответвления от неё вашей тематической ветки, вы можете захотеть протестировать её с последней версией master, даже до того, как ваша тематическая ветка будет готова к отправке вышестоящей ветке:
o---*---o topic
/
o---o---o---*---o---o master
Для такого теста вам нужно каким-то образом слить master и topic. Один из способов — выполнить получение master в ветку topic:
$ git switch topic
$ git merge master
o---*---o---+ topic
/ /
o---o---o---*---o---o master
Коммиты, отмеченные *, затрагивают одну и ту же область в одном и том же файле; вам нужно разрешить конфликты при создании коммита, отмеченного +. Затем вы можете протестировать результат, чтобы убедиться, что ваша незавершённая работа всё ещё работает с тем, что находится в последней версии master.
После этого тестового слияния есть два способа продолжить работу над topic. Самый простой — строить поверх тестового коммита слияния +, а когда ваша работа в ветке topic будет наконец готова, выполнить получение ветки topic в master и/или попросить вышестоящую ветку получить от вас. Однако к тому времени master или вышестоящая ветка могли продвинуться с момента тестового слияния +, и в этом случае окончательный граф коммитов будет выглядеть так:
$ git switch topic
$ git merge master
$ ... работа над ветками topic и master
$ git switch master
$ git merge topic
o---*---o---+---o---o topic
/ / \
o---o---o---*---o---o---o---o---+ master
Однако, когда ваша тематическая ветка долгоживущая, в ней в итоге окажется много таких коммитов «Merge from master», которые будут излишне загромождать историю разработки. Читатели списка рассылки ядра Linux могут помнить, что Линус жаловался на такие слишком частые тестовые слияния, когда сопровождающий подсистемы просил выполнить получение из ветки, полной «бесполезных слияний».
В качестве альтернативы, чтобы сохранить тематическую ветку чистой от тестовых слияний, вы могли бы удалить тестовое слияние и продолжать строить поверх верхушки перед тестовым слиянием:
$ git switch topic
$ git merge master
$ git reset --hard HEAD^ ;# откатить тестовое слияние
$ ... работа над ветками topic и master
$ git switch master
$ git merge topic
o---*---o-------o---o topic
/ \
o---o---o---*---o---o---o---o---+ master
Это приведёт к тому, что останется только один коммит слияния, когда ваша тематическая ветка будет наконец готова и слита с веткой master. Это слияние потребует от вас разрешить конфликт, внесённый коммитами, отмеченными *. Однако этот конфликт часто является тем же самым конфликтом, который вы разрешали при создании тестового слияния, которое вы удалили. git rerere помогает вам разрешить это окончательное конфликтующее слияние, используя информацию из вашего более раннего ручного разрешения.
Выполнение команды git rerere сразу после конфликтующего автоматического слияния записывает конфликтующие файлы рабочего каталога с обычными маркерами конфликта <<<<<<<, ======= и >>>>>>>. Позже, после того как вы закончите разрешать конфликты, повторное выполнение git rerere запишет разрешённое состояние этих файлов. Предположим, вы сделали это, когда создавали тестовое слияние master в ветку topic.
В следующий раз, после обнаружения того же конфликтующего автоматического слияния, выполнение git rerere выполнит трёхходовое слияние между более ранним конфликтующим автоматическим слиянием, более ранним ручным разрешением и текущим конфликтующим автоматическим слиянием. Если это трёхходовое слияние разрешается чисто, результат записывается в ваш файл рабочего каталога, поэтому вам не нужно разрешать его вручную. Обратите внимание, что git rerere не трогает файл индекса, поэтому вам всё равно нужно выполнить окончательные проверки работоспособности с помощью git diff (или git diff -c) и git add, когда вы будете удовлетворены.
В качестве удобства git merge автоматически вызывает git rerere при завершении с неудачным автоматическим слиянием, и git rerere записывает ручное разрешение, если это новый конфликт, или повторно использует более раннее ручное разрешение, если это не так. git commit также вызывает git rerere при фиксации результата слияния. Это означает, что вам не нужно делать ничего особенного самостоятельно (кроме включения переменной конфигурации rerere.enabled).
В нашем примере, когда вы выполняете тестовое слияние, ручное разрешение записывается, и оно будет повторно использовано, когда вы позже выполните фактическое слияние с обновлёнными ветками master и topic, если только записанное разрешение всё ещё применимо.
Информация, записанная git rerere, также используется при запуске git rebase. После удаления тестового слияния и продолжения разработки в ветке topic:
o---*---o-------o---o topic
/
o---o---o---*---o---o---o---o master
$ git rebase master topic
o---*---o-------o---o topic
/
o---o---o---*---o---o---o---o master
вы могли бы выполнить git rebase master topic, чтобы обновить себя перед тем, как ваша тема будет готова к отправке вышестоящей ветке. Это приведёт к возврату к трёхходовому слиянию, и конфликт будет таким же, как и в тестовом слиянии, которое вы разрешили ранее. git rerere будет запущен git rebase, чтобы помочь вам разрешить этот конфликт.
[ПРИМЕЧАНИЕ] git rerere полагается на маркеры конфликта в файле для обнаружения конфликта. Если файл уже содержит строки, которые выглядят так же, как строки с маркерами конфликта, git rerere может не записать разрешение конфликта. Чтобы обойти это, можно использовать настройку conflict-marker-size в gitattributes[5].
GIT
Является частью пакета git[1]