Warum möchte jeder ernsthafte Github-Repo, für den ich Anfragen ziehe, dass ich meine Commits in einem einzigen Commit zusammenführe?
Ich dachte, das GIT-Protokoll wäre da, damit Sie Ihre gesamte Historie einsehen und genau sehen können, was sich an welcher Stelle geändert hat, aber wenn Sie es zerquetschen, wird es aus der Historie entfernt und alles wird zu einem Commit zusammengefasst. Was ist der Sinn?
Dies scheint auch gegen das Mantra "Frühzeitig und häufig festlegen" zu verstoßen.
Antworten:
Damit Sie eine klare und prägnante Git-Historie haben, die die vorgenommenen Änderungen und die Gründe dafür klar und einfach dokumentiert.
Zum Beispiel könnte ein typisches 'unsquashed' Git-Log für mich so aussehen:
Was für ein Chaos!
Während ein sorgfältig verwaltetes und zusammengeführtes Git-Protokoll mit einem kleinen zusätzlichen Fokus auf die Nachrichten dafür wie folgt aussehen könnte:
Ich denke, Sie können den Punkt des Quetschens von Commits im Allgemeinen erkennen und dasselbe Prinzip gilt für Pull-Anfragen - Lesbarkeit der Historie. Sie können auch ein Commit-Protokoll hinzufügen, das bereits Hunderte oder sogar Tausende von Commits enthält. Auf diese Weise können Sie den wachsenden Verlauf kurz und präzise halten.
Sie möchten sich früh und häufig festlegen. Es ist aus vielen Gründen eine bewährte Methode. Ich stelle fest, dass ich häufig Commits habe, die "wip" (in Bearbeitung) oder "part A done" oder "typo, minor fix" sind, bei denen ich git verwende, um zu arbeiten und mir Arbeitspunkte zu geben Ich kann zurückgehen, wenn der folgende Code nicht funktioniert, während ich Fortschritte mache, um die Dinge zum Laufen zu bringen. Ich brauche oder möchte diese Historie jedoch nicht als Teil der finalen Git-Historie, damit ich meine Commits quetschen kann. Beachten Sie jedoch die nachstehenden Hinweise dazu, was dies für einen Entwicklungszweig im Vergleich zu einem Master bedeutet.
Wenn es wichtige Meilensteine gibt, die unterschiedliche Arbeitsphasen darstellen, ist es immer noch in Ordnung, mehr als ein Commit pro Feature / Task / Fehler zu haben. Dies kann jedoch häufig die Tatsache hervorheben, dass das Ticket in der Entwicklung "zu groß" ist und in kleinere Teile zerlegt werden muss, die eigenständig sein können, zum Beispiel:
scheint wie "1 Stück Arbeit". Entweder existieren sie oder nicht! Es scheint keinen Sinn zu machen, es herauszubrechen. Die Erfahrung hat jedoch gezeigt, dass (abhängig von der Größe und Komplexität der Organisation) ein differenzierterer Pfad sein kann:
Kleine Teile bedeuten einfachere Codeüberprüfungen, einfachere Komponententests, bessere Qa-Möglichkeiten, bessere Ausrichtung auf das Prinzip der Einzelverantwortung usw.
Für die praktische Durchführung solcher Kürbisse gibt es grundsätzlich zwei verschiedene Phasen, die ihren eigenen Arbeitsablauf haben
Während Ihrer Entwicklung legen Sie "früh und häufig" und mit schnellen "Wegwerf" -Botschaften fest. Möglicherweise möchten Sie hier gelegentlich einen Squash ausführen, z. B. Wip-Squashing und Nachrichten-Commits ausführen. Innerhalb des Zweigs ist es in Ordnung, mehrere Festschreibungen zu speichern, die unterschiedliche Schritte darstellen, die Sie in der Entwicklung durchgeführt haben. Die meisten Kürbisse, die Sie auswählen, sollten sich in diesen Feature-Zweigen befinden, während sie entwickelt werden und bevor sie zum Master zusammengeführt werden.
Beim Hinzufügen zum Hauptleitungszweig möchten Sie, dass die Festschreibungen präzise sind und entsprechend der vorhandenen Hauptleitungshistorie korrekt formatiert werden. Dies kann die Ticket Tracker-System-ID enthalten, z. B. JIRA, wie in den Beispielen gezeigt. Squashing wird hier nicht wirklich angewendet, es sei denn, Sie möchten mehrere verschiedene Commits auf dem Master "zusammenfassen". Normalerweise nicht.
Unter Verwendung
--no-ff
beim Zusammenführen zu meistern wird ein für die merge commit verwenden und auch Geschichte zu erhalten (im Zweig). Einige Organisationen halten dies für eine bewährte Methode. Weitere Informationen finden Sie unter https://stackoverflow.com/q/9069061/631619. Sie sehen auch den praktischen Effekt, ingit log
dem ein--no-ff
Commit das letzte Commit oben im HEAD ist (wenn es gerade ausgeführt wurde), während--no-ff
dies möglicherweise nicht der Fall ist weiter unten in der Geschichte, abhängig von Daten und anderen Verpflichtungen.quelle
Weil sich die Person, die eine PR zieht, oft um den Nettoeffekt des Commits "Added Feature X" kümmert, nicht um die "Base Templates", Bugfix-Funktion X, Add-Funktion Y, feste Tippfehler in Kommentaren, angepasste Daten-Skalierungsparameter, Hashmap-Leistung besser als list "... Detaillierungsgrad
Wenn Sie der Meinung sind, dass Ihre 16 Commits am besten durch 2 Commits und nicht durch 1 "Feature X hinzugefügt, Z neu faktorisiert, um X zu verwenden" dargestellt werden, ist dies wahrscheinlich in Ordnung, um einen PR mit 2 Commits vorzuschlagen, aber dann ist es möglicherweise am besten, dies vorzuschlagen In diesem Fall 2 separate Prs (wenn der Repo immer noch auf einzelnen Commit-Prs besteht)
Dies steht nicht im Widerspruch zum Mantra "Frühes und häufiges Festschreiben", wie in Ihrem Repo, während Sie sich weiterentwickeln, haben Sie immer noch die detaillierten Details, sodass Sie nur eine minimale Chance haben, Arbeit zu verlieren, und andere Personen können prüfen / ziehen / vorschlagen PR ist gegen deine Arbeit, während der neue PR entwickelt wird.
quelle
Der Hauptgrund für das, was ich sehen kann, ist folgender:
Merge pull request #123 from joebloggs/fix-snafoo
--first-parent
Sicht anzuzeigen--first-parent
Sicht anzuzeigen (beachten Sie, dass dies nur in Git 2.6.2 behoben wurde, sodass wir GitHub verzeihen konnten, dass dies nicht der Fall war verfügbar)Wenn Sie also alle drei oben genannten Situationen kombinieren, erhalten Sie eine Situation, in der nicht gequetschte Commits, die zusammengeführt werden, auf der GitHub-Benutzeroberfläche hässlich aussehen.
Ihr Verlauf mit gequetschten Commits sieht ungefähr so aus
Während ohne gequetschte Commits die Geschichte ungefähr so aussieht
Wenn Sie in einer PR-Ablaufverfolgung viele Commits haben, bei denen eine Änderung eingetreten ist, kann dies zu einem Albtraum werden, wenn Sie sich auf die Verwendung der GitHub-Benutzeroberfläche beschränken .
Sie finden beispielsweise einen Nullzeiger, auf den irgendwo in einer Datei nicht mehr verwiesen wird. Sie sagen also "Wer hat das getan und wann? Welche Release-Versionen sind betroffen?". Dann wandern Sie zur Schuldansicht in der GitHub-Benutzeroberfläche und sehen, dass die Zeile in geändert wurde
789fdfffdf
... "Oh, aber warte mal, die Einrückung dieser Zeile wurde nur so geändert, dass sie in den Rest des Codes passt." Nun müssen Sie zum Baumstatus für diese Datei im übergeordneten Festschreiben navigieren und erneut besuchen die Schuld Seite ... irgendwann finden Sie das Commit ... es ist ein Commit von vor 6 Monaten ... "Oh, das könnte die Benutzer für 6 Monate beeinflussen", sagen Sie ... ah, aber warten Sie, das Commit war eigentlich in einem Pull Request und wurde erst gestern zusammengeführt und noch hat niemand eine Veröffentlichung gekürzt ... "Verdammt ihr Leute für das Zusammenführen von Commits ohne die Geschichte zu quetschen" ist der Schrei, der normalerweise nach etwa 2 oder 3 Code-Archäologie-Expeditionen über das Internet zu hören ist GitHub UILassen Sie uns nun überlegen, wie dies funktioniert, wenn Sie die Git-Befehlszeile verwenden (und Super-Awesome 2.6.2, für das es das Update gibt
git blame --first-parent
).So würde unsere Commit-Historie aussehen
Aber wir können es auch tun
(Mit anderen Worten: Mit der Git CLI können Sie Ihren Kuchen haben und ihn auch essen.)
Wenn wir nun auf das Nullzeiger-Problem stoßen ... nun, wir verwenden es einfach
git blame --first-parent -w dodgy-file.c
und erhalten sofort das genaue Commit, bei dem die Nullzeiger-De-Referenz in den Master-Zweig eingefügt wurde, wobei einfache Leerzeichenänderungen ignoriert wurden.Natürlich, wenn Sie Merges mit der GitHub-Benutzeroberfläche durchführen,
git log --first-parent
ist das wirklich beschissen, da GitHub die erste Zeile der Merge-Commit-Nachricht erzwingt:Um es kurz zu machen:
Die GitHub-Benutzeroberfläche (Okt. 2015) weist eine Reihe von Mängeln bei der Zusammenführung von Pull-Anforderungen, der Darstellung des Commit-Verlaufs und der Attributierung von Schuldinformationen auf. Die derzeit beste Möglichkeit, diese Fehler in der GitHub-Benutzeroberfläche zu umgehen, besteht darin, die Benutzer aufzufordern, ihre Commits vor dem Zusammenführen zu quetschen.
In der Git-CLI gibt es diese Probleme nicht, und Sie können einfach auswählen, welche Ansicht Sie anzeigen möchten, damit Sie beide den Grund für eine bestimmte Änderung ermitteln können (indem Sie sich den Verlauf der nicht unterdrückten Festschreibungen ansehen) siehe die effektiv gequetschten Commits.
Post Script
Der letzte Grund, der häufig für das Squashing von Commits genannt wird, ist die Erleichterung des Backports. Wenn Sie nur ein Commit für den Backport haben (dh das Squashed-Commit), ist es einfach, das richtige zu finden.
Wenn Sie sich den Git-Verlauf ansehen
git log --first-parent
, können Sie einfach die Merge-Commits auswählen. Die meisten Leute sind verwirrt, weil Sie die-m N
Option angeben müssen, aber wenn Sie den Commit erhalten habengit log --first-parent
, wissen Sie, dass dies das erste übergeordnete Element ist, dem Sie folgen möchtengit cherry-pick -m 1 ...
quelle
--first-parent
meiner selbst vorangetrieben habe, um ein Argument gegen das Zusammendrücken von Commits zu gewinnen ;-)Ich stimme den in anderen Antworten in diesem Thread zum Ausdruck gebrachten Ansichten zu, wonach ein klarer und prägnanter Verlauf der hinzugefügten Funktionen und behobenen Fehler angezeigt werden soll. Ich wollte jedoch auf einen anderen Aspekt eingehen, auf den Ihre Frage nicht eingegangen ist, den Sie jedoch nicht ausdrücklich ausgeführt haben. Ein Teil des Problems, das Sie möglicherweise mit einigen der Arbeitsmethoden von git haben, ist, dass Sie mit git den Verlauf neu schreiben können, was seltsam erscheint, wenn Sie in git eingeführt werden, nachdem Sie andere Formen der Quellcodeverwaltung verwendet haben, bei denen solche Aktionen unmöglich sind. Darüber hinaus verstößt dies auch gegen das allgemein anerkannte Prinzip der Quellcodeverwaltung, dass Sie nach dem Festschreiben / Einchecken in die Quellcodeverwaltung in diesen Zustand zurückkehren können sollten, unabhängig davon, welche Änderungen Sie nach dem Festschreiben vornehmen. Wie Sie in Ihrer Frage implizieren, ist dies eine dieser Situationen. Ich denke, Git ist ein großartiges Versionskontrollsystem. Um es jedoch zu verstehen, müssen Sie einige der Implementierungsdetails und die Entwurfsentscheidungen dahinter verstehen. Infolgedessen weist es eine steilere Lernkurve auf. Denken Sie daran, dass git ein verteiltes Versionskontrollsystem sein sollte, und dies hilft zu erklären, warum die Designer das Umschreiben des Git-Verlaufs zulassen, wobei Squash-Commits ein Beispiel dafür sind.
quelle
git gc
wurde ausgeführt, um nicht referenzierte Objekte zu verwerfen.Aufgrund der Perspektive ... Die beste Vorgehensweise ist,
<<issue-management-system>>
wenn möglich, ein einzelnes Commit pro Ausgabe durchzuführen.Sie können beliebig viele Commits in Ihrem eigenen Feature-Zweig / Repo haben, aber es ist Ihre Historie, die für das, was Sie jetzt für IHRE Perspektive tun, relevant ist. Es ist nicht die GESCHICHTE für das gesamte TEAM / PROJEKT oder die Anwendung von diesem Perspektive wird in einigen Monaten beibehalten ...
Wenn Sie also eine Fehlerbehebung oder ein Feature für ein allgemeines Repo durchführen möchten (in diesem Beispiel für den Entwicklungszweig), können Sie dies folgendermaßen tun:
So bauen Sie Ihre Feature-Verzweigung schnell wieder auf
quelle
Ich würde sehen, ob der Code öffentlich wird oder nicht.
Wenn Projekte privat bleiben:
Ich würde empfehlen, nicht zu quetschen und die Herstellung der Wurst zu sehen. Wenn Sie gute und kleine Commits verwenden, sind Tools wie git bisect sehr praktisch und die Benutzer können schnell Regressions-Commits ermitteln und sehen, warum Sie dies getan haben (aufgrund der Commit-Meldung).
Wenn Projekte an die Öffentlichkeit gehen:
Squash alles, weil einige Commits Sicherheitslücken enthalten können. Zum Beispiel ein Passwort, das bestätigt und wieder entfernt wurde.
quelle