Git
日本語 ▾ トピック ▾ 最新バージョン ▾ git-merge-tree の最終更新は 2.46.0 です

名前

git-merge-tree - インデックスまたは作業ツリーに触れずにマージを実行

概要

git merge-tree [--write-tree] [<options>] <branch1> <branch2>
git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2> (deprecated)

説明

このコマンドには、最新の --write-tree モードと、非推奨の --trivial-merge モードがあります。末尾の非推奨の説明セクションを除き、このドキュメントの残りの部分は、最新の --write-tree モードについて説明します。

マージを実行しますが、新しいコミットを作成したり、作業ツリーやインデックスから読み書きしたりしません。

実行されるマージは、「実際の」git-merge[1]と同じ機能を使用します。以下を含みます。

  • 個々のファイルの3方向コンテンツマージ

  • 名前変更検出

  • 適切なディレクトリ/ファイル競合処理

  • 再帰的な祖先統合 (つまり、複数のマージベースがある場合、マージベースをマージして仮想マージベースを作成)

  • など

マージが完了すると、新しいトップレベルのツリーオブジェクトが作成されます。詳細は以下の OUTPUT を参照してください。

オプション

-z

<競合ファイル情報> セクションでファイル名を引用符で囲まず、各ファイル名を改行ではなく NUL 文字で終了します。また、メッセージセクションを改行ではなく NUL 文字で開始します。詳細については、以下の出力を参照してください。

--name-only

競合ファイル情報セクションで、競合したファイルの (モード、OID、ステージ、パス) のタプルのリストを出力する代わりに、競合のあるファイル名のリストのみを提供します (また、複数の競合ステージがある場合は、ファイル名を複数回リストしません)。

--[no-]messages

"Auto-merging <パス>" や CONFLICT 通知などの情報メッセージを標準出力の最後に書き込みます。指定しない場合、デフォルトでは、マージ競合がある場合はこれらのメッセージを含み、それ以外の場合は省略します。

--allow-unrelated-histories

merge-tree はデフォルトで、指定された 2 つのブランチが共通の履歴を共有しない場合にエラーを出します。このフラグを指定すると、そのチェックを上書きして、マージを続行させることができます。

--merge-base=<tree-ish>

<ブランチ1> と <ブランチ2> のマージベースを見つける代わりに、マージのマージベースを指定します。複数のベースの指定は現在サポートされていません。このオプションは --stdin と互換性がありません。

マージベースが直接提供されるため、<ブランチ1> と <ブランチ2> はコミットを指定する必要はありません。ツリーで十分です。

-X<オプション>
--strategy-option=<オプション>

マージ戦略固有のオプションをマージ戦略に渡します。詳細は git-merge[1] を参照してください。

出力

マージが成功した場合、git-merge-tree の出力は単純に 1 行です。

<OID of toplevel tree>

一方、競合のあるマージの場合、出力はデフォルトで次の形式になります。

<OID of toplevel tree>
<Conflicted file info>
<Informational messages>

これらについては、以下で個別に説明します。

ただし、例外があります。--stdin が渡された場合、先頭に追加のセクションがあり、末尾に NUL 文字があり、すべてのセクションが入力行ごとに繰り返されます。したがって、最初のマージが競合し、2 番目のマージがクリーンな場合、出力は次の形式になります。

<Merge status>
<OID of toplevel tree>
<Conflicted file info>
<Informational messages>
NUL
<Merge status>
<OID of toplevel tree>
NUL

マージステータス

これは、NUL 文字が続く整数ステータスです。整数ステータスは次のとおりです。

   0: merge had conflicts
   1: merge was clean
   <0: something prevented the merge from running (e.g. access to repository
objects denied by filesystem)

トップレベルツリーの OID

これは、git merge の最後に作業ツリーにチェックアウトされるものを表すツリーオブジェクトです。競合があった場合、このツリー内のファイルには競合マーカーが埋め込まれている可能性があります。このセクションの後に、常に改行 (または -z が渡された場合は NUL) が続きます。

競合ファイル情報

これは、次の形式の行のシーケンスです。

<mode> <object> <stage> <filename>

ファイル名は、構成変数 core.quotePath ( git-config[1]を参照) で説明されているように引用符で囲まれます。ただし、--name-only オプションが渡された場合、モード、オブジェクト、およびステージは省略されます。-z が渡された場合、「行」は改行文字ではなく NUL 文字で終了します。

情報メッセージ

このセクションでは、通常は競合に関する情報メッセージを提供します。セクションの形式は、-z が渡されたかどうかによって大きく異なります。

-z が渡された場合

出力形式は、0 個以上の競合情報レコードで、それぞれ次の形式です。

<list-of-paths><conflict-type>NUL<conflict-message>NUL

ここで、<パスのリスト> は次の形式です。

<number-of-paths>NUL<path1>NUL<path2>NUL...<pathN>NUL

および <競合メッセージ> で競合または情報メッセージの影響を受けるパス (またはブランチ名) を含みます。また、<競合タイプ> は、次のような競合のタイプを説明する安定した文字列です。

  • "Auto-merging"

  • "CONFLICT (rename/delete)"

  • "CONFLICT (submodule lacks merge base)"

  • "CONFLICT (binary)"

および <競合メッセージ> は、多くの場合 (常にではありませんが)、<安定した短いタイプの説明> を埋め込んだ、競合に関するより詳細なメッセージです。これらの文字列は、将来の Git バージョンで変更される可能性があります。いくつかの例

  • "Auto-merging <file>"

  • "CONFLICT (rename/delete): <oldfile> renamed…​but deleted in…​"

  • "Failed to merge submodule <submodule> (no merge base)"

  • "Warning: cannot merge binary files: <filename>"

-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] と同様に、低レベルのプラミングとして意図されています。したがって、次のような一連の手順の一部として使用できます。

NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2)
test $? -eq 0 || die "There were conflicts..."
NEWCOMMIT=$(git commit-tree $NEWTREE -p $BRANCH1 -p $BRANCH2)
git update-ref $BRANCH1 $NEWCOMMIT

終了ステータスが 0 以外の場合、このシーケンスの NEWTREE には、ツリーだけでなく、さらに多くの出力が含まれることに注意してください。

競合の場合、出力には git-merge[1] で得られる情報と同じ情報が含まれます。

入力形式

git merge-tree --stdin の入力形式は完全にテキストベースです。各行は次の形式です。

[<base-commit> -- ]<branch1> <branch2>

1行が--で区切られている場合、セパレータの前の文字列はマージのベースを指定するために使用され、セパレータの後の文字列はマージするブランチを表します。

避けるべき間違い

競合するファイルを見つけようとして、結果のトップレベルツリーを調べないでください。代わりに、競合ファイル情報セクションを解析してください。大規模なリポジトリでは、ツリー全体を解析するのに非常に時間がかかるだけでなく、競合マーカーで表現できない多数のタイプの競合(変更/削除、モードの競合、両側で変更されたバイナリファイル、ファイル/ディレクトリの競合、さまざまなリネーム競合の順列など)があります。

空の競合ファイル情報リストをクリーンなマージと解釈しないでください。終了ステータスを確認してください。マージは、個々のファイルが競合していなくても競合を持つ可能性があります(このカテゴリに該当するいくつかのディレクトリリネーム競合があり、将来的に追加される可能性もあります)。

競合ファイル情報リストから競合の種類を推測したり、ユーザーに推測させようとしないでください。そこにある情報はそれを行うには不十分です。例:リネーム/リネーム(1to2)競合(両側が同じファイルを異なる名前にリネームした場合)は、3つの異なるファイルが上位ステージを持つことになります(ただし、それぞれが1つの上位ステージのみを持ちます)。どの3つのファイルが関連しているかを(情報メッセージセクション以外に)特定する方法はありません。ファイル/ディレクトリの競合も、上位ステージが1つだけであるファイルになります。ディレクトリリネームに関連する可能性のある競合("merge.directoryRenames"が設定されていないか、"conflicts"に設定されている場合)も、上位ステージが1つだけであるファイルになります。すべての場合において、情報メッセージセクションには必要な情報がありますが、機械で解析できるように設計されていません。

競合ファイル情報からの各パスと、情報メッセージ内の論理的な競合が1対1でマッピングされると想定しないでください。1対多のマッピングでも、多対1のマッピングでもありません。多対多のマッピングが存在し、各パスは1つのマージで多くの論理的な競合タイプを持つことができ、各論理的な競合タイプは多くのパスに影響を与える可能性があります。

情報メッセージセクションにリストされているすべてのファイル名が競合を持つと想定しないでください。メッセージには、"Auto-merging <file>"など、競合のないファイルも含まれる場合があります。

競合ファイル情報からOIDを取得し、それらを再度マージしてユーザーに競合を提示することを避けてください。これにより、情報が失われます。代わりに、トップレベルツリーのOID内にあるファイルのバージョンを調べて、代わりにそれを表示してください。特に、後者にはマージされている元のブランチ/コミットで注釈が付けられた競合マーカーがあり、リネームが関与している場合は、元のファイル名があります。再マージ時に競合マーカーの注釈に元のブランチ/コミットを含めることはできますが、元のファイル名は競合ファイル情報からは利用できないため、ユーザーが競合を解決するのに役立つ可能性のある情報を失うことになります。

非推奨の説明

説明に従い、このドキュメントの他の部分とは異なり、このセクションでは非推奨の--trivial-mergeモードについて説明します。

オプションの--trivial-mergeを除き、このモードはオプションを受け付けません。

このモードは3つのツリー風のものを読み取り、自明なマージ結果と競合するステージを標準出力にセミdiff形式で出力します。これは、上位レベルのスクリプトが結果を消費してインデックスにマージするように設計されているため、<branch1>と一致するエントリは省略されます。この2番目の形式の結果は、3方向のgit read-tree -mが行うことと似ていますが、結果をインデックスに格納する代わりに、コマンドはエントリを標準出力に出力します。

この形式は、適用範囲が限定的であるだけでなく(自明なマージは個々のファイルの内容のマージ、リネーム検出、適切なディレクトリ/ファイル競合処理などを処理できません)、出力形式も扱いにくく、一般的に成功したマージでも(特に大規模なリポジトリで作業している場合は)最初の形式よりもパフォーマンスが低くなります。

GIT

git[1]スイートの一部

scroll-to-top