English ▾ Themen ▾ Neueste Version ▾ git-merge-tree zuletzt aktualisiert in 2.52.0

NAME

git-merge-tree - Merge durchführen, ohne Index oder Arbeitsverzeichnis zu berühren

SYNOPSIS

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

BESCHREIBUNG

Dieser Befehl hat einen modernen Modus --write-tree und einen veralteten Modus --trivial-merge. Mit Ausnahme des Abschnitts VERALTETE BESCHREIBUNG am Ende beschreibt der Rest dieser Dokumentation den modernen Modus --write-tree.

Führt einen Merge durch, erstellt jedoch keine neuen Commits und liest weder aus dem Arbeitsverzeichnis noch in dieses, noch liest es aus dem Index oder schreibt in diesen.

Der durchgeführte Merge verwendet die gleichen Funktionen wie der "echte" git-merge[1], einschließlich

  • Drei-Wege-Inhalts-Merges einzelner Dateien

  • Namenserkennung

  • korrekte Handhabung von Verzeichnis-/Datei-Konflikten

  • rekonsolidierung von gemeinsamen Vorfahren (d.h. wenn es mehr als eine Merge-Basis gibt, Erstellung einer virtuellen Merge-Basis durch Zusammenführen der Merge-Basen)

  • usw.

Nach Abschluss des Merges wird ein neues Top-Level-Tree-Objekt erstellt. Details finden Sie in AUSGABE unten.

OPTIONEN

--stdin

Liest die zu mergenden Commits von der Standardeingabe anstatt von der Befehlszeile. Siehe EINGABEFORMAT unten für weitere Informationen. Impliziert -z.

-z

Dateinamen im Abschnitt <Conflicted file info> nicht quotieren und jeden Dateinamen mit einem NUL-Zeichen statt einem Zeilenumbruch beenden. Beginnen Sie auch den Nachrichtenabschnitt mit einem NUL-Zeichen anstelle eines Zeilenumbruchs. Siehe AUSGABE unten für weitere Informationen.

--name-only

Schreiben Sie im Abschnitt "Conflicted file info" anstelle einer Liste von (Modus, OID, Stage, Pfad)-Tupeln für konflikthafte Dateien nur eine Liste von Dateinamen mit Konflikten (und listen Sie Dateinamen nicht mehrmals auf, wenn sie mehrere konflikthafte Stages haben).

--messages
--no-messages

Schreibt alle informativen Meldungen wie "Auto-merging <path>" oder KONFLIKT-Hinweise am Ende von stdout. Wenn nicht angegeben, werden diese Meldungen standardmäßig eingeschlossen, wenn es Konflikte gibt, und ansonsten weggelassen.

--quiet

Deaktiviert die gesamte Ausgabe des Programms. Nützlich, wenn Sie nur am Exit-Status interessiert sind. Ermöglicht merge-tree, frühzeitig zu beenden, wenn ein Konflikt gefunden wird, und vermeidet das Schreiben der meisten Objekte, die durch Merges erstellt werden.

--allow-unrelated-histories

merge-tree wird standardmäßig einen Fehler ausgeben, wenn die beiden angegebenen Branches keine gemeinsame Historie teilen. Dieses Flag kann angegeben werden, um diese Prüfung zu überschreiben und den Merge trotzdem fortzusetzen.

--merge-base=<tree-ish>

Anstatt die Merge-Basen für <branch1> und <branch2> zu finden, geben Sie eine Merge-Basis für den Merge an. Diese Option ist inkompatibel mit --stdin.

Die Angabe mehrerer Basen wird derzeit nicht unterstützt, was bedeutet, dass bei der Zusammenführung zweier Branches mit mehr als einer Merge-Basis die Verwendung dieser Option dazu führen kann, dass die Merge-Ergebnisse von dem abweichen, was git merge berechnen würde. Dies kann den potenziellen Verlust einiger Änderungen auf einer Seite der Historie im resultierenden Merge einschließen.

Mit dieser Option, da die Merge-Basis direkt angegeben wird, müssen <branch1> und <branch2> keine Commits angeben; Trees reichen aus.

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

Übergibt die strategie-spezifische Merge-Option an die Merge-Strategie. Details finden Sie in git-merge[1].

AUSGABE

Bei einem erfolgreichen Merge besteht die Ausgabe von git-merge-tree einfach aus einer Zeile

<OID of toplevel tree>

Bei einem konflikthaltigen Merge hat die Ausgabe standardmäßig die Form

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

Diese werden einzeln unten besprochen.

Es gibt jedoch eine Ausnahme. Wenn --stdin übergeben wird, gibt es einen zusätzlichen Abschnitt am Anfang, ein NUL-Zeichen am Ende und dann wiederholen sich alle Abschnitte für jede Eingabezeile. Wenn also der erste Merge konflikthaltig und der zweite sauber ist, wäre die Ausgabe von der Form

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

Merge-Status

Dies ist ein Integer-Status gefolgt von einem NUL-Zeichen. Der Integer-Status ist

0: merge had conflicts
1: merge was clean

OID des Top-Level-Trees

Dies ist ein Tree-Objekt, das repräsentiert, was am Ende von git merge im Arbeitsverzeichnis ausgecheckt würde. Wenn es Konflikte gab, können Dateien innerhalb dieses Trees eingebettete Konfliktmarker enthalten. Dieser Abschnitt wird immer von einem Zeilenumbruch gefolgt (oder NUL, wenn -z übergeben wird).

Informationen zu konflikthaltigen Dateien

Dies ist eine Sequenz von Zeilen im Format

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

Der Dateiname wird wie für die Konfigurationsvariable core.quotePath erklärt zitiert (siehe git-config[1]). Wenn jedoch die Option --name-only übergeben wird, werden Modus, Objekt und Stage weggelassen. Wenn -z übergeben wird, werden die "Zeilen" anstelle eines Zeilenumbruchs mit einem NUL-Zeichen beendet.

Informationsmeldungen

Dieser Abschnitt liefert informative Meldungen, typischerweise über Konflikte. Das Format des Abschnitts variiert erheblich je nachdem, ob -z übergeben wird.

Wenn -z übergeben wird

Das Ausgabeformat sind null oder mehr Konflikt-Informationsdatensätze, jeder im Format

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

wobei <list-of-paths> vom Format ist

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

und Pfade (oder Branch-Namen) enthält, die vom Konflikt oder der Informationsmeldung in <conflict-message> betroffen sind. Außerdem ist <conflict-type> ein stabiler String, der die Art des Konflikts erklärt, wie z.B.

  • "Auto-merging"

  • "CONFLICT (rename/delete)"

  • "CONFLICT (submodule lacks merge base)"

  • "CONFLICT (binary)"

und <conflict-message> ist eine detailliertere Meldung über den Konflikt, die oft (aber nicht immer) die <stable-short-type-description> enthält. Diese Strings können sich in zukünftigen Git-Versionen ändern. Einige Beispiele

  • "Auto-merging <file>"

  • "CONFLICT (rename/delete): <oldfile> umbenannt…​aber gelöscht in…​"

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

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

Wenn -z NICHT übergeben wird

Dieser Abschnitt beginnt mit einer Leerzeile, um ihn von den vorherigen Abschnitten zu trennen, und enthält dann nur die <conflict-message>-Informationen aus dem vorherigen Abschnitt (durch Zeilenumbrüche getrennt). Dies sind nicht-stabile Strings, die nicht von Skripten geparst werden sollten und nur für menschliche Leser bestimmt sind. Beachten Sie auch, dass <conflict-message>-Strings normalerweise keine eingebetteten Zeilenumbrüche enthalten, aber manchmal tun sie das. (Die frei formatierten Meldungen enthalten jedoch niemals ein eingebettetes NUL-Zeichen.) Daher ist der gesamte Informationsblock für menschliche Leser als Agglomeration aller Konfliktmeldungen gedacht.

BEENDIGUNGSSTATUS

Für einen erfolgreichen, nicht konflikthaltigen Merge ist der Exit-Status 0. Wenn der Merge Konflikte aufweist, ist der Exit-Status 1. Wenn der Merge aufgrund eines Fehlers nicht abgeschlossen werden kann (oder gestartet werden kann), ist der Exit-Status etwas anderes als 0 oder 1 (und die Ausgabe ist undefiniert). Wenn --stdin übergeben wird, ist der Rückgabestatus 0 sowohl für erfolgreiche als auch für konflikthaltige Merges, und etwas anderes als 0 oder 1, wenn nicht alle angeforderten Merges abgeschlossen werden können.

HINWEISE ZUR VERWENDUNG

Dieser Befehl ist als Low-Level-Plumbing gedacht, ähnlich wie git-hash-object[1], git-mktree[1], git-commit-tree[1], git-write-tree[1], git-update-ref[1] und git-mktag[1]. Daher kann er als Teil einer Schrittfolge verwendet werden, wie z.B.

vi message.txt
BRANCH1=refs/heads/test
BRANCH2=main
NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) || {
    echo "There were conflicts..." 1>&2
    exit 1
}
NEWCOMMIT=$(git commit-tree $NEWTREE -F message.txt \
    -p $BRANCH1 -p $BRANCH2)
git update-ref $BRANCH1 $NEWCOMMIT

Beachten Sie, dass bei einem nicht-null Exit-Status NEWTREE in dieser Sequenz mehr als nur einen Tree enthalten wird.

Für Konflikte enthält die Ausgabe die gleichen Informationen, die Sie mit git-merge[1] erhalten würden

EINGABEFORMAT

Das Eingabeformat von *git merge-tree --stdin* ist vollständig textbasiert. Jede Zeile hat dieses Format

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

Wenn eine Zeile durch -- getrennt ist, wird der String vor dem Trennzeichen zur Angabe einer Merge-Basis für den Merge verwendet und der String danach beschreibt die zu mergenden Branches.

ZU VERMEIDENDE FEHLER

Schauen Sie NICHT durch den resultierenden Top-Level-Tree, um zu versuchen, welche Dateien in Konflikt stehen; parsen Sie stattdessen den Abschnitt Informationen zu konflikthaltigen Dateien. Nicht nur wäre das Parsen eines gesamten Trees in großen Repositories extrem langsam, sondern es gibt auch zahlreiche Arten von Konflikten, die nicht durch Konfliktmarker darstellbar sind (Änderung/Löschung, Modus-Konflikt, Binärdatei auf beiden Seiten geändert, Datei/Verzeichnis-Konflikte, verschiedene Umbenennungs-Konflikt-Permutationen usw.).

Interpretieren Sie eine leere Liste von Informationen zu konflikthaltigen Dateien NICHT als sauberen Merge; überprüfen Sie den Exit-Status. Ein Merge kann Konflikte haben, ohne dass einzelne Dateien kollidieren (es gibt einige Arten von Verzeichnis-Umbenennungskonflikten, die in diese Kategorie fallen, und andere könnten in Zukunft hinzugefügt werden).

Versuchen Sie NICHT, die Konflikttypen aus der Liste Informationen zu konflikthaltigen Dateien zu erraten oder den Benutzer raten zu lassen. Die Informationen dort reichen dafür nicht aus. Zum Beispiel: Umbenennung/Umbenennung(1zu2)-Konflikte (beide Seiten haben dieselbe Datei unterschiedlich umbenannt) führen zu drei verschiedenen Dateien mit höherrangigen Stages (aber jede hat nur eine höherrangige Stage), ohne Möglichkeit (außer dem Abschnitt Informationsmeldungen), festzustellen, welche drei Dateien zusammenhängen. Datei/Verzeichnis-Konflikte führen ebenfalls zu einer Datei mit genau einer höherrangigen Stage. Möglicherweise an Verzeichnis-Umbenennungen beteiligte Konflikte (wenn "merge.directoryRenames" nicht gesetzt oder auf "conflicts" gesetzt ist) führen ebenfalls zu einer Datei mit genau einer höherrangigen Stage. In allen Fällen enthält der Abschnitt Informationsmeldungen die notwendigen Informationen, obwohl er nicht für maschinelles Parsen ausgelegt ist.

Gehen Sie NICHT davon aus, dass jeder Pfad aus Informationen zu konflikthaltigen Dateien und die logischen Konflikte in den Informationsmeldungen eine Eins-zu-Eins-Zuordnung haben, noch dass es eine Eins-zu-Viele- oder Viele-zu-Eins-Zuordnung gibt. Es gibt viele-zu-viele-Zuordnungen, was bedeutet, dass jeder Pfad viele logische Konflikttypen in einem einzigen Merge haben kann und jeder logische Konflikttyp viele Pfade betreffen kann.

Gehen Sie NICHT davon aus, dass alle im Abschnitt Informationsmeldungen aufgeführten Dateinamen Konflikte hatten. Meldungen können für Dateien eingeschlossen werden, die keine Konflikte haben, wie z.B. "Auto-merging <file>".

VERMEIDEN Sie es, die OIDs aus den Informationen zu konflikthaltigen Dateien zu nehmen und sie neu zu mergen, um die Konflikte dem Benutzer zu präsentieren. Dies würde Informationen verlieren. Suchen Sie stattdessen die Version der Datei im OID des Top-Level-Trees und zeigen Sie diese stattdessen an. Insbesondere letztere enthält Konfliktmarker, die mit dem ursprünglichen Branch/Commit, der gemerged wird, und, falls Umbenennungen beteiligt waren, dem ursprünglichen Dateinamen annotiert sind. Obwohl Sie den ursprünglichen Branch/Commit in den Konfliktmarker-Annotationen beim Neumengen einschließen könnten, ist der ursprüngliche Dateiname nicht aus den Informationen zu konflikthaltigen Dateien verfügbar und Sie würden somit Informationen verlieren, die dem Benutzer bei der Behebung des Konflikts helfen könnten.

VERALTETE BESCHREIBUNG

Gemäß BESCHREIBUNG und im Gegensatz zum Rest dieser Dokumentation beschreibt dieser Abschnitt den veralteten Modus --trivial-merge.

Abgesehen von der optionalen --trivial-merge akzeptiert dieser Modus keine Optionen.

Dieser Modus liest drei Tree-ishs und gibt triviale Merge-Ergebnisse und konfliktäre Stages in einem Semi-Diff-Format auf der Standardausgabe aus. Da dies für höherrangige Skripte konzipiert wurde, um die Ergebnisse zu konsumieren und zurück in den Index zu mergen, werden Einträge, die mit <branch1> übereinstimmen, weggelassen. Das Ergebnis dieser zweiten Form ähnelt dem, was drei-Wege *git read-tree -m* tut, aber anstatt die Ergebnisse im Index zu speichern, gibt der Befehl die Einträge auf der Standardausgabe aus.

Diese Form hat nicht nur eine begrenzte Anwendbarkeit (ein trivialer Merge kann keine Inhaltsmerges einzelner Dateien, keine Namenserkennung, keine korrekte Handhabung von Verzeichnis-/Datei-Konflikten usw. bewältigen), sondern das Ausgabeformat ist auch schwierig zu handhaben, und es wird im Allgemeinen langsamer sein als die erste Form, selbst bei erfolgreichen Merges (besonders beim Arbeiten in großen Repositories).

GIT

Teil der git[1] Suite