-
1. Erste Schritte
-
2. Git Grundlagen
-
3. Git Branching
- 3.1 Branches auf einen Blick
- 3.2 Einfaches Branching und Merging
- 3.3 Branch-Management
- 3.4 Branching-Workflows
- 3.5 Remote-Branches
- 3.6 Rebasing
- 3.7 Zusammenfassung
-
4. Git auf dem Server
- 4.1 Die Protokolle
- 4.2 Git auf einem Server einrichten
- 4.3 Erstellung eines SSH-Public-Keys
- 4.4 Einrichten des Servers
- 4.5 Git-Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Von Drittanbietern gehostete Optionen
- 4.10 Zusammenfassung
-
5. Verteiltes Git
-
6. GitHub
-
7. Git Tools
- 7.1 Revisions-Auswahl
- 7.2 Interaktives Stagen
- 7.3 Stashen und Bereinigen
- 7.4 Ihre Arbeit signieren
- 7.5 Suchen
- 7.6 Den Verlauf umschreiben
- 7.7 Reset entzaubert
- 7.8 Fortgeschrittenes Merging
- 7.9 Rerere
- 7.10 Debuggen mit Git
- 7.11 Submodule
- 7.12 Bundling
- 7.13 Replace (Ersetzen)
- 7.14 Anmeldeinformationen speichern
- 7.15 Zusammenfassung
-
8. Git einrichten
- 8.1 Git Konfiguration
- 8.2 Git-Attribute
- 8.3 Git Hooks
- 8.4 Beispiel für Git-forcierte Regeln
- 8.5 Zusammenfassung
-
9. Git und andere Systeme
- 9.1 Git als Client
- 9.2 Migration zu Git
- 9.3 Zusammenfassung
-
10. Git Interna
-
A1. Anhang A: Git in anderen Umgebungen
- A1.1 Grafische Schnittstellen
- A1.2 Git in Visual Studio
- A1.3 Git in Visual Studio Code
- A1.4 Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git in Sublime Text
- A1.6 Git in Bash
- A1.7 Git in Zsh
- A1.8 Git in PowerShell
- A1.9 Zusammenfassung
-
A2. Anhang B: Git in Ihre Anwendungen einbetten
- A2.1 Die Git-Kommandozeile
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Anhang C: Git Kommandos
- A3.1 Setup und Konfiguration
- A3.2 Projekte importieren und erstellen
- A3.3 Einfache Snapshot-Funktionen
- A3.4 Branching und Merging
- A3.5 Projekte gemeinsam nutzen und aktualisieren
- A3.6 Kontrollieren und Vergleichen
- A3.7 Debugging
- A3.8 Patchen bzw. Fehlerkorrektur
- A3.9 E-mails
- A3.10 Externe Systeme
- A3.11 Administration
- A3.12 Basisbefehle
7.3 Git Tools - Stashen und Bereinigen
Stashen und Bereinigen
Oft, wenn Sie an einem Teil Ihres Projekts gearbeitet haben, ist es in einem unordentlichen Zustand. Sie wollen jetzt den Branch für eine gewisse Zeit wechseln, um an etwas anderem zu arbeiten.
Das Problem ist, dass Sie keinen Commit mit halbfertiger Arbeit machen wollen, nur um später an diesen Punkt zurückkehren zu können.
Die Antwort auf dieses Problem ist der Befehl git stash
.
Stashing nimmt den unsauberen Zustand Ihres Arbeitsverzeichnisses – das heißt, Ihre geänderten getrackten Dateien und gestagten Änderungen – und speichert ihn in einem Stapel unvollendeter Änderungen, die Sie jederzeit (auch auf einen anderen Branch) wieder anwenden können.
Anmerkung
|
Migrieren zu
git stash push
Ende Oktober 2017 gab es eine ausführliche Diskussion innerhalb der Git-Mailingliste, bei der der Befehl
|
Ihre Arbeit stashen
Um das Stashen zu demonstrieren, gehen Sie in Ihr Projekt und beginnen Sie mit der Arbeit an ein paar Dateien. Sie können dann eine der Änderungen der Staging-Area hinzufügen.
Wenn Sie git status
ausführen, können Sie den schlechten Status sehen:
$ git status
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
Sie möchten nun den Branch wechseln, aber Sie wollen das bisherige noch nicht committen, also werden Sie die Änderungen stashen.
Um einen neuen Stash in Ihren Stack zu verschieben, führen Sie git stash
oder git stash push
aus:
$ git stash
Saved working directory and index state \
"WIP on master: 049d078 Create index file"
HEAD is now at 049d078 Create index file
(To restore them type "git stash apply")
Sie sehen dann, dass Ihr Arbeitsverzeichnis bereinigt ist:
$ git status
# On branch master
nothing to commit, working directory clean
An dieser Stelle können Sie die Branches wechseln und anderswo arbeiten. Ihre Änderungen werden auf Ihrem Stack gespeichert.
Um zu sehen, welche Stashes Sie gespeichert haben, können Sie git stash list
verwenden:
$ git stash list
stash@{0}: WIP on master: 049d078 Create index file
stash@{1}: WIP on master: c264051 Revert "Add file_size"
stash@{2}: WIP on master: 21d80a5 Add number to log
Hier wurden vorher schon zwei Stashes gespeichert, so dass Sie Zugriff auf drei verschiedene gestashte Arbeiten haben.
Sie können den soeben versteckten Stash erneut aufrufen, indem Sie den Befehl verwenden, der in der Hilfe-Anzeige des ursprünglichen Stash-Befehls angezeigt wird: git stash apply
.
Wenn Sie einen der früheren Stashes anwenden möchten, können Sie ihn durch einen Namen angeben, etwa so: git stash apply stash@{2}
.
Wenn Sie keinen Stash angeben, nimmt Git den neuesten Stash und versucht, ihn zu übernehmen:
$ git stash apply
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: index.html
modified: lib/simplegit.rb
no changes added to commit (use "git add" and/or "git commit -a")
Sie können feststellen, dass Git die Dateien, die Sie beim Speichern des Stashes zurückgesetzt haben, erneut modifiziert. So hatten Sie ein sauberes Arbeitsverzeichnis, als Sie versuchten, den Stash anzuwenden den Sie auf den gleichen Branch anwenden wollten, aus dem Sie ihn erzeugt hatten. Ein sauberes Arbeitsverzeichnis und dessen Anwendung auf denselben Branch sind nicht nötig, um einen Stash erfolgreich anzulegen. Sie können einen Stash in einem Branch speichern, später in einen anderen Branch wechseln und erneut versuchen, die Änderungen zu übernehmen. Sie können auch geänderte und nicht übertragene Dateien in Ihrem Arbeitsverzeichnis haben, wenn Sie einen Stash anwenden – Git meldet Ihnen Merge-Konflikte, wenn etwas nicht mehr sauber funktioniert.
Die Änderungen an Ihren Dateien wurden erneut angewendet, aber die Datei, die Sie zuvor bereitgestellt haben, wurde nicht neu eingestellt.
Um das zu erreichen, müssen Sie den Befehl git stash apply
mit der Option --index
ausführen und so dem Befehl anweisen, dass er versuchen soll, die gestagten Änderungen erneut anzuwenden.
Hätten Sie stattdessen diesen Befehl ausgeführt, wären Sie an Ihre ursprüngliche Position zurückgekehrt:
$ git stash apply --index
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
Die apply-Option versucht nur, die gestashte Arbeit zu übernehmen – Sie haben sie weiterhin in Ihrem Stack.
Um sie zu entfernen, kann man git stash drop
mit dem Namen des zu entfernenden Stashes ausführen:
$ git stash list
stash@{0}: WIP on master: 049d078 Create index file
stash@{1}: WIP on master: c264051 Revert "Add file_size"
stash@{2}: WIP on master: 21d80a5 Add number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
Man kann auch git stash pop
ausführen, um den Stash einzubringen und ihn dann sofort vom Stack zu entfernen.
Kreatives Stashing
Es gibt ein paar Stash-Varianten, die ebenfalls nützlich sein können.
Die erste, recht beliebte Option ist die --keep-index
Option zum git stash
Befehl.
Diese weist Git an, nicht nur alle bereitgestellten Inhalte in den zu erstellenden Stash aufzunehmen, sondern sie gleichzeitig im Index zu belassen.
$ git status -s
M index.html
M lib/simplegit.rb
$ git stash --keep-index
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file
$ git status -s
M index.html
Eine weitere gebräuchliche Funktion von stash ist die Ablage der nicht getrackten sowie der getrackten Dateien.
Standardmäßig wird git stash
nur modifizierte und gestagte, getrackte Dateien aufnehmen.
Wenn Sie --include-untracked
oder -u
angeben, wird Git ungetrackte Dateien in den zu erstellenden Stash einschließen.
Trotzdem wird das Einfügen von nicht getrackten Dateien in den Stash weiterhin keine explizit zu ignorierenden Dateien enthalten; um zusätzlich ignorierte Dateien einzubeziehen, verwenden Sie --all
(oder nur -a
).
$ git status -s
M index.html
M lib/simplegit.rb
?? new-file.txt
$ git stash -u
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file
$ git status -s
$
Schließlich, wenn Sie das --patch
Flag angeben, wird Git nicht alles, was modifiziert wurde, in den Stash aufnehmen, sondern Sie interaktiv fragen, welche der Änderungen Sie sicher verwahren wollen und welche Sie noch in Ihrem Arbeitsverzeichnis behalten möchten.
$ git stash --patch
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 66d332e..8bb5674 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -16,6 +16,10 @@ class SimpleGit
return `#{git_cmd} 2>&1`.chomp
end
end
+
+ def show(treeish = 'master')
+ command("git show #{treeish}")
+ end
end
test
Stash this hunk [y,n,q,a,d,/,e,?]? y
Saved working directory and index state WIP on master: 1b65b17 added the index file
Einen Branch aus einem Stash erzeugen
Wenn Sie etwas Arbeit stashen, sie eine Weile dort belassen und dann auf dem Branch weiter machen wollen, aus dem Sie die Arbeit gebunkert haben, könnten Sie ein Problem bekommen, die Arbeit wieder aufzunehmen.
Wenn man versucht, eine Datei zu ändern, die man zwischenzeitlich schon bearbeitet hatte, erhält man einen Merge-Konflikt und muss versuchen, diesen aufzulösen.
Wenn Sie einen einfacheren Weg bevorzugen, um die gespeicherten Änderungen noch einmal zu testen, könnten Sie git stash branch <new branchname>
ausführen, der einen neuen Branch mit dem gewählten Branch-Namen für Sie erzeugt, die Übertragung, an der Sie gerade waren, auscheckt, Ihre Arbeit dort wieder einsetzt und dann den Stash verwirft, wenn er erfolgreich angewendet wird:
$ git stash branch testchanges
M index.html
M lib/simplegit.rb
Switched to a new branch 'testchanges'
On branch testchanges
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
Dropped refs/stash@{0} (29d385a81d163dfd45a452a2ce816487a6b8b014)
Das ist ein interessanter Weg, mit dem man die gestashten Arbeiten leicht wiederherstellen und in einem neuen Branch bearbeiten kann.
Bereinigung des Arbeitsverzeichnisses
Letztendlich möchten Sie vielleicht einige Arbeiten oder Dateien nicht in Ihrem Arbeitsverzeichnis ablegen, sondern sie einfach nur loswerden; dafür ist der Befehl git clean
gedacht.
Einige gängige Fälle, in denen Sie Ihr Arbeitsverzeichnis bereinigen müssen, sind das Entfernen von überflüssigem Programmcode, der durch Merges oder externe Tools erzeugt wurde oder das Entfernen von Build-Artefakten, um einen sauberen Aufbau zu ermöglichen.
Sie sollten mit diesem Befehl sehr vorsichtig sein, da er darauf ausgelegt ist, Dateien aus Ihrem Arbeitsverzeichnis zu entfernen, die nicht getrackt werden.
Wenn Sie Ihre Absicht ändern, gibt es oft keine Möglichkeit mehr, den Inhalt dieser Dateien wiederherzustellen.
Eine bessere Option ist, git stash --all
auszuführen um alles zu entfernen, aber es in einem Stash zu speichern.
Angenommen, Sie wollen unerwünschte Dateien entfernen oder Ihr Arbeitsverzeichnis bereinigen, dann können Sie das mit git clean
erledigen.
Um alle ungetrackten Dateien in Ihrem Arbeitsverzeichnis zu entfernen, können Sie git clean -f -d
ausführen, das alle Dateien entfernt, auch aus Unterverzeichnissen, die dadurch leer werden.
Das -f bedeutet „force“ (dt. „erzwingen“ oder „unbedingt ausführen“) und wird benötigt, falls die Git-Konfigurationsvariable clean.requireForce
explizit nicht auf false gesetzt ist.
Wenn Sie einmal wissen wollen, was der Befehl bewirken könnte, dann führen Sie ihn mit der Option --dry-run
(oder -n
) aus. Das bedeutet: „Mach einen Probelauf und berichte mir, was du gelöscht hättest“.
$ git clean -d -n
Would remove test.o
Would remove tmp/
Standardmäßig entfernt der Befehl git clean
nur die ungetrackten Dateien, die nicht ignoriert werden.
Jede Datei, die mit einem Suchmuster in Ihrer .gitignore
oder anderen Ignore-Dateien übereinstimmt, wird nicht entfernt.
Wenn Sie diese Dateien ebenfalls entfernen wollen, z.B. um alle .o
Dateien zu entfernen, die von einem Build erzeugt wurden, damit Sie einen vollständig sauberen Build machen können, können Sie dem clean-Befehl ein -x
hinzufügen.
$ git status -s
M lib/simplegit.rb
?? build.TMP
?? tmp/
$ git clean -n -d
Would remove build.TMP
Would remove tmp/
$ git clean -n -d -x
Would remove build.TMP
Would remove test.o
Would remove tmp/
Wenn Sie nicht wissen, was der git clean
Befehl bewirken wird, führen Sie ihn immer mit einem -n
aus, um ihn zu überprüfen, bevor Sie das -n
in ein -f
ändern und ihn dann wirklich ausführen.
Der andere Weg, wie Sie sich vorsehen können, ist den Prozess mit dem -i
oder „interactive“ Flag auszuführen.
Dadurch wird der Clean-Befehl im interaktiven Modus ausgeführt.
$ git clean -x -i
Would remove the following items:
build.TMP test.o
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit
6: help
What now>
Auf diese Weise können Sie jede Datei einzeln durchgehen oder interaktiv den zu löschenden Pattern festlegen.
Anmerkung
|
Es gibt eine ungewöhnliche Situation, in der man Git besonders energisch auffordern muss, das Arbeitsverzeichnis zu bereinigen.
Wenn Sie sich in einem Arbeitsverzeichnis befinden, unter dem Sie andere Git-Repositorys (vielleicht als Submodule) kopiert oder geklont haben, wird selbst |