Git
Chapters ▾ 2nd Edition

7.2 Git Tools - Interaktives Stagen

Interaktives Stagen

In diesem Abschnitt werden Sie einige interaktive Git-Befehle kennenlernen, mit denen Sie Ihre Commits so gestalten können, 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 können Sie sichergehen, dass Ihre Commits in logisch getrennten Changesets vorliegen, die von Ihren Entwicklern leicht überprüft werden können.

Wenn Sie git add mit der Option -i oder --interactive ausführen, 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>

Sie können erkennen, dass dieser Befehl Ihnen eine ganz neue Darstellung Ihrer Staging-Area zeigt, als Sie es gewohnt sind – im Grunde genommen zeigt sie die gleichen Informationen, die Sie mit git status erhalten, aber etwas kompakter und informativer. Es 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 Sie eine Reihe von Aktionen ausführen können, 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 Sie u oder 2 (für Update) an der Eingabeaufforderung What now> eingeben, werden Sie aufgefordert die Dateien anzugeben, die Sie zur Staging-Area hinzufügen möchten:

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, können Sie 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 Sie die Enter-Taste drücken, ohne dass Sie an der Eingabeaufforderung nach Update>> etwas eingegeben haben, übernimmt Git alles, was ausgewählt war und stagt es für Sie:

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 können Sie sehen, dass die Dateien TODO und index.html gestagt sind und die Datei simplegit.rb noch nicht zur Staging-Area hinzugefügt ist. Wenn Sie die TODO`Datei an dieser Stelle unstagen wollen, verwenden Sie 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 Sie sich Ihren Git-Status noch einmal ansehen, sehen Sie, dass Sie die Datei TODO nicht mehr der Staging-Area hinzugefügt ist:

*** 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 Sie gestagt haben, können Sie den Befehl d oder 6 (für diff) verwenden. Er zeigt Ihnen eine Liste Ihrer gestagten Dateien an, aus der Sie auswählen können, für welche Dateien Sie die gestagte Differenz sehen möchten. 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 können Sie den interaktiven Einfügen-Modus nutzen, um Ihre 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 Sie beispielsweise zwei Änderungen an Ihrer Datei simplegit.rb vornehmen und eine davon stagen möchten und die andere nicht, so ist das in Git sehr einfach. Geben Sie auf der gleichen interaktiven Eingabeaufforderung, die im vorherigen Abschnitt erläutert wurde, p oder 5 (für Patch) ein. Git wird Sie fragen, welche Dateien Sie teilweise stagen möchten; dann zeigt es für jeden Abschnitt der ausgewählten Dateien Diffs an und fragt Sie nacheinander, Stück für Stück, was Sie stagen möchten:

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,?]?

Sie haben 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

Im Allgemeinen tippen Sie y oder n, wenn Sie die einzelnen Abschnitte stagen möchten, aber auch das Staging aller Abschnitte in bestimmten Dateien oder das Überspringen einer Abschnitts bis zu einem späteren Zeitpunkt kann sinnvoll sein. Wenn Sie einen Teil der Datei stagen und einen anderen Teil nicht, sieht die Ausgabe Ihres 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 Ihnen, dass ein paar Zeilen gestagt sind und andere nicht. Sie haben diese Datei teilweise zur Staging-Area hinzugefügt. An diesem Punkt können Sie das interaktive Einfüge-Skript verlassen und git commit ausführen, um die teilweise bereitgestellten Dateien zu übertragen.

Sie brauchen auch nicht im interaktiven Einfüge-Modus zu sein, um mit einem Teil der Datei Staging durchzuführen – Sie können das gleiche Skript starten, indem Sie git add -p oder git add --patch auf der Kommandozeile verwenden.

Darüber hinaus können Sie 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.