Was ist der Vorteil des zweistufigen Festschreibungsprozesses von git (Staging)?

174

Ich lerne Git und habe festgestellt, dass es einen zweistufigen Festschreibungsprozess gibt:

  1. git add <files>
  2. git commit

Der erste Schritt fügt Revisionen in den sogenannten "Staging-Bereich" oder "Index" ein.

Mich interessiert, warum diese Entwurfsentscheidung getroffen wird und welche Vorteile sie hat.

Machst du das auch als Git-User oder benutzt du es einfach git commit -a?

Ich frage dies, da ich von bzr (Bazaar) komme, der diese Funktion nicht hat.

thomasrutter
quelle
3
+1 für das Fragen. Ich benutze Tortoise SVN, die den gleichen Ansatz hat und ich habe nie verstanden, warum.
DPD
3
Der Staging-Bereich ist nicht so ungewöhnlich. Das Äquivalent in TFS ist beispielsweise, dass Sie das Kontrollkästchen neben einer Datei aktivieren oder deaktivieren, bevor Sie einchecken. Nur die aktivierten Dateien werden festgeschrieben. Der Unterschied zu Git besteht darin, dass Sie bei der Verwendung git add -pfestlegen können, dass ein Teil einer Datei festgeschrieben wird, während ein anderer Teil derselben Datei nicht festgeschrieben wird .
Kyralessa
Ich fand heraus, dass dieser Link die meisten der hier beantworteten Fragen zusammenfasst und einige weitere Anwendungsfälle hinzufügt, um die Notwendigkeit einer Inszenierung zu rechtfertigen.
Veverke,
2
Diese Frage ist eigentlich schon beantwortet, aber hier ist auch eine gute Erklärung: stackoverflow.com/questions/4878358/…
guitar_freak
1
Vergessen Sie nicht git statusund möglicherweise git push. Bei allem Hype um Git (und GitHub-Sharing-Code ist wunderbar) sind Teile sehr nervig
user949300

Antworten:

83

Arbeit in separate Commits aufteilen. Sie haben wahrscheinlich schon oft eine Datei geöffnet, um einen einzeiligen Fix zu schreiben, aber gleichzeitig haben Sie festgestellt, dass die Formatierung falsch ist, dass einige Dokumentationen verbessert werden könnten oder ein anderer Fix, der nichts mit dem Problem zu tun hat. Bei anderen RCS müssten Sie das aufschreiben oder in den Speicher schreiben, den Fix beenden, den festschreiben und dann zurückkehren, um die anderen Probleme zu beheben (oder ein Ball-of-Mud-Commit mit nicht verwandten Problemen erstellen). . Mit Git können Sie einfach alles auf einmal reparieren und die einzelne Zeile separat mit git add -ioder + festschreiben git-gui.

Unterbrechen Sie nicht den Build. Sie arbeiten an einer komplizierten Modifikation. Sie probieren also verschiedene Dinge aus, von denen einige besser funktionieren als andere, von denen einige Dinge kaputt machen. Mit Git würden Sie Dinge inszenieren, wenn die Modifikation die Dinge besser gemacht hat, und checkout(oder noch mehr optimieren), wenn die Modifikation nicht funktioniert hat. Sie müssen sich nicht auf die Rückgängig-Funktionalität des Editors verlassen, checkoutsondern können das gesamte Repo anstatt nur Datei für Datei und alle Fehler auf Dateiebene (z. B. Entfernen einer Datei, die nicht festgeschrieben wurde, oder Speichern + Schließen nach einem schlechte Änderung) führt nicht zu viel Arbeit verloren.

l0b0
quelle
3
Da ich von einem DVCS (bzr) komme, der diese Funktion nicht besitzt, klingt das sehr ähnlich wie das, was ich derzeit mit einer Kombination aus der großzügigen Verwendung der "Rückgängig" -Puffer meines Editors, dem Befehl "<Datei> zurücksetzen" und selektiven Festschreibungen (" commit <Datei> "). Klingt wie diese Funktion von Git hat das Potenzial, methodischer zu sein.
Thomasrutter
1
In Bezug auf "andere RCS" ist dies nicht unbedingt der Fall. Tatsächlich können Sie dieselben Funktionen in Mercurial mithilfe von Patches erreichen .
Lucio Paiva
1
@ 10b0, über deinen zweiten Punkt. Wenn es nur ein einstufiges Commit gab, hätten Sie die Änderungen, die Sie mit git add verwenden, direkt als Commit festschreiben können. Wenn Sie herausgefunden haben, dass Sie etwas falsch gemacht haben, haben Sie die Festschreibung gerade gelöscht und sind zu Ihrem Standort zurückgekehrt, bevor Sie die Festschreibung getätigt haben. Tun Sie mit dem Staging-Konzept nicht nur das, sondern erhöhen Sie die Komplexität?
Alpha_989
Ihr erster Punkt ist sinnvoll, obwohl ich ihn bisher nicht verwendet habe. Theoretisch, warum kannst du so etwas nicht git add -imit einem einstufigen Commit machen? Sie wählen einfach eine Reihe von Dateien (oder Zeilen in Dateien) aus, die sich auf eine einzelne Funktion beziehen, und führen ein Commit durch. Dann würden Sie zurückkommen und ein zweites Commit für ein anderes Feature durchführen.
alpha_989
@thomasrutter, Nach Ihrer Aussage schlagen Sie vor, dass der Staging-Bereich "manuelle Rückgängigmachungspunkte" erstellt. In VIM mit Persistent-Undo können Sie sehr zuverlässig unbegrenzte Historie erhalten. Dies wird auch automatisch in einer git-branchArt und Weise verfolgt ( jovicailic.org/2017/04/vim-persistent-undo ). Außerdem wird Ihr Rückgängig-Verlauf jedes Mal automatisch aufgezeichnet, wenn Sie in den normalen Modus wechseln. So wird Ihre mentale Belastung durch das Erstellen von "manuellen Rückgängigmachungspunkten" verringert. Warum ist die Verwendung der Rückgängig-Puffer Ihrer Editoren nicht so methodisch?
Alpha_989
65

Einer der Vorteile für mich ist die Möglichkeit, Dateien schrittweise hinzuzufügen. Vor dem Festschreiben überprüfe ich jede Datei. Sobald die Datei überprüft wurde, füge ich sie hinzu. Wenn ich git statusoder git diff, zeigt git mir nur die Dateien an, die geändert und noch nicht hinzugefügt wurden. Wenn ich alle Dateien überprüft und hinzugefügt habe, kann ich einen Commit durchführen.

Also ja, ich finde den Staging-Bereich sehr hilfreich.

Und nein, ich benutze es nie git commit -a. Ich benutze jedoch oft git add -u. Auf diese Weise kann ich immer noch visualisieren, was zu begehen ist.

David
quelle
2
Genau. Der Vorteil ist eine viel feinkörnigere Kontrolle über genau das, was Sie begehen.
Josh K
Was passiert, wenn Sie eine Datei mehrmals bereitstellen? wird es im Staging-Bereich "zusammengeführt"?
m4l490n
21

Der Vorteil ist ganz einfach: Sie haben die volle Kontrolle darüber, welche Dateien Sie wann festschreiben möchten. In diesem Fall können Sie git add -psteuern, welche Zeilen Sie festschreiben möchten.

Rein Henrichs
quelle
2
Ich habe mich immer gefragt, wie das geht. Ich wünschte, es gäbe eine Datei .gitignorelines, mit der Sie lokale Änderungen an einzelnen Zeilen vornehmen können, die Commits überleben und intakt bleiben.
Alex Gray
3
Denken Sie bei ReinHenrichs an Konfigurationsdateien, die von jedem Entwickler geändert werden müssen.
Ian
1
@Ian Ein Teil der Datei ändert sich also selten und wird gemeinsam genutzt. Ein Teil der Datei ändert sich häufig auf inkompatible Weise und wird nicht gemeinsam genutzt. Diese falsche Konnascenz zu unterstützen, klingt definitiv wie ein Anti-Feature.
Rein Henrichs
1
@ReinHenrichs, ja, und es kommt sehr häufig vor, dass die Datei den Namen des Datenbankservers enthält und jeder Entwickler eine eigene Datenbank hat.
Ian
4
@Ian Dein Problem ist wirklich da, dass du eine Datei hast, die die Konfiguration für die Anwendung sein soll und auch eine rechner- / dev-spezifische Konfiguration enthält. Alle mir bekannten Konfigurationssysteme erlauben es Ihnen, das in mehrere Dateien aufzuteilen. So haben Sie zum Beispiel app.confeine db.confDatei, die das Zeug enthält, das Sie teilen möchten, und eine, die Sie einfach in die .gitignore-Liste aufnehmen. Problem gelöst. Wenn Sie etwas Eigenes verwenden, sollten Sie wirklich darauf achten, dass etwas so Einfaches darin enthalten ist. Oder setzen Sie es durch einen Präprozessor in einem Pre-Build-Ereignis. Viele Lösungen da.
Aidiakapi,
1

Einer der Vorteile, die ich mag, ist die Fähigkeit, einen Teil einer Änderung festzuschreiben. Dh mit git add -e. Ich lege nicht so oft fest, wie ich es manchmal tun sollte, und mit dem Befehl git add -e kann ich meine Änderungen bis zu einem gewissen Grad auflösen.

leed25d
quelle