Mit git log können Dateien angezeigt werden, die während der Zusammenführung geändert wurden

8

Ich führe den folgenden Befehl aus:

%Vor%

gibt die Ergebnisse im folgenden Format zurück:

%Vor%

Die Ausgabe wird in eine Datei umgeleitet, und das Format ist genau das, wonach ich suche, aber das Zusammenfügen ist ein Problem. Die Dateien, die als Teil einer Zusammenführung geändert wurden, werden nie aufgelistet. Stattdessen habe ich am Ende folgendes:

%Vor%

Ich habe hier offensichtlich etwas missverstanden, weil ich erwarte, dass die Dateien, die während der Zusammenführung geändert wurden, aufgelistet werden. Gibt es eine Möglichkeit, diese Dateien in die Ausgabe aufzunehmen?

    
Blue 14.06.2016, 00:55
quelle

2 Antworten

12

TL; DR

Fügen Sie den Optionen -m die Option git log hinzu. Dadurch wird Git bei jeder Zusammenführung "geteilt", so dass es die Verschmelzung zweimal einmal gegen jeden Elternteil trennt. Ohne diese oder eine andere ähnliche Option findet git log die Zusammenführungen, schaut dann aber nicht einmal in sie hinein.

Auch als ElpieKay kommentierte , du musst --grep=<regexp> vor -- setzen. Es kann auch sinnvoll sein, "*.sql" , also in Anführungszeichen, zu schreiben, um zu verhindern, dass Ihre Shell das Sternchen selbst erweitert (die Details variieren von einer Shell zur anderen und hängen davon ab, ob% code% Dateien in Ihrer aktuellen Datei vorhanden sind) Arbeitsverzeichnis).

Lange Version

Tim Biegeleisen sagte , das Problem rührt von der Art einer Zusammenführung her.

Um Ihnen zu zeigen, was sich bei einem Commit geändert hat, führt Git normalerweise ein einfaches *.sql aus, wobei git diff parent self und parent das übergeordnete Element des Commits sind das Commit selbst jeweils. Sowohl self als auch git log tun dies in leicht unterschiedlicher Weise und unter etwas anderen Umständen. Das offensichtlichste ist, dass git show standardmäßig jedes Mal ein diff anzeigt, aber git show nur ein diff, wenn git log oder eine der verschiedenen diff-Steueroptionen wie -p angegeben wird.

Zusammenführungen sind anders

Ein merge commit ist ein Commit mit zwei 1 Eltern. Dies bedeutet, dass --name-only und git log zwei git show Befehle ausführen müssen. 2 Und tatsächlich, git diff führt zwei Diffs aus, aber dann- Standardmäßig werden sie zu einem kombinierten Unterschied , die nur die Dateien anzeigt, deren Zusammenführung erfolgt -commit Version unterscheidet sich von beiden Eltern . Aber aus irgendeinem Grund macht 3 git show dies standardmäßig nicht.

Auch wenn git log Diffs anzeigt, verhält es sich bei Merges jedoch besonders merkwürdig (ich könnte sogar schlecht sagen). Während git log oder git log -p bei einem regulären Commit ein (einzelnes) diff ausführt, führt bei einem Commit mit mehreren sichtbaren Eltern, es sei denn , das diff überhaupt nicht aus du zwingst es dazu.

Die Verwendung von git log --name-status allein funktioniert immer. Dieses Flag teilt im Wesentlichen -m (und git log ) zu Zerlegen eine Zusammenführung in mehrere separate "virtuelle Commits". Das heißt, wenn commit M eine Zusammenführung mit Eltern P1 und P2 ist, dann wirkt Git - zumindest für den Zweck des Diff - als obwohl es ein commit MP1 mit übergeordnetem P1 und ein zweites commit MP2 mit übergeordnetem P2 gab. Sie erhalten zwei diffs (und zwei Commit-IDs in den diff-Headern).

Das Hinzufügen von git show sagt --first-parent , das zweite (und jedes zusätzliche) Elternteil einer Zusammenführung zu ignorieren, wodurch nur ein Elternteil übrig bleibt. Dies bedeutet, dass git log dem Seitenzweig überhaupt nicht folgt . Daher können Sie git log verwenden, vorausgesetzt, Sie interessieren sich nicht für Historien, die von den anderen Seiten von Zusammenführungen stammen. Dadurch erhalten Sie einen einzigen Vergleich gegen nur das erste übergeordnete Element und nicht über ein diff pro übergeordnetes Element.

(Welches Elternteil ist das erste? Nun, es ist dasjenige, das dein -m --first-parent war, als du HEAD liefst. Das ist normalerweise die "Hauptlinie" von Commits, dh die "on" Wenn Ihre Gruppe git merge zufällig verwendet, möchten Sie wahrscheinlich nicht die andere Seite von Zusammenführungen ignorieren, da git pull die Hauptarbeit von anderen Personen in "foxtrot fusioniert" mit kleinen Seitenästen.

Kombinierte Diffs, wieder

Neben git pull können Sie -m oder -c angeben (beachten Sie, dass --cc einen Bindestrich hat, während -c zwei 4 hat), um --cc zu erhalten erzeugt ein kombiniertes diff, genau wie git log . Wie bei allen kombinierten Diffs ignoriert dies jedoch Dateien, die zwischen dem Zusammenführungs-Commit und einem der Eltern übereinstimmen. Das heißt, bei der gleichen Verschmelzung M vergleicht Git diesmal M vs P1 und M vs < em> P2 . Für jede Datei F wobei M: F dasselbe ist wie entweder P1: F oder P2: F , Git zeigt gar nichts.

Wie sich herausstellt, ist dies normalerweise das, was Sie wollen. Wenn Datei F in commit M mit Datei F in einem der beiden übergeordneten Commits übereinstimmt, bedeutet das, dass die Datei von dieses Elternteil. Die Tatsache, dass F in P1 nicht mit F in P2 übereinstimmt, ist normalerweise nicht interessant: jede Änderung in F in entweder P1 oder P2 ist wahrscheinlich das Ergebnis einer früheren Änderung im Verlauf, und das sollten wir beachten davon, anstatt bei Merge M .

Das ist die Logik hinter kombinierten Diffs. Es ist nicht unter allen Umständen anwendbar, weshalb git show existiert: um die Zusammenführung in ihre Bestandteile aufzuteilen.

1 Zwei oder mehr, eigentlich, aber "mehr" ist ungewöhnlich; Die meisten Zusammenführungs-Commits haben genau zwei Eltern. Ein Zusammenführungs-Commit mit mehr als zwei Eltern wird als Octopus Merge bezeichnet.

2 Sowohl -m als auch git log haben die meisten von git show eingebaut, so dass sie eigentlich keine zusätzlichen Befehle ausführen müssen, aber es funktioniert genauso .

3 Ich kenne den Grund nicht, und ich habe nur von diesem bestimmten Verhalten erfahren, als ich die git diff Quelle durchging und versuchte zu erklären, warum git log nichts gezeigt hat.

4 Dies liegt daran, dass git log --name-status eine lange Option ist und beim Analysieren der GNU-Option alle langen Optionen wie --cc oder name-only get erhalten zwei Bindestriche, während alle kurzen (ein Buchstabe) Optionen wie cc get ein Bindestrich

erhalten     
torek 14.06.2016, 02:41
quelle
1

Der Grund, warum Sie dieses Verhalten beobachten, ist, dass es im Falle eines Merge-Commits zwei Sätze von geänderten Dateien gibt, von denen jeweils eine von jedem Elternteil kommt. Eine Option wäre, die Optionen --first-parent -m zu verwenden, wenn Sie git log ausführen:

%Vor%

Dadurch wird Git angewiesen, sich nur auf den Hauptzweig zu konzentrieren, in dem die Zusammenführung stattfindet, und zeigt nur die Dateigruppe für dieses Commit an.

hier für die Dokumentation und hier für einen tollen Blogbeitrag.

    
Tim Biegeleisen 14.06.2016 01:12
quelle

Tags und Links