Die Vereinfachung des Git-Verlaufs verstehen

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019

Die Vereinfachung des Git-Verlaufs kann an ein verwirrtes Tier erinnern. In 99 % der Zeit werden Sie nicht einmal wissen, dass es existiert, aber gelegentlich springt es aus einer dunklen Ecke von Git und beißt Sie. In diesem Artikel untersuchen wir, worum es bei der Vereinfachung des Verlaufs geht und wie sie beim Betrachten des Dateiverlaufs zu Verwirrung führen kann.

Beginnen wir mit einem gängigen Szenario:

  1. Sie pushen eine Änderung in eine Datei und führen die Änderung dann in den Hauptvorgang zusammen.
  2. Einige Ihrer Kollegen führen auch ihre Branches in den Hauptvorgang zusammen.
  3. Sie kehren einige Zeit später zurück und stellen fest, dass Ihre Änderungen fehlen.
  4. Auf der Suche nach dem Schuldigen, sehen Sie sich den Dateiverlauf an und stellen fest... Ihre Änderungen sind noch nicht einmal aufgeführt!?

Der Git-Commitverlauf ist eine Struktur. Manchmal stimmt der chronologische Verlauf nicht mit dem tatsächlichen Dateistrukturverlauf überein. Diese Situation tritt am häufigsten auf, wenn eine Datei durch einen Mergecommit wieder in den ursprünglichen Zustand zurückversetzt wird. In diesem Fall werden in der Standardverlaufsansicht nicht alle Änderungen angezeigt, da sich die Datei technisch gesehen nicht geändert hat. In diesem Szenario erkennt Git, dass es den Verlauf vereinfachen kann, und die „Änderungen“, nach denen Sie höchstwahrscheinlich suchen, werden aus dem Protokoll entfernt.

Wenn Ihnen das nicht schon einmal begegnet ist, sind Sie möglicherweise frustriert und fragen sich, wo zum Teufel sind meine Änderungen hin?

Verlaufsvereinfachung: Standardmäßig aktiviert

Standardmäßig vereinfacht git log file.txt wird beim Ausführen des Protokollbefehls für eine Datei automatisch den Verlauf, und möglicherweise werden einige Commits aus der Ausgabe ausgeblendet. Weitere Informationen finden Sie auf der Git-Protokoll-Manpage.

Was zur Verwirrung beiträgt, ist, dass die Vereinfachung des Verlaufs nicht auftritt, wenn Sie einfach git log ausführen, da Sie sich alle Änderungen ansehen, da es nichts zu vereinfachen gibt.

Um die Vereinfachung des Verlaufs zu deaktivieren, müssen Sie den Befehlszeilenschalter --full-history verwenden.

Beispiel für die Vereinfachung des Verlaufs

Um besser zu verstehen, wie die Vereinfachung funktioniert, erstellen wir ein eigenes Beispiel für die Verlaufsvereinfachung. Sehen wir uns zunächst ein Diagramm des zu erstellenden Verlaufs an:

Git-Branches

Wie Sie sehen können, gehen wir folgendermaßen vor:

  1. Erstellen Sie eine Datei.
  2. Fügen Sie dieser Datei in einem Branch (Tiere) eine Zeile hinzu.
  3. Fügen Sie dieser Datei in einem anderen Branch (Obst) eine andere Zeile hinzu.
  4. Führen Sie den Branch Tiere wieder in dem Hauptvorgang zusammen.
  5. Führen Sie den Branch Obst wieder in den Hauptvorgang zusammen, und wählen Sie die gesamte Kopie der Datei aus dem Obst-Branch aus.
  6. Überprüfen Sie den Dateiverlauf.

Git wird den Verlauf für uns vereinfachen. Schritt 5 ist hier der Schlüssel. Wir haben alle Änderungen des Branchs Tier ignoriert. Git stellt nun fest, dass sich unsere Datei zwischen Schritt 1 und Schritt 5 im Wesentlichen nicht geändert hat, und so werden uns nur zwei Verlaufseinträge angezeigt.

Zuerst erstellen wir die Datei und fügen sie unserem Repository hinzu:

> cd sample
> git init
> echo "some content" > test.txt
> git add test.txt
> git commit -m "Initial commit"

Nun entscheiden wir uns, den Text „Esel“ an die Datei in einem Tier-Branch anzufügen:

> git checkout -b animals
> echo "donkeys" >> test.txt
> git commit -am "We have added an animal"

Während wir experimentieren, entscheiden wir uns, dass wir stattdessen Obst in unserer Datei verwenden möchten, sodass wir einen anderen Branch erstellen und stattdessen den Text „Bananen am Ende der Datei anfügen:

> git checkout main -b fruit
> echo "bananas" >> test.txt
> git commit -am "We have added a fruit"

Wir sind mit unseren Veränderungen zufrieden und beschließen, unseren Tier-Branch wieder in den Hauptvorgang zusammenzuführen:

> git checkout main
> git merge animals

Sehen wir uns nun das Protokoll zu unserer test.txt-Datei an:

> git log test.txt
    
    commit 6b33d99b996c430a60c9552b79245d1aa8320339
        Date:   Mon Feb 15 10:45:33 2016 -0500

        We have added an animal

    commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
        Date:   Mon Feb 15 10:44:18 2016 -0500

        Initial commit

So weit so gut, oder? In unserer Protokollausgabe sieht nichts außergewöhnlich aus. Nehmen wir nun an, wir haben unsere Meinung geändert und beschlossen, unseren Obst-Branch zusammenzuführen:

>git merge fruit
    
    Auto-merging test.txt
    CONFLICT (content): Merge conflict in test.txt
    Automatic merge failed; fix conflicts and then commit the result.

Oh, ein Mergekonflikt. Nach einiger Überlegung entscheiden wir uns, die gesamte test.txt-Datei aus unserem Obst-Branch zu verwenden. In der Regel verwenden Sie eine Art Text-Editor oder Merge-Tool, aber wir erstellen einfach die gesamte Datei neu, da es sich nur um zwei Zeilen handelt:

> echo "some content" > test.txt
> echo "bananas" >> test.txt
> git commit -am "Fixed merge conflict"

Sehen wir uns nun den Verlauf unserer test.txt-Datei an:

> git log test.txt
    
    commit fdd4dfd816c4efebc5bdb240f49e934e299db581
        Date:   Mon Feb 15 10:51:06 2016 -0500

        We have added a fruit

    commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
        Date:   Mon Feb 15 10:44:18 2016 -0500

        Initial commit

Sicher, wir sehen keine Änderungen aus unserem ersten Experiment im Protokoll, und auch unsere Zusammenführung sehen wir nicht! Sind sie noch da? Hat Git die Änderungen vollständig beseitigt?

> git log --full-history test.txt

Wie Sie sehen können, hat Git alle Änderungen beibehalten, obwohl es das Protokoll ohne das full-history-Flag vereinfacht hat:

> commit 5d0bb77a24e265dc154654fb3b5be331b53bf977
    Merge: 6b33d99 fdd4dfd
        Date:   Mon Feb 15 10:59:34 2016 -0500

        Fixed merge conflict

    commit fdd4dfd816c4efebc5bdb240f49e934e299db581
        Date:   Mon Feb 15 10:51:06 2016 -0500

        We have added a fruit

    commit 6b33d99b996c430a60c9552b79245d1aa8320339
        Date:   Mon Feb 15 10:45:33 2016 -0500

        We have added an animal

    commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
        Date:   Mon Feb 15 10:44:18 2016 -0500

        Initial commit

Zusammenfassung der Vereinfachung des Git-Verlaufs

Das Besondere an der Verlaufsvereinfachung ist, dass Sie sie meistens gar nicht bemerken. Wenn jedoch ein Mergekonflikt eintritt und Sie wissen möchten, was passiert ist, sehen Sie sich möglicherweise den Git-Protokollverlauf an und fragen sich, was mit Ihren Änderungen passiert ist.

Anstatt in Panik zu geraten, wissen Sie Folgendes:

  • Die Vereinfachung des Verlaufs für Dateien ist standardmäßig aktiviert.
  • Das --full-history-Flag gibt Ihnen einen umfassenderen Dateiverlauf an.

Update: Seit ich diesen Artikel geschrieben habe, hat Azure DevOps Services eine Reihe von großartigen Verlaufsanzeigeoptionen im Web eingeführt. Dies bedeutet, dass Sie, wenn Sie sich nicht durch die Befehlszeile durcharbeiten möchten, einfach die Datei abrufen können, für die Sie den Verlauf im Explorer anzeigen möchten, und dass Ihnen der folgende Verlaufsfilter angezeigt wird, in dem Sie einfache oder nicht einfache Verlaufsansichten angeben können:

Git-Filter

(c) 2016 Microsoft Corporation. Alle Rechte vorbehalten. Dieses Dokument wird „wie besehen“ zur Verfügung gestellt. Die in diesem Dokument enthaltenen Informationen und zum Ausdruck gebrachten Ansichten, auch URL- und andere Internet-Websitebezüge, können ohne vorherige Ankündigung geändert werden. Sie tragen das alleinige Verwendungsrisiko.

Dieses Dokument stellt keinerlei Rechtsansprüche auf geistiges Eigentum in Microsoft-Produkten jeglicher Art bereit. Dieses Dokument darf für interne Referenzzwecke kopiert und verwendet werden.