Was git commit practice ist besser?

8

Ich glaube wirklich, dass es eine gute Übung ist, sich zu einem Thema zu verpflichten. Ich bin sicher, ich habe es irgendwo in einem Artikel wie "Best Practices" gelesen.

Daher war mein Arbeitsablauf der folgende:

  • Für ein neues Problem erstelle ich einen neuen lokalen Zweig mit git checkout -b new-issue .
  • Übernehmen Sie alle Änderungen. Manchmal beinhaltet dies viele Commits.
  • Wenn das erledigt ist, habe ich squash die commits und rebase sie in den aktuellen thematischen Zweig übernommen.
  • Wenn etwas schief geht, kann ich git revert committen, den Fehler finden, beheben und einen neuen Patch in den thematischen Zweig schreiben. Ich werde den Verlauf des Remote-Repositorys nicht ändern.

Aber heute war ich überrascht, folgenden Workflow zu hören:

  • Erstellen Sie einen neuen Zweig für das neue Problem.
  • Übermittle alles darin.
  • Verwenden Sie merge --no-ff , um den Issue-Zweig mit dem thematischen Zweig zusammenzuführen (also haben wir "merge-commit", das wir können revert ).
  • Wenn etwas schief geht, können wir git bisect verwenden, um den Fehler zu finden.

Nach dem ersten Ansatz haben wir einen sauberen Git-Verlauf und keine Ahnung von Overhead-Zweigen, die während der Entwicklung verwendet wurden.

Nach dem zweiten Ansatz haben wir eine sehr schmutzige Geschichte mit vielen unschönen, unnötigen Zusammenführungen und Commits für nur ein Problem. Allerdings können wir git bisect verwenden, um Fehler zu finden. (Vielleicht ist das besser für Refactoring?)

  • Welche Vor- und Nachteile sehen Sie für beide Ansätze?

  • Welchen Ansatz verwenden Sie und warum?

  • Haben Sie tatsächlich in der Praxis git bisect benutzt, um Fehler zu finden? (Ich habe nicht ...)

Viacheslav Kondratiuk 21.03.2013, 16:37
quelle

2 Antworten

5
Am Ende ist es weitgehend ein persönliches Geschmacksproblem ... kann nur meinen Geschmack erklären (und ein wenig Rechtfertigung dafür geben).

Ich neige dazu, die einzelnen Commits zu behalten, auch wenn sie nur "Fix dumme Tippfehler" sind. Jedes "History Rewriting" erzeugt Commits, die noch nie zuvor existierten, also sind sie garantiert nie getestet worden. Außerdem machen minimale Commits git bisect immens nützlich, wenn ein Fehler später auftritt. Besser in der Lage zu sein, es auf ein paar veränderte Linien einzuschränken als auf eine Woche Arbeit, zusammengequetscht.

Wenn ein Entwicklungszweig eine Geschichte durcheinanderbringt, bereinige ich ihn (minimal, dh rückgängig gemachte Commits sind einfach nie passiert, allgemeine Fixes wie Leerzeichen oder variable Umbenennungen könnten früher angewendet werden, einige neu geordnet verwandte Änderungen zusammenfügen). Commits bleiben immer noch klein, werden selten gequetscht. Diese Reinigung mache ich meistens inkrementell. Dann füge ich den bereinigten Zweig mit dem "offiziellen" zusammen (oder rebase).

    
vonbrand 21.03.2013, 19:10
quelle
5

Der zweite Ansatz muss nicht viele hässliche und unnötige Verschmelzungen und Commits enthalten. Das ist was ich vorziehe:

  1. Erstellen Sie einen neuen Themenzweig
  2. Machen Sie eine Reihe von Commits
  3. kurz vor dem Zusammenführen mit dem übergeordneten Zweig bereinigen Sie die Commits:
    • rebase auf die neueste Version des übergeordneten Zweiges
    • Squash Tippfehler beheben
    • split setzt mehrere Dinge gleichzeitig in separate Commits um
    • Ordnen Sie die Commits neu an, um es einem Prüfer zu erleichtern, die Abfolge der Änderungen zu verstehen
    • usw.
  4. merge mit --no-ff in den übergeordneten Zweig
  5. ein

Die obigen Schritte führen zu einem Verlauf, der folgendermaßen aussieht:

%Vor%

Das obige Diagramm hat die gleichen Vorteile wie Ansatz 1:

  • Sie können das Argument --first-parent für git log verwenden, um eine übersichtliche Zusammenfassung zu erhalten, die dem entspricht, was Sie mit Ansatz # 1 erhalten würden:

    %Vor%
  • Sie können immer noch die Gesamtheit der Änderungen in einer Zweigstelle überprüfen. Zum Beispiel zeigt git diff 354b644^..354b644 Ihnen an, was für Thema Nr. 3 geändert wurde.

Aber Sie erhalten Vorteile, die Ansatz Nr. 1 Ihnen nicht geben kann:

  • Der Verlauf ist viel einfacher zu überprüfen: commits b45fbcf und 7dfc7e5 (für den Zweig topic3 ) führen eine Menge Rauschen ein, aber keine tatsächlichen logischen Änderungen. Jemand versucht, die Frage zu beantworten: "Welche logischen Änderungen wurden für Thema Nr. 3 vorgenommen?" könnte es schwer haben, durch den Lärm zu graben, wenn all diese Verpflichtungen in einen zerquetscht werden.
  • Die Zusammenführung legt fest, dass der Kontext für die Reihe von Festschreibungen im zusammengeschlossenen Zweig identifiziert wird (z. B. wurde diese Gruppe von Festlegungen getroffen, um Thema Nr. 3 anzusprechen).
  • Die feinere Granularität von Commits erleichtert es, herauszufinden, warum eine bestimmte Änderung vorgenommen wurde, die dazu beitragen kann, zufällige Änderungen von absichtlich-aber-subtil zu unterscheiden.
  • Wenn mehrere Personen in der Zweigstelle zusammenarbeiten, können Sie sehen, wer sie alle waren und wie viel jede Person beigetragen hat.
  • Die Anzahl der Commits im zusammengelegten Zweig gibt Ihnen eine ungefähre Vorstellung davon, wie viel geändert wurde.
  • Der Zeitbereich der Commits kann einen nützlichen Kontext darstellen.
  • Sie können leicht eine bestimmte Änderung auswählen, die in einem anderen Zweig vorgenommen wurde (z. B. cherry-wählen Sie die minimale Änderung aus, die benötigt wird, um einen Fehler in einem Zweig zu beheben).

Es gibt einen Nachteil, den ich mir vorstellen kann: Es kann schwierig sein, Ihre Softwareentwicklungstools so zu konfigurieren, dass sie nur dem First-Parent-Pfad folgen und all diese zwischenzeitlichen Commits ignorieren. Beispiel: Es gibt kein Argument --first-parent für git bisect . Außerdem kenne ich Jenkins nicht genug, um zu wissen, wie einfach es ist, es so zu konfigurieren, dass der Pfad des ersten Elternteils über alle anderen Commits hinweg erstellt und getestet wird.

    
Richard Hansen 30.03.2013 17:36
quelle

Tags und Links