← Zurück zum Blog

Staging pro Zeile: Stagen Sie genau das, was Sie wollen

feature tutorial

Warum granulares Staging wichtig ist

Eine gut gestaltete Git-Historie erzählt eine Geschichte. Jeder Commit repräsentiert eine einzelne logische Änderung: eine Fehlerbehebung, ein Refactoring, ein neues Feature. Aber reale Entwicklung ist selten so ordentlich. Sie beheben einen Bug, bemerken dann einen Tippfehler in der Nähe, passen dann etwas Formatierung an, beginnen dann ein kleines Refactoring -- alles in derselben Datei. Wenn Sie die gesamte Datei auf einmal stagen und committen, erhalten Sie einen Commit, der zusammenhanglose Änderungen vermischt. Das erschwert Code-Reviews, erschwert die Fehlersuche mit bisect und macht die Commit-Historie als Dokumentation weniger nützlich.

Granulares Staging ermöglicht es Ihnen, Ihre Arbeit in sinnvolle Commits aufzuteilen, selbst wenn die Änderungen innerhalb derselben Datei verflochten sind. Anstatt alles auf einmal zu committen, wählen Sie genau aus, welche Änderungen zusammengehören.

Drei Ebenen des Staging

Staging auf Dateiebene

Die grundlegendste Ebene. Sie stagen ganze Dateien mit git add:

git add src/auth.ts src/utils.ts

Das ist ausreichend, wenn jede Datei nur eine logische Änderung enthält. Aber sobald eine Datei mehrere zusammenhanglose Änderungen enthält, ist Staging auf Dateiebene zu grob.

Staging auf Hunk-Ebene

Git kann die Änderungen einer Datei in "Hunks" aufteilen -- zusammenhängende Blöcke geänderter Zeilen, die durch unveränderten Code getrennt sind. Mit git add -p (Patch-Modus) präsentiert Git jeden Hunk einzeln und fragt, ob er gestagt werden soll:

git add -p src/auth.ts

Für jeden Hunk wählen Sie y (stagen), n (überspringen), s (in kleinere Hunks aufteilen) oder e (manuell bearbeiten). Dies ist eine wesentliche Verbesserung gegenüber dem Staging auf Dateiebene, hat aber Grenzen. Hunks werden durch Nähe definiert: Wenn zwei zusammenhanglose Änderungen nahe beieinander liegen (durch weniger als drei Kontextzeilen getrennt), gruppiert Git sie in einen einzelnen Hunk. Sie zu trennen erfordert manuelle Patch-Bearbeitung, was mühsam und fehleranfällig ist.

Staging auf Zeilenebene

Staging auf Zeilenebene ist die präziseste Option. Anstatt mit Dateien oder Hunks zu arbeiten, wählen Sie einzelne Zeilen zum Stagen aus. Sie möchten die Zeilen 12 und 15 stagen, aber nicht Zeile 14? Das geht. Dies gibt Ihnen vollständige Kontrolle darüber, was in jeden Commit kommt, unabhängig davon, wie nahe die Änderungen in der Datei beieinander liegen.

Auf der Kommandozeile bedeutet Staging auf Zeilenebene das manuelle Bearbeiten von Patches mit git add -p und der Option e. Sie müssen das Unified-Diff-Format verstehen, den Patch sorgfältig bearbeiten und hoffen, keine Fehler einzuführen. Es funktioniert, aber es ist nichts, was die meisten Entwickler regelmäßig tun möchten.

Staging auf Zeilenebene in GitSquid

GitSquid macht Staging auf Zeilenebene visuell und unkompliziert. Wenn Sie eine modifizierte Datei auswählen, zeigt der Diff-Viewer jede geänderte Zeile an. Um bestimmte Zeilen zu stagen:

  • Klicken Sie auf eine einzelne Zeile, um sie auszuwählen.
  • Cmd+Click (Ctrl+Click unter Windows/Linux) um mehrere einzelne Zeilen auszuwählen.
  • Shift+Click um einen Zeilenbereich auszuwählen.

Sobald Sie die gewünschten Zeilen ausgewählt haben, stagen Sie sie. Nur diese Zeilen werden dem Index hinzugefügt. Der Rest verbleibt als ungestagete Änderungen in Ihrem Arbeitsverzeichnis, bereit für einen anderen Commit.

Der gleiche Workflow funktioniert auch umgekehrt. Wenn Sie bereits Zeilen gestagt haben, die Sie aus dem Staging-Bereich entfernen möchten, können Sie sie im gestagten Diff auswählen und nur diese Zeilen entstagen.

Wie es unter der Haube funktioniert

Wenn Sie einzelne Zeilen stagen, generiert GitSquid serverseitig einen Patch, der nur die ausgewählten Änderungen enthält. Dieser Patch wird dann mit Gits Patch-Mechanismus auf den Index angewendet. Durch die serverseitige Patch-Generierung statt clientseitiger Diff-Manipulation ist das Ergebnis zuverlässig und entspricht genau dem, was Git erwartet. Es gibt keine Formatierungsprobleme oder Off-by-One-Fehler, die beim manuellen Bearbeiten von Patches auftreten könnten.

Praktische Beispiele

Eine Fehlerbehebung von einem Refactoring trennen

Sie arbeiten an einem Refactoring und bemerken einen Bug. Sie beheben ihn sofort, weil die Lösung offensichtlich ist. Jetzt enthält Ihre Datei zwei Arten von Änderungen: das Refactoring und die Fehlerbehebung. Mit Staging auf Zeilenebene wählen Sie nur die Zeilen der Fehlerbehebung aus, committen sie mit einer klaren Nachricht wie "fix null check in auth validation" und committen dann das Refactoring separat. Das Ergebnis sind zwei saubere, überprüfbare Commits statt einem vermischten.

Debug-Code von Produktionscode trennen

Sie haben console.log-Anweisungen beim Debuggen hinzugefügt, direkt neben den eigentlichen Code-Änderungen. Anstatt sich zu merken, welche Zeilen Debug und welche produktiv sind, wählen Sie visuell nur die Produktionsänderungen aus, stagen sie und committen. Die Debug-Zeilen bleiben in Ihrem Arbeitsverzeichnis, wo Sie sie weiter verwenden oder später entfernen können.

Einen partiellen Commit für die Überprüfung vorbereiten

Sie haben einen großen Satz von Änderungen, aber nur ein Teil der Arbeit ist bereit für die Überprüfung. Staging auf Zeilenebene ermöglicht es Ihnen, die fertigen Teile zu committen, während der Code in Arbeit unverpflichtet bleibt. Ihre Pull Request bleibt fokussiert, und der Reviewer muss sich nicht durch unvollständigen Code arbeiten.

Commits atomar halten

Ein atomarer Commit ist einer, der eine einzelne, vollständige, logische Änderung enthält. Er besteht die Tests, bricht den Build nicht und kann für sich allein verstanden werden. Atomare Commits sind nicht nur eine Frage der Ordnung. Sie haben praktische Vorteile:

  • Code-Review. Reviewer können jeden Commit unabhängig verstehen. Ein Commit mit dem Titel "fix input validation", der nur Validierungslogik berührt, ist leicht zu überprüfen. Ein Commit mit dem Titel "various changes", der Validierung, Styling und Konfiguration berührt, ist es nicht.
  • Fehlersuche. Wenn etwas kaputt geht, kann git bisect den genauen Commit identifizieren, der das Problem eingeführt hat. Atomare Commits machen das Ergebnis aussagekräftig: Sie finden die spezifische Änderung, die den Bug verursacht hat, nicht ein Sammelsurium zusammenhangloser Modifikationen.
  • Revert. Wenn ein Commit revertiert werden muss, kann ein atomarer Commit sauber revertiert werden. Ein gemischter Commit könnte Sie zwingen, Änderungen zu revertieren, die Sie eigentlich behalten wollten.
  • Historie als Dokumentation. Monate später, wenn jemand die Commit-Historie liest, um zu verstehen, warum ein Stück Code existiert, erzählen atomare Commits mit klaren Nachrichten eine nützliche Geschichte.

Staging auf Zeilenebene ist das Werkzeug, das atomare Commits praktikabel macht. Ohne es erfordert das Erstellen sauberer Commits aus unordentlicher realer Entwicklung Disziplin und manuellen Aufwand. Mit ihm ist der Prozess so einfach wie das Auswählen der Zeilen, die zusammengehören.

Die besten Commits sind die, die genau eine Sache tun. Granulares Staging gibt Ihnen die Kontrolle, um das zu erreichen, auch wenn Ihr Arbeitsverzeichnis eine andere Geschichte erzählt.