Русский ▾ Topics ▾ Latest version ▾ git-merge last updated in 2.53.0

НАЗВАНИЕ

git-merge - Объединение одной или нескольких историй разработки вместе

ОБЗОР

git merge [-n] [--stat] [--compact-summary] [--no-commit] [--squash] [--[no-]edit]
	[--no-verify] [-s <стратегия>] [-X <параметр-стратегии>] [-S[<id-ключа>]]
	[--[no-]allow-unrelated-histories]
	[--[no-]rerere-autoupdate] [-m <сообщение>] [-F <файл>]
	[--into-name <ветка>] [<коммит>…​]
git merge (--continue | --abort | --quit)

ОПИСАНИЕ

Включает изменения из указанных коммитов (с момента расхождения их историй с текущей веткой) в текущую ветку. Эта команда используется git pull для включения изменений из другого репозитория и может использоваться вручную для слияния изменений из одной ветки в другую.

Предположим, существует следующая история, и текущая ветка — master:

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

Затем git merge topic повторно применит изменения, сделанные в ветке topic с момента её расхождения с master (т.е. E) до её текущего коммита (C), поверх master, и запишет результат в новый коммит вместе с именами двух родительских коммитов и сообщением журнала от пользователя, описывающим изменения. Перед операцией ORIG_HEAD устанавливается на верхушку (tip) текущей ветки (G).

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

Слияние останавливается, если возникает конфликт, который не может быть разрешён автоматически, или если при инициировании слияния был указан --no-commit. В этот момент вы можете выполнить git merge --abort или git merge --continue.

git merge --abort прервёт процесс слияния и попытается восстановить состояние до слияния. Однако, если на момент начала слияния были незафиксированные изменения (и особенно если эти изменения были дополнительно изменены после начала слияния), git merge --abort в некоторых случаях не сможет восстановить исходные (до слияния) изменения. Поэтому:

Warning
Выполнение git merge с нетривиальными незафиксированными изменениями не рекомендуется: хотя это возможно, в случае конфликта вы можете оказаться в состоянии, из которого трудно выбраться.

ПАРАМЕТРЫ

Warning

Missing ru/merge-options.adoc

See original version for this content.

-m <сообщение>

Установить сообщение коммита, которое будет использовано для коммита слияния (если он создаётся).

Если указан --log, к указанному сообщению будет добавлен краткий журнал (shortlog) сливаемых коммитов.

Команда git fmt-merge-msg может использоваться для создания хорошего значения по умолчанию для автоматических вызовов git merge. Автоматическое сообщение может включать описание ветки.

--into-name <ветка>

Подготовить сообщение слияния по умолчанию так, как если бы слияние выполнялось в ветку <ветка>, вместо имени реальной ветки, в которую выполняется слияние.

-F <файл>
--file=<файл>

Прочитать сообщение коммита, которое будет использовано для коммита слияния (если он создаётся).

Если указан --log, к указанному сообщению будет добавлен краткий журнал (shortlog) сливаемых коммитов.

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

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

--overwrite-ignore
--no-overwrite-ignore

Незаметно перезаписывать игнорируемые файлы из результата слияния. Это поведение по умолчанию. Используйте --no-overwrite-ignore, чтобы прервать операцию.

--abort

Прервать текущий процесс разрешения конфликта и попытаться восстановить состояние до слияния. Если присутствует запись автоатайника (autostash), применить её к рабочему каталогу.

Если на момент начала слияния присутствовали незафиксированные изменения в рабочем каталоге, git merge --abort в некоторых случаях не сможет восстановить эти изменения. Поэтому рекомендуется всегда фиксировать или прятать (stash) свои изменения перед запуском git merge.

git merge --abort эквивалентен git reset --merge, когда присутствует MERGE_HEAD, если только также не присутствует MERGE_AUTOSTASH, и в этом случае git merge --abort применяет запись из тайника (stash) к рабочему каталогу, тогда как git reset --merge сохранит спрятанные изменения в списке тайников.

--quit

Забыть о текущем процессе слияния. Оставить индекс и рабочий каталог в текущем состоянии. Если присутствует MERGE_AUTOSTASH, запись из тайника будет сохранена в список тайников.

--continue

После остановки git merge из-за конфликтов вы можете завершить слияние, выполнив git merge --continue (см. раздел «КАК РАЗРЕШАТЬ КОНФЛИКТЫ» ниже).

<коммит>...

Коммиты, обычно головы других веток, для слияния в нашу ветку. Указание более одного коммита создаст слияние с более чем двумя родителями (ласково называемое слиянием Octopus).

Если коммит не указан в командной строке, выполнить слияние отслеживаемых внешних веток, которые текущая ветка настроена использовать в качестве своей вышестоящей (upstream) ветки. См. также раздел конфигурации этой справочной страницы.

Когда указан FETCH_HEAD (и никакой другой коммит), ветки, записанные в файле .git/FETCH_HEAD предыдущим вызовом git fetch для слияния, сливаются с текущей веткой.

ПРОВЕРКИ ПЕРЕД СЛИЯНИЕМ

Перед применением внешних изменений вы должны привести свою работу в порядок и зафиксировать её локально, чтобы она не была затёрта в случае конфликтов. См. также git-stash[1]. git pull и git merge остановятся без каких-либо действий, когда локальные незафиксированные изменения пересекаются с файлами, которые git pull/git merge могут потребовать обновить.

Чтобы избежать записи несвязанных изменений в коммит слияния, git pull и git merge также прервутся, если в индексе есть какие-либо изменения относительно коммита HEAD. (В зависимости от используемой стратегии слияния могут существовать особые узкие исключения из этого правила, но обычно индекс должен соответствовать HEAD.)

Если все указанные коммиты уже являются предками HEAD, git merge завершится досрочно с сообщением «Уже актуально.» (Already up to date.)

СЛИЯНИЕ ПЕРЕМОТКОЙ ВПЕРЁД

Часто голова текущей ветки является предком указанного коммита. Это самый распространённый случай, особенно при вызове из git pull: вы отслеживаете вышестоящий (upstream) репозиторий, у вас нет зафиксированных локальных изменений, и теперь вы хотите обновиться до более новой вышестоящей редакции. В этом случае новый коммит не нужен для хранения объединённой истории; вместо этого HEAD (вместе с индексом) обновляется, чтобы указывать на указанный коммит, без создания дополнительного коммита слияния.

Это поведение можно подавить с помощью опции --no-ff.

ИСТИННОЕ СЛИЯНИЕ

За исключением слияния перемоткой вперёд (см. выше), сливаемые ветки должны быть связаны коммитом слияния, у которого обе они являются родителями.

Фиксируется объединённая версия, согласовывающая изменения из всех сливаемых веток, и ваш HEAD, индекс и рабочий каталог обновляются до неё. Допустимо наличие изменений в рабочем каталоге, если они не пересекаются; обновление сохранит их.

Когда неочевидно, как согласовать изменения, происходит следующее:

  1. Указатель HEAD остаётся тем же.

  2. Ссылка MERGE_HEAD устанавливается указывать на голову другой ветки.

  3. Пути, которые слились чисто, обновляются как в файле индекса, так и в вашем рабочем каталоге.

  4. Для конфликтующих путей файл индекса хранит до трёх версий: этап 1 хранит версию от общего предка, этап 2 от HEAD, а этап 3 от MERGE_HEAD (вы можете просмотреть этапы с помощью git ls-files -u). Файлы рабочего каталога содержат результат операции слияния; т.е. результаты трёхстороннего слияния со знакомыми маркерами конфликтов <<< === >>>.

  5. Записывается ссылка с именем AUTO_MERGE, указывающая на дерево, соответствующее текущему содержимому рабочего каталога (включая маркеры конфликтов для текстовых конфликтов). Обратите внимание, что эта ссылка записывается только при использовании стратегии слияния ort (по умолчанию).

  6. Никаких других изменений не делается. В частности, локальные изменения, которые у вас были до начала слияния, останутся такими же, и записи индекса для них останутся такими, как были, т.е. соответствующими HEAD.

Если вы попытались выполнить слияние, которое привело к сложным конфликтам, и хотите начать заново, вы можете восстановиться с помощью git merge --abort.

СЛИЯНИЕ МЕТКИ

При слиянии аннотированной (и, возможно, подписанной) метки Git всегда создаёт коммит слияния, даже если возможно слияние перемоткой вперёд, и шаблон сообщения коммита подготавливается с сообщением метки. Кроме того, если метка подписана, проверка подписи сообщается как комментарий в шаблоне сообщения. См. также git-tag[1].

Когда вы хотите просто интегрироваться с работой, ведущей к коммиту, который оказался помеченным, например, синхронизируясь с точкой вышестоящего (upstream) выпуска, вы можете не захотеть создавать ненужный коммит слияния.

В таком случае вы можете самостоятельно «развернуть» метку перед передачей её в git merge или передать --ff-only, если у вас нет своей работы. например

git fetch origin
git merge v1.2.3^0
git merge --ff-only v1.2.3

КАК ПРЕДСТАВЛЯЮТСЯ КОНФЛИКТЫ

Во время слияния файлы рабочего каталога обновляются, чтобы отразить результат слияния. Среди изменений, внесённых в версию общего предка, непересекающиеся (то есть вы изменили область файла, в то время как другая сторона оставила эту область нетронутой, или наоборот) включаются в конечный результат дословно. Однако, когда обе стороны внесли изменения в одну и ту же область, Git не может случайным образом выбрать одну сторону над другой и просит вас разрешить это, оставляя то, что обе стороны сделали с этой областью.

По умолчанию Git использует тот же стиль, что и программа «merge» из набора RCS, для представления такого конфликтного блока, например:

Вот строки, которые либо не изменились по сравнению с общим
предком, либо чисто разрешены, потому что изменилась только одна сторона,
либо чисто разрешены, потому что обе стороны изменились одинаково.
<<<<<<< yours:sample.txt
Разрешение конфликтов — это сложно;
пойдём по магазинам.
=======
Git делает разрешение конфликтов лёгким.
>>>>>>> theirs:sample.txt
А вот другая строка, которая либо чисто разрешена, либо не изменена.

Область, где произошла пара конфликтующих изменений, помечена маркерами <<<<<<<, ======= и >>>>>>>. Часть до ======= обычно представляет вашу сторону, а часть после — их сторону.

Формат по умолчанию не показывает, что говорилось в исходном тексте в конфликтующей области. Вы не можете сказать, сколько строк удалено и заменено на замечание Барби с вашей стороны. Единственное, что вы можете сказать, это то, что ваша сторона хочет сказать, что это сложно, и вы предпочли бы пойти по магазинам, в то время как другая сторона хочет утверждать, что это легко.

Альтернативный стиль можно использовать, установив переменную конфигурации merge.conflictStyle в diff3 или zdiff3. В стиле diff3 вышеуказанный конфликт может выглядеть так:

Вот строки, которые либо не изменились по сравнению с общим
предком, либо чисто разрешены, потому что изменилась только одна сторона,
<<<<<<< yours:sample.txt
либо чисто разрешены, потому что обе стороны изменились одинаково.
Разрешение конфликтов — это сложно;
пойдём по магазинам.
||||||| base:sample.txt
либо чисто разрешены, потому что обе стороны изменились идентично.
Разрешение конфликтов — это сложно.
=======
либо чисто разрешены, потому что обе стороны изменились одинаково.
Git делает разрешение конфликтов лёгким.
>>>>>>> theirs:sample.txt
А вот другая строка, которая либо чисто разрешена, либо не изменена.

тогда как в стиле zdiff3 это может выглядеть так:

Вот строки, которые либо не изменились по сравнению с общим
предком, либо чисто разрешены, потому что изменилась только одна сторона,
либо чисто разрешены, потому что обе стороны изменились одинаково.
<<<<<<< yours:sample.txt
Разрешение конфликтов — это сложно;
пойдём по магазинам.
||||||| base:sample.txt
либо чисто разрешены, потому что обе стороны изменились идентично.
Разрешение конфликтов — это сложно.
=======
Git делает разрешение конфликтов лёгким.
>>>>>>> theirs:sample.txt
А вот другая строка, которая либо чисто разрешена, либо не изменена.

В дополнение к маркерам <<<<<<<, ======= и >>>>>>> он использует ещё один маркер |||||||, за которым следует исходный текст. Вы можете сказать, что исходный текст просто констатировал факт, а ваша сторона просто согласилась с этим утверждением и сдалась, в то время как другая сторона попыталась иметь более позитивный настрой. Иногда вы можете придумать лучшее разрешение, просмотрев исходный текст.

КАК РАЗРЕШАТЬ КОНФЛИКТЫ

Увидев конфликт, вы можете сделать две вещи:

  • Решить не сливать. Единственная необходимая очистка — сбросить файл индекса до коммита HEAD, чтобы отменить шаг 2, и очистить изменения в рабочем каталоге, сделанные на шагах 2 и 3; для этого можно использовать git merge --abort.

  • Разрешить конфликты. Git отметит конфликты в рабочем каталоге. Отредактируйте файлы в нужную форму и выполните git add для них в индекс. Используйте git commit или git merge --continue, чтобы завершить дело. Последняя команда проверяет, есть ли (прерванное) слияние в процессе, перед вызовом git commit.

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

  • Используйте инструмент слияния (mergetool). git mergetool запускает графический инструмент слияния, который проведёт вас через слияние.

  • Посмотрите на различия. git diff покажет трёхстороннее сравнение, выделяя изменения как из версии HEAD, так и из MERGE_HEAD. git diff AUTO_MERGE покажет, какие изменения вы внесли на данный момент для разрешения текстовых конфликтов.

  • Посмотрите на различия из каждой ветки. git log --merge -p <путь> покажет различия сначала для версии HEAD, а затем для версии MERGE_HEAD.

  • Посмотрите на оригиналы. git show :1:имя_файла показывает общего предка, git show :2:имя_файла показывает версию HEAD, а git show :3:имя_файла показывает версию MERGE_HEAD.

ПРИМЕРЫ

  • Выполнить слияние веток fixes и enhancements поверх текущей ветки, создавая слияние octopus:

    $ git merge fixes enhancements
  • Выполнить слияние ветки obsolete в текущую ветку, используя стратегию слияния ours (наша):

    $ git merge -s ours obsolete
  • Выполнить слияние ветки maint в текущую ветку, но не создавать новый коммит автоматически:

    $ git merge --no-commit maint

    Это можно использовать, когда вы хотите включить дополнительные изменения в слияние или написать собственное сообщение коммита слияния.

    Вам следует воздерживаться от злоупотребления этим параметром, чтобы протаскивать существенные изменения в коммит слияния. Небольшие исправления, такие как изменение имени выпуска/версии, будут приемлемы.

Warning

Missing ru/merge-strategies.adoc

See original version for this content.

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

branch.<имя>.mergeOptions

Устанавливает параметры по умолчанию для слияния в ветку <имя>. Синтаксис и поддерживаемые параметры такие же, как в git merge, но значения параметров, содержащие пробельные символы, в настоящее время не поддерживаются.

Дальнейшее содержание этого раздела (в отличие от того, что было описано до данной строки), повторяет то, что может быть найдено в git-config[1]:

merge.conflictStyle

Определяет стиль, в котором конфликтные блоки записываются в файлы рабочего дерева при слиянии. По умолчанию используется «merge», который показывает маркер конфликта <<<<<<<, изменения одной стороны, маркер =======, изменения другой стороны и затем маркер >>>>>>>. Альтернативный стиль «diff3» добавляет маркер ||||||| и исходный текст перед маркером =======. Стиль «merge» обычно создаёт меньшие области конфликта, чем «diff3», как из-за исключения исходного текста, так и потому, что когда подмножество строк совпадает с обеих сторон, они просто выносятся из области конфликта. Ещё один альтернативный стиль, «zdiff3», похож на «diff3», но удаляет совпадающие строки с обеих сторон из области конфликта, когда эти совпадающие строки появляются ближе к началу или концу области конфликта.

merge.defaultToUpstream

Если merge вызывается без аргумента коммита, выполняется слияние вышестоящих веток, настроенных для текущей ветки, с использованием их последних наблюдаемых значений, сохранённых в их удалённых отслеживающих ветках. Используются значения branch.<текущая ветка>.merge, которые называют ветки в удалённом репозитории, указанном в branch.<текущая ветка>.remote, а затем они отображаются через remote.<удалённый>.fetch в соответствующие удалённые отслеживающие ветки, и концы этих отслеживающих веток сливаются. По умолчанию true.

merge.ff

По умолчанию Git не создаёт дополнительный коммит слияния при слиянии коммита, являющегося потомком текущего коммита. Вместо этого конец текущей ветки перемещается вперёд (fast-forward). При установке в false эта переменная указывает Git создать дополнительный коммит слияния в таком случае (эквивалентно передаче опции --no-ff из командной строки). При установке в only разрешены только такие быстрые слияния (эквивалентно передаче параметра --ff-only из командной строки).

merge.verifySignatures

Если true, это эквивалентно опции командной строки --verify-signatures. Подробности см. в git-merge[1].

merge.branchdesc

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

merge.log

Помимо имён веток, заполнять сообщение журнала не более чем указанным количеством однострочных описаний из фактических коммитов, которые сливаются. По умолчанию false, а true является синонимом 20.

merge.suppressDest

Добавляя glob, соответствующий именам веток интеграции, в эту многозначную конфигурационную переменную, стандартное сообщение о слиянии, вычисляемое для слияний в эти ветки интеграции, будет опускать "into <имя-ветки>" из своего заголовка.

Элемент с пустым значением можно использовать для очистки списка glob-ов, накопленных из предыдущих записей конфигурации. Когда переменная merge.suppressDest не определена, для обратной совместимости используется значение по умолчанию master.

merge.renameLimit

Количество файлов для рассмотрения в исчерпывающей части обнаружения переименований во время слияния. Если не указано, по умолчанию используется значение diff.renameLimit. Если не указаны ни merge.renameLimit, ни diff.renameLimit, в настоящее время по умолчанию используется 7000. Этот параметр не действует, если обнаружение переименований отключено.

merge.renames

Должен ли Git находить переименования. При значении false обнаружение переименований отключено. При значении true включено базовое обнаружение переименований. По умолчанию используется значение diff.renames.

merge.directoryRenames

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

false

Обнаружение переименований каталогов отключено, что означает, что такие новые файлы останутся в старом каталоге.

true

Обнаружение переименований каталогов включено, что означает, что такие новые файлы будут перемещены в новый каталог.

conflict

Для таких путей будет сообщён конфликт.

Если merge.renames равно false, merge.directoryRenames игнорируется и трактуется как false. По умолчанию conflict.

merge.renormalize

Сообщает Git, что каноническое представление файлов в репозитории со временем изменилось (например, ранние коммиты записывают текстовые файлы с окончаниями строк CRLF, а более поздние используют LF). В таком репозитории для каждого файла, требующего трёхстороннего слияния содержимого, Git может преобразовать данные, записанные в коммитах, в каноническую форму перед выполнением слияния, чтобы уменьшить количество ненужных конфликтов. Для получения дополнительной информации см. раздел «Слияние веток с различными атрибутами checkin/checkout» в gitattributes[5].

merge.stat

Определяет, что печатать (если вообще что-либо) между ORIG_HEAD и результатом слияния в конце процесса слияния. Возможные значения:

false

Ничего не показывать.

true

Показать git diff --diffstat --summary ORIG_HEAD.

compact

Показать git diff --compact-summary ORIG_HEAD.

но любое нераспознанное значение (например, добавленное будущей версией Git) трактуется как true, а не вызывает ошибку. По умолчанию true.

merge.autoStash

При значении true автоматически создаёт временную запись stash перед началом операции и применяет её после завершения операции. Это позволяет выполнять слияние на грязном рабочем дереве. Однако используйте с осторожностью: финальное применение stash после успешного слияния может привести к непростым конфликтам. Эту опцию можно переопределить с помощью опций --no-autostash и --autostash команды git-merge[1]. По умолчанию false.

merge.tool

Управляет тем, какой инструмент слияния используется git-mergetool[1]. Список ниже показывает допустимые встроенные значения. Любое другое значение трактуется как пользовательский инструмент слияния и требует определения соответствующей переменной mergetool.<инструмент>.cmd.

merge.guitool

Управляет тем, какой инструмент слияния используется git-mergetool[1] при указании флага -g/--gui. Список ниже показывает допустимые встроенные значения. Любое другое значение трактуется как пользовательский инструмент слияния и требует определения соответствующей переменной mergetool.<guitool>.cmd.

Warning

Missing ru/config/{build_dir}/mergetools-merge.adoc

See original version for this content.

merge.verbosity

Управляет объёмом вывода, показываемого рекурсивной стратегией слияния. Уровень 0 не выводит ничего, кроме финального сообщения об ошибке, если обнаружены конфликты. Уровень 1 выводит только конфликты, 2 — конфликты и изменения файлов. Уровень 5 и выше выводит отладочную информацию. По умолчанию используется уровень 2. Может быть переопределено переменной окружения GIT_MERGE_VERBOSITY.

merge.<драйвер>.name

Определяет человекопонятное имя для пользовательского низкоуровневого драйвера слияния. Подробности см. в gitattributes[5].

merge.<драйвер>.driver

Определяет команду, реализующую пользовательский низкоуровневый драйвер слияния. Подробности см. в gitattributes[5].

merge.<драйвер>.recursive

Указывает низкоуровневый драйвер слияния, который будет использоваться при выполнении внутреннего слияния между общими предками. Подробности см. в gitattributes[5].

GIT

Является частью пакета git[1]