Git
Chapters ▾ 2nd Edition

7.2 Git Tools - Interaktives Stagen

Interaktives Stagen

In diesem Abschnitt wirst du einige interaktive Git-Befehle kennenlernen, mit denen du deine Commits so gestalten kannst, dass sie nur bestimmte Kombinationen und Teile von Dateien enthalten. Diese Tools sind nützlich, um zu entscheiden, ob eine Vielzahl von umfassend modifizierten Dateien in mehrere gezielte Commits aufgeteilt oder in einem großen unübersichtlichen Commit übertragen werden sollen. Auf diese Weise kannst du sicherstellen, dass deine Commits in logisch getrennten Changesets vorliegen, die von deinen Entwicklern leichter überprüft werden können.

Wenn du git add mit der Option -i oder --interactive ausführst, wechselt Git in einen interaktiven Shell-Modus, der so etwas wie das folgende anzeigt:

$ git add -i
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:    unchanged        +1/-1 index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now>

Du kannst erkennen, dass dieser Befehl dir eine ganz neue Darstellung deiner Staging-Area zeigt, als du es gewohnt bist. Im Grunde genommen zeigt er die gleichen Informationen, die du mit git status erhältst, aber etwas kompakter und informativer. Er listet auf der linken Seite die gestagten und auf der rechten Seite die nicht gestagten Änderungen auf.

Danach folgt der Bereich „Commands“ (Befehle), in dem du eine Reihe von Aktionen ausführen kannst, wie z.B. Staging und Unstaging von Dateien, Staging von Teilen von Dateien, Hinzufügen von nicht getrackten Dateien und das Anzeigen von Diffs (Unterschieden) der zuvor gestagten Dateien.

Staging und Unstaging von Dateien

Wenn du u oder 2 (für Update) an der Eingabeaufforderung What now> eingibst, wirst du aufgefordert die Dateien anzugeben, die du zur Staging-Area hinzufügen möchtest:

What now> u
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:    unchanged        +1/-1 index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Update>>

Um die Dateien TODO und index.html zu stagen, kannst du die entsprechenden Ziffern eingeben:

Update>> 1,2
           staged     unstaged path
* 1:    unchanged        +0/-1 TODO
* 2:    unchanged        +1/-1 index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Update>>

Das * (Sternchen) neben den Dateien bedeutet, dass die Datei zum Stagen ausgewählt wurde. Wenn du die Enter-Taste drückst, ohne dass du an der Eingabeaufforderung nach Update>> etwas eingegeben hast, übernimmt Git alles, was ausgewählt ist und stagt es:

Update>>
updated 2 paths

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> s
           staged     unstaged path
  1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

Jetzt kannst du sehen, dass die Dateien TODO und index.html gestagt sind und die Datei simplegit.rb noch nicht zur Staging-Area hinzugefügt ist. Wenn du die Datei TODO an dieser Stelle unstagen möchtest, verwendest du die Option r oder 3 (für revert/rückgängig):

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Revert>> 1
           staged     unstaged path
* 1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Revert>> [enter]
reverted one path

Wenn du dir deinen Git-Status noch einmal anschaust, siehst du, dass du die Datei TODO unstaged hast:

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> s
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

Um den Diff von dem zu sehen, was du gestagt hast, kannst du den Befehl d oder 6 (für diff) verwenden. Er zeigt dir eine Liste deiner gestagten Dateien an, aus der du auswählen kannst, für welche Dateien du die gestagte Differenz sehen möchtest. Das ist so ähnlich wie die Angabe von git diff --cached auf der Kommandozeile:

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> d
           staged     unstaged path
  1:        +1/-1      nothing index.html
Review diff>> 1
diff --git a/index.html b/index.html
index 4d07108..4335f49 100644
--- a/index.html
+++ b/index.html
@@ -16,7 +16,7 @@ Date Finder

 <p id="out">...</p>

-<div id="footer">contact : support@github.com</div>
+<div id="footer">contact : email.support@github.com</div>

 <script type="text/javascript">

Mit diesen grundlegenden Befehlen kannst du den interaktiven Einfügen-Modus nutzen, um deine Staging-Area etwas komfortabler zu verwalten.

Staging von Patches

Es ist auch möglich, dass Git nur bestimmte Teile der Dateien stagt, ohne die restlichen Teile. Wenn du beispielsweise zwei Änderungen an deiner Datei simplegit.rb vornimmst und eine davon stagen möchtest und die andere nicht, so ist das in Git sehr einfach. Gib auf der gleichen interaktiven Eingabeaufforderung, die im vorherigen Abschnitt erläutert wurde, p oder 5 (für Patch) ein. Git wird dich fragen, welche Dateien du teilweise stagen möchtest. Anschließend zeigt es für jeden Abschnitt der ausgewählten Dateien Diffs an und fragt dich nacheinander, Stück für Stück, was du stagen möchtest:

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index dd5ecc4..57399e0 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -22,7 +22,7 @@ class SimpleGit
   end

   def log(treeish = 'master')
-    command("git log -n 25 #{treeish}")
+    command("git log -n 30 #{treeish}")
   end

   def blame(path)
Stage this hunk [y,n,a,d,/,j,J,g,e,?]?

Du hast an dieser Stelle viele Möglichkeiten. Die Eingabe von ? zeigt eine Auflistung aller Aktionen, die durchführbar sind:

Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ?
y - stage this hunk
n - do not stage this hunk
a - stage this and all the remaining hunks in the file
d - do not stage this hunk nor any of the remaining hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

Normalerweise tippst du y oder n, wenn du die einzelnen Abschnitte stagen möchtest. Auch das Staging aller Abschnitte in bestimmten Dateien oder das Überspringen einer Abschnitts bis zu einem späteren Zeitpunkt kann sinnvoll sein. Wenn du einen Teil der Datei stagen möchtest und einen anderen Teil nicht, sieht die Ausgabe deines Status so aus:

What now> 1
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:        +1/-1      nothing index.html
  3:        +1/-1        +4/-0 lib/simplegit.rb

Der Status der Datei simplegit.rb ist sehr interessant. Es zeigt dir, dass ein paar Zeilen gestagt sind und andere nicht. Du hast diese Datei teilweise zur Staging-Area hinzugefügt. An diesem Punkt kannst du das interaktive Einfüge-Skript verlassen und git commit ausführen, um die teilweise bereitgestellten Dateien zu committen.

Du brauchst auch nicht im interaktiven Einfüge-Modus zu sein, um mit einem Teil der Datei Staging durchzuführen. Du kannst das gleiche Skript starten, indem du git add -p oder git add --patch auf der Kommandozeile verwendest.

Darüber hinaus kannst du den Patch-Modus verwenden, um Dateien mit dem Befehl git reset --patch teilweise zurückzusetzen, um Teile von Dateien mit dem Befehl git checkout --patch auszuchecken und um Teile von Dateien mit dem Befehl git stash save --patch zu speichern. Wir werden auf jeden dieser Befehle näher eingehen, wenn wir zu komplexeren Anwendungen dieser Befehle kommen.

scroll-to-top