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

НАЗВАНИЕ

git-merge-tree — Выполнить слияние без касания индекса или рабочего каталога

ОБЗОР

git merge-tree [--write-tree] [<параметры>] <ветка1> <ветка2>
git merge-tree [--trivial-merge] <базовое-дерево> <ветка1> <ветка2> (устарело)

ОПИСАНИЕ

Эта команда имеет современный режим --write-tree и устаревший режим --trivial-merge. За исключением раздела УСТАРЕВШЕЕ ОПИСАНИЕ в конце, остальная часть этой документации описывает современный режим --write-tree.

Выполняет слияние, но не создаёт никаких новых коммитов и не читает из рабочего каталога или индекса и не записывает в них.

Выполняемое слияние будет использовать те же функции, что и "настоящее" git-merge[1], включая:

  • трёхходовое слияние содержимого отдельных файлов

  • обнаружение переименований

  • правильную обработку конфликтов каталог/файл

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

  • и т.д.

После завершения слияния создаётся новый объект дерева верхнего уровня. Подробности см. в разделе ВЫВОД ниже.

ПАРАМЕТРЫ

--stdin

Читать коммиты для слияния из стандартного ввода, а не из командной строки. Дополнительную информацию см. в разделе ФОРМАТ ВВОДА ниже. Подразумевает -z.

-z

Не заключать имена файлов в кавычки в разделе <Информация о конфликтующих файлах> и завершать каждое имя файла символом NUL вместо символа новой строки. Также начинать раздел сообщений с символа NUL вместо символа новой строки. Дополнительную информацию см. в разделе ВЫВОД ниже.

--name-only

В разделе информации о конфликтующих файлах вместо вывода списка кортежей (режим, oid, стадия, путь) для конфликтующих файлов просто предоставить список имён файлов с конфликтами (и не перечислять имена файлов несколько раз, если они имеют несколько конфликтующих стадий).

--messages
--no-messages

Записывать любые информационные сообщения, такие как "Auto-merging <путь>" или уведомления о КОНФЛИКТАХ, в конец stdout. Если не указано, по умолчанию эти сообщения включаются, если есть конфликты слияния, и опускаются в противном случае.

--quiet

Отключает весь вывод программы. Полезно, когда вас интересует только статус выхода. Позволяет merge-tree завершиться досрочно при обнаружении конфликта и избежать записи большинства объектов, созданных слияниями.

--allow-unrelated-histories

merge-tree по умолчанию завершится ошибкой, если указанные две ветки не имеют общей истории. Этот флаг можно указать, чтобы переопределить эту проверку и всё равно выполнить слияние.

--merge-base=<указатель дерева>

Вместо поиска основ слияния для <ветка1> и <ветка2> указать основу слияния для слияния. Этот параметр несовместим с --stdin.

Указание нескольких основ в настоящее время не поддерживается, что означает, что при слиянии двух веток с более чем одной основой слияния использование этого параметра может привести к результатам слияния, отличным от тех, которые вычислил бы git merge. Это может включать потенциальную потерю некоторых изменений, сделанных на одной стороне истории, в результирующем слиянии.

С этим параметром, поскольку основа слияния предоставляется непосредственно, <ветка1> и <ветка2> не должны указывать коммиты; достаточно деревьев.

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

Передать параметр, специфичный для стратегии слияния, самой стратегии слияния. Подробности см. в git-merge[1].

ВЫВОД

Для успешного слияния вывод git-merge-tree представляет собой просто одну строку:

<OID дерева верхнего уровня>

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

<OID дерева верхнего уровня>
<Информация о конфликтующих файлах>
<Информационные сообщения>

Они обсуждаются по отдельности ниже.

Однако есть исключение. Если передан --stdin, то в начале есть дополнительный раздел, символ NUL в конце, а затем все разделы повторяются для каждой строки ввода. Таким образом, если первое слияние конфликтующее, а второе чистое, вывод будет иметь вид:

<Статус слияния>
<OID дерева верхнего уровня>
<Информация о конфликтующих файлах>
<Информационные сообщения>
NUL
<Статус слияния>
<OID дерева верхнего уровня>
NUL

Состояние слияния

Это целочисленный статус, за которым следует символ NUL. Целочисленный статус:

0: слияние имело конфликты
1: слияние было чистым

OID дерева верхнего уровня

Это объект дерева, который представляет то, что было бы переключено в рабочем каталоге в конце git merge. Если были конфликты, то файлы внутри этого дерева могут содержать встроенные маркеры конфликта. За этим разделом всегда следует символ новой строки (или NUL, если передан -z).

Информация о конфликтующих файлах

Это последовательность строк формата

<режим> <объект> <стадия> <имя-файла>

Имя файла будет заключено в кавычки, как объяснено для переменной конфигурации core.quotePath (см. git-config[1]). Однако если передан параметр --name-only, режим, объект и стадия будут опущены. Если передан -z, "строки" завершаются символом NUL вместо символа новой строки.

Информационные сообщения

Этот раздел предоставляет информационные сообщения, обычно о конфликтах. Формат раздела значительно различается в зависимости от того, передан ли -z.

Если передан -z:

Формат вывода представляет собой ноль или более информационных записей о конфликтах, каждая вида:

<список-путей><тип-конфликта>NUL<сообщение-конфликта>NUL

где <список-путей> имеет вид

<количество-путей>NUL<путь1>NUL<путь2>NUL...<путьN>NUL

и включает пути (или имена веток), затронутые конфликтом или информационным сообщением в <сообщение-конфликта>. Кроме того, <тип-конфликта> — это стабильная строка, объясняющая тип конфликта, например

  • "Auto-merging"

  • "CONFLICT (rename/delete)"

  • "CONFLICT (submodule lacks merge base)"

  • "CONFLICT (binary)"

а <сообщение-конфликта> — это более подробное сообщение о конфликте, которое часто (но не всегда) содержит <краткое-стабильное-описание-типа> внутри себя. Эти строки могут измениться в будущих версиях Git. Некоторые примеры:

  • "Auto-merging <файл>"

  • "CONFLICT (rename/delete): <старый-файл> переименован…​но удалён в…​"

  • "Failed to merge submodule <подмодуль> (no merge base)"

  • "Warning: cannot merge binary files: <имя-файла>"

Если -z НЕ передан:

Этот раздел начинается с пустой строки, чтобы отделить его от предыдущих разделов, а затем содержит только информацию <сообщение-конфликта> из предыдущего раздела (разделённую символами новой строки). Это нестабильные строки, которые не должны анализироваться сценариями и предназначены только для чтения человеком. Также обратите внимание, что хотя строки <сообщение-конфликта> обычно не содержат встроенных символов новой строки, иногда они их содержат. (Однако свободные сообщения никогда не будут содержать встроенный символ NUL). Таким образом, весь блок информации предназначен для читателей-людей как агломерация всех сообщений о конфликтах.

КОД ЗАВЕРШЕНИЯ

Для успешного, неконфликтующего слияния статус выхода равен 0. Когда слияние имеет конфликты, статус выхода равен 1. Если слияние не может быть завершено (или начато) из-за какой-либо ошибки, статус выхода отличен от 0 или 1 (и вывод не определён). Когда передан --stdin, статус возврата равен 0 как для успешных, так и для конфликтующих слияний, и отличен от 0 или 1, если не может завершить все запрошенные слияния.

ЗАМЕЧАНИЯ ПО ИСПОЛЬЗОВАНИЮ

Эта команда предназначена как низкоуровневый внутренний интерфейс, аналогичный git-hash-object[1], git-mktree[1], git-commit-tree[1], git-write-tree[1], git-update-ref[1] и git-mktag[1]. Таким образом, она может использоваться как часть серии шагов, например:

vi message.txt
ВЕТКА1=refs/heads/test
ВЕТКА2=main
НОВОЕ_ДЕРЕВО=$(git merge-tree --write-tree $ВЕТКА1 $ВЕТКА2) || {
    echo "Были конфликты..." 1>&2
    exit 1
}
НОВЫЙ_КОММИТ=$(git commit-tree $НОВОЕ_ДЕРЕВО -F message.txt \
    -p $ВЕТКА1 -p $ВЕТКА2)
git update-ref $ВЕТКА1 $НОВЫЙ_КОММИТ

Обратите внимание, что когда статус выхода ненулевой, НОВОЕ_ДЕРЕВО в этой последовательности будет содержать гораздо больше вывода, чем просто дерево.

При конфликтах вывод включает ту же информацию, которую вы получили бы с git-merge[1]:

ФОРМАТ ВВОДА

Формат ввода git merge-tree --stdin полностью основан на тексте. Каждая строка имеет следующий формат:

[<базовый-коммит> -- ]<ветка1> <ветка2>

Если строка разделена --, строка перед разделителем используется для указания основы слияния для слияния, а строка после разделителя описывает ветки, которые должны быть слиты.

ОШИБКИ, КОТОРЫХ СЛЕДУЕТ ИЗБЕГАТЬ

НЕ просматривайте результирующее дерево верхнего уровня, пытаясь найти, какие файлы конфликтуют; вместо этого анализируйте раздел Информация о конфликтующих файлах. Анализ всего дерева был бы ужасно медленным в больших репозиториях, и существуют многочисленные типы конфликтов, которые не могут быть представлены маркерами конфликта (изменение/удаление, конфликт режима, двоичный файл изменён с обеих сторон, конфликты файл/каталог, различные перестановки конфликтов переименования и т.д.)

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

НЕ пытайтесь угадать или заставить пользователя угадывать типы конфликтов из списка Информация о конфликтующих файлах. Информации там недостаточно для этого. Например: конфликты Переименования/переименования (1 в 2) (обе стороны переименовали один и тот же файл по-разному) приведут к тому, что три разных файла будут иметь стадии более высокого порядка (но каждый имеет только одну стадию более высокого порядка), и не будет способа (кроме раздела Информационные сообщения) определить, какие три файла связаны. Конфликты файл/каталог также приводят к файлу ровно с одной стадией более высокого порядка. Конфликты, возможно связанные с переименованием каталога (когда «merge.directoryRenames» не установлен или установлен в «conflicts»), также приводят к файлу ровно с одной стадией более высокого порядка. Во всех случаях раздел Информационные сообщения содержит необходимую информацию, хотя он не предназначен для машинного анализа.

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

НЕ предполагайте, что все имена файлов, перечисленные в разделе Информационные сообщения, имели конфликты. Сообщения могут быть включены для файлов, у которых нет конфликтов, например "Auto-merging <файл>".

ИЗБЕГАЙТЕ брать OID из Информация о конфликтующих файлах и повторно сливать их, чтобы представить конфликты пользователю. Это приведёт к потере информации. Вместо этого найдите версию файла, найденную в OID дерева верхнего уровня, и покажите её. В частности, последняя будет иметь маркеры конфликта, аннотированные исходной веткой/коммитом, которые сливаются, и, если были задействованы переименования, исходное имя файла. Хотя вы могли бы включить исходную ветку/коммит в аннотации маркеров конфликта при повторном слиянии, исходное имя файла недоступно из Информация о конфликтующих файлах, и, таким образом, вы потеряете информацию, которая могла бы помочь пользователю разрешить конфликт.

УСТАРЕВШЕЕ ОПИСАНИЕ

Согласно ОПИСАНИЮ и в отличие от остальной части этой документации, этот раздел описывает устаревший режим --trivial-merge.

Кроме необязательного --trivial-merge, этот режим не принимает никаких параметров.

Этот режим читает три указателя дерева и выводит тривиальные результаты слияния и конфликтующие стадии в стандартный вывод в полуформате сравнения. Поскольку это было разработано для того, чтобы высокоуровневые сценарии могли потреблять и сливать результаты обратно в индекс, он опускает записи, соответствующие <ветка1>. Результат этой второй формы аналогичен тому, что делает трёхходовой git read-tree -m, но вместо сохранения результатов в индексе команда выводит записи в стандартный вывод.

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

GIT

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