509 Stimmen

Wie kann ich eine Vorschau einer Zusammenführung in Git anzeigen?

Ich habe einen Git-Zweig (z. B. den Hauptzweig) und möchte einen anderen Entwicklungszweig einbinden. Oder muss ich das?

Um zu entscheiden, ob ich diesen Zweig wirklich zusammenführen möchte, würde ich gerne eine Art Vorschau sehen, was die Zusammenführung bewirken wird. Vorzugsweise mit der Möglichkeit, die Liste der Commits zu sehen, die angewendet werden.

Bislang ist das Beste, was mir einfällt merge --no-ff --no-commit und dann diff HEAD .

22 Stimmen

Ich würde nur git merge y git reset --keep HEAD@{1} wenn mir das Ergebnis nicht gefällt.

4 Stimmen

Beachten Sie, dass die Liste der Commits mit ihrem Diff nicht notwendigerweise die ganze Geschichte erzählt - wenn die Zusammenführung nicht trivial ist, und besonders wenn es Konflikte gibt, könnte das tatsächliche Ergebnis der Zusammenführung ein wenig interessant sein.

0 Stimmen

Das Problem dabei ist, dass man nur schwer erkennen kann, welche Änderungen tatsächlich vorgenommen wurden.

520voto

Jan Hudec Punkte 69126
  • git log ..otherbranch
    • Liste der Änderungen, die in den aktuellen Zweig übernommen werden.
  • git diff ...otherbranch
    • diff vom gemeinsamen Vorgänger (Merge-Basis) bis zum Kopf dessen, was zusammengeführt werden soll. Beachten Sie die drei Punkte , die im Vergleich zu zwei Punkten eine besondere Bedeutung haben (siehe unten).
  • gitk ...otherbranch
    • grafische Darstellung der Zweige seit der letzten Zusammenführung.

Leere Zeichenfolge impliziert HEAD und deshalb nur ..otherbranch anstelle von HEAD..otherbranch .

Die zwei bzw. drei Punkte haben für diff eine etwas andere Bedeutung als für die Befehle, die Revisionen auflisten (log, gitk usw.). Für log und andere haben zwei Punkte ( a..b ) bedeutet alles, was in b aber nicht a und drei Punkte ( a...b ) bedeutet alles, was nur in einer der folgenden Kategorien enthalten ist a o b . Aber diff arbeitet mit zwei Revisionen und dort mit dem einfacheren Fall, der durch zwei Punkte ( a..b ) ist der einfache Unterschied zu a a b und drei Punkte ( a...b ) mittlere Differenz zwischen gemeinsamem Vorfahren und b ( git diff $(git merge-base a b)..b ).

10 Stimmen

Der dritte Punkt war der Teil, der mir fehlte, danke! Der Log-Ansatz funktioniert auch gut, log -p --reverse ..otherbranch scheint ein guter Weg zu sein, um zu sehen, was zusammengeführt werden würde.

1 Stimmen

Ich vermisste git checkout master bevor ich das hier ausprobiert habe. Ich habe mich gefragt, warum es hieß, dass alle meine Änderungen überschrieben werden würden...

10 Stimmen

git show ..otherbranch zeigt eine Liste der Änderungen und Diffs, die in den aktuellen Zweig eingefügt werden.

347voto

Kasapo Punkte 5154

Ich habe festgestellt, dass die beste Lösung für mich darin besteht, dass ich einfach die Zusammenführung durchführen und bei Konflikten abbrechen . Diese spezielle Syntax erscheint mir sauber und einfach. Dies ist Strategie 2 unten.

Wenn Sie jedoch sicherstellen wollen, dass Sie Ihren aktuellen Zweig nicht durcheinander bringen, oder wenn Sie einfach nicht bereit sind, unabhängig von der Existenz von Konflikten zusammenzuführen, erstellen Sie einfach einen neuen Unterzweig davon und führen diesen zusammen:

Strategie 1: Der sichere Weg - Zusammenführen aus einem temporären Zweig:

git checkout mybranch
git checkout -b mynew-temporary-branch
git merge some-other-branch

Auf diese Weise können Sie den temporären Zweig einfach wegwerfen, wenn Sie nur sehen wollen, wo die Konflikte liegen. Sie müssen sich nicht die Mühe machen, die Zusammenführung "abzubrechen", und Sie können zu Ihrer Arbeit zurückkehren - checken Sie einfach "mybranch" wieder aus und Sie werden keinen zusammengeführten Code oder Konflikte in Ihrem Zweig haben.

Dies ist im Grunde ein Probelauf.

Strategie 2: Wenn Sie unbedingt fusionieren wollen, aber nur, wenn es keine Konflikte gibt

git checkout mybranch
git merge some-other-branch

Wenn git Konflikte meldet (und NUR WENN ES Konflikte) können Sie dann tun:

git merge --abort

Wenn die Zusammenführung erfolgreich ist, können Sie sie nicht abbrechen (nur zurücksetzen).

Wenn Sie noch nicht bereit sind, zu fusionieren, verwenden Sie den oben beschriebenen sichereren Weg.

[EDIT: 2016-Nov - Ich habe Strategie 1 gegen 2 ausgetauscht, da es scheint, dass die meisten Leute nach dem "sicheren Weg" suchen. Strategie 2 ist jetzt eher ein Hinweis darauf, dass man die Zusammenführung einfach abbrechen kann, wenn die Zusammenführung Konflikte hat, mit denen man nicht umgehen kann. Denken Sie daran, wenn Sie Kommentare lesen!]

3 Stimmen

+1 für Strategie 2: Temporärer Zweig, der genau zeigt, was beim Zusammenführen hineingehen wird. Strategie 1 ist, was ich versuche, für diesen speziellen Fall zu vermeiden.

3 Stimmen

Ich schlage vor, die Strategien so zu ändern, dass die sicherere zuerst kommt (hier kommt meine psychologische Ausbildung zum Vorschein - die meisten Leute würden annehmen, dass die beste Option die erste ist, trotz der eindeutigen Verwendung des Wortes "sicherer"), aber abgesehen davon, ausgezeichnete Arbeit.

11 Stimmen

Sie könnten eine git merge --no-ff --no-commit wenn Sie die Änderungen nicht direkt übertragen wollen. Dadurch entfällt die "Notwendigkeit" für einen anderen Zweig, was die Überprüfung der Änderungen ein klein wenig einfacher macht, wie ich finde.

28voto

hraban Punkte 1587

Die meisten Antworten hier erfordern entweder ein sauberes Arbeitsverzeichnis und mehrere interaktive Schritte (schlecht für Skripte), oder sie funktionieren nicht in allen Fällen, z.B. bei vergangenen Merges, die bereits einige der ausstehenden Änderungen in den Zielzweig bringen, oder bei Cherry-Picks, die dasselbe tun.

Um wirklich zu sehen, was sich in der master Zweig, wenn Sie zusammengeführt haben develop und zwar jetzt sofort:

git merge-tree $(git merge-base master develop) master develop

Da es sich um einen Klempnerbefehl handelt, kann er nicht erraten, was Sie meinen, Sie müssen es explizit sagen. Außerdem wird die Ausgabe nicht eingefärbt oder Ihr Pager verwendet, so dass der vollständige Befehl lauten würde:

git merge-tree $(git merge-base master develop) master develop | colordiff | less -R

- https://git.seveas.net/previewing-a-merge-result.html

(Dank an David Normington für den Link)

P.S.:

Wenn es zu Konflikten beim Zusammenführen kommt, werden diese mit den üblichen Konfliktmarkierungen in der Ausgabe angezeigt, z. B.:

$ git merge-tree $(git merge-base a b ) a b 
added in both
  our    100644 78981922613b2afb6025042ff6bd878ac1994e85 a
  their  100644 61780798228d17af2d34fce4cfbdf35556832472 a
@@ -1 +1,5 @@
+<<<<<<< .our
 a
+=======
+b
+>>>>>>> .their

Der Benutzer @dreftymac hat ein gutes Argument: Das macht es für Skripting ungeeignet, weil man das nicht einfach aus dem Statuscode herauslesen kann. Die Konfliktmarkierungen können je nach Umstand recht unterschiedlich sein (gelöscht vs. geändert, etc.), was das Grepen ebenfalls erschwert. Vorsicht!

2 Stimmen

@dreftymac kann nichts in dieser Richtung finden. Sie könnten etwas verwenden wie git merge-tree ... | grep -q '^[a-z].*in both$' && echo conflict || echo safe to merge aber es ist pingelig; ich vergesse wahrscheinlich einen Fall. vielleicht wollen Sie stattdessen nach den Konfliktmarkierungen suchen? z.B. fängt dies wahrscheinlich keine Konflikte im Stil von "ihre gelöscht, unsere geändert" ab. (Ich habe gerade überprüft und das zeigt nicht einmal Konfliktmarker, so dass Sie eine sorgfältige Regex benötigen, um hier sicher zu sein)

1 Stimmen

使用する less -R um eine farbige Ausgabe zu ermöglichen, ohne die Konfiguration zu ändern.

0 Stimmen

Dies ist die einzig richtige Antwort. Jetzt sicher, warum andere hochgestuft werden.

19voto

djschny Punkte 679

Wenn es Ihnen wie mir geht, suchen Sie nach einem Äquivalent zu svn update -n . Das folgende Beispiel scheint zu funktionieren. Achten Sie darauf, dass Sie eine git fetch damit Ihr lokales Repository über die entsprechenden Aktualisierungen verfügt, mit denen es verglichen werden kann.

$ git fetch origin
$ git diff --name-status origin/master
D       TableAudit/Step0_DeleteOldFiles.sh
D       TableAudit/Step1_PopulateRawTableList.sh
A       manbuild/staff_companies.sql
M       update-all-slave-dbs.sh

oder wenn Sie einen Unterschied zwischen Ihrem Kopf und der Fernbedienung wünschen:

$ git fetch origin
$ git diff origin/master

IMO ist diese Lösung viel einfacher und weniger fehleranfällig (und daher viel weniger riskant) als die oberste Lösung, die "Zusammenführen und dann Abbrechen" vorschlägt.

1 Stimmen

Sollte sein $ git checkout target-branch und dann $ git diff --name-status ...branch-to-be-merged (drei Punkte sind unerlässlich, also geben Sie sie unverändert ein)

1 Stimmen

Eine Sache, die hier fehlt, ist, dass es nicht anzeigt, welche Dateien einen Konflikt haben könnten - sie haben dieselbe "M"-Markierung wie Dateien, die im Zweig geändert wurden, aber ohne Konflikte zusammengeführt werden können.

1 Stimmen

Vielleicht waren die Dinge 2012 anders, aber heutzutage scheint der Abbruch einer Zusammenführung recht zuverlässig zu sein, daher halte ich es nicht für fair, dies jetzt als "viel einfacher und weniger fehleranfällig" zu bezeichnen.

6voto

Wenn Sie die Änderungen bereits abgeholt haben, ist mein Favorit:

git log ...@{u}

Ich glaube aber, dass dafür Git 1.7.x erforderlich ist. Die @{u} Notation ist eine "Kurzschrift" für den vorgelagerten Zweig und damit ein wenig vielseitiger als git log ...origin/master .

Hinweis: Wenn Sie zsh und die erweiterte Glog-Funktion verwenden, müssen Sie wahrscheinlich etwas wie folgt tun:

git log ...@\{u\}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X