Letzte Änderung: 26.06.2012 - 15:55 Uhr
Diese Fallstudie wurde unter Ubuntu 10.10 mit git in der Version v1.7.5.1 getestet. Alle hier genannte Kommandos werden in der Bash/dem Terminal/der Konsole ausgeführt. Es gibt auch Tools wie tortoisegit für Windows, auf die hier nicht weiter eingegangen wird.
Diese Seite ist eine Sammlung von git Kommandos und git Workflows.
1 Installation
1.1 Debian/Ubuntu
apt-get install git-core
1.2 Windows
msysgit oder tortoisegit, ggf. mit Cygwin.
1.3 Testen
Eine funktionierende Installation kann einfach getestet werden:
git version
2 Konfiguration
Man kann git global (mit --global) für alle git-Projekte und lokal (ohne --global) je git-Projekt konfigurieren. Zweiteres ist bei Projekten von github.com hilfreich.
2.1 Benutzer
git config --global user.name "Dennis Boldt" git config --global user.email spam@dennis-boldt.de
2.2 Farben
git config --global color.diff true git config --global color.ui true git config --global color.status true
2.3 Zeilenumbrüche
git config --global core.autocrlf input
2.4 Konfiguration anzeigen
git config -l git config --list
Es kann zum Folgenden Fehler kommen:
bash: git-upload-pack: command not found fatal: The remote end hung up unexpectedly
Das Problem - auf Remote/Server-Seite - habe ich wie folgt gelöst:
$ cd /usr/bin/ $ sudo ln -s /[path/to/git]/bin/git* .
2.5 Standard-Editor zum Schreiben der Commit-Nachrichten
git config --global core.editor "nano" git config core.editor "nano"
Man kann sich auch die von git erstelle globale Konfiguration anzeigen lassen
cat ~/.gitconfig
Die projektspezifische Konfiguration findet sich unter
cat .git/config
3 Git Repository anlegen
mkdir ~/git/fallstudie cd ~/git/fallstudie git init --bare --share // Initialized empty shared Git repository in ~/git/fallstudie/
In einem existierendem Projekt (.git-Ordner wird erstellt)
git init --share git add .
4 Git Repository clonen
cd ~/Desktop/ git clone ~/git/fallstudie // warning: You appear to have cloned an empty repository. git clone git://../repo.git git clone ssh://../repo.git cd fallstudie/
5 Eine neue Datei zum "lokalen" Repository hinzufügen
touch README // Datei erstellen nano README // Inhalt: "Das ist ein Test." git status // Untracked files: README git add README // Commit vorbereiten/Datei zum Index/Stage hinzufügen git status // Changes to be committed: new file: README git commit // 1 files changed, 1 insertions(+), 0 deletions(-) git status // nothing to commit (working directory clean)
6 Änderungen zum Remote-Repository hinzufügen
Der initiale Commit sieht wie folgt aus:
git push origin master // [new branch] master -> master
HEAD wir folgt (hier als Linux-Kommando) angelegt werden (Nur nach dem initalien Commit!):echo "ref: refs/remotes/origin/master" > .git/refs/remotes/origin/HEAD
oder
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/master
7 Eine bekannte Datei ändern
nano README // Inhalt: "Das ist ein schöner Test." git status // modified: README git diff // -Das ist ein Test. // +Das ist ein schöner Test. git add README // Commit vorbereiten/Datei zum Index/Stage hinzufügen git status // modified: README git commit // 1 files changed, 1 insertions(+), 1 deletions(-) git status // nothing to commit (working directory clean) git push // 5ae2478..083fd93 master -> master
8 Die Commit Historie anzeigen
git log git log -1 // -5 git log -p // Zeigt alle Änderungen git log --stat // Zeigt die Statistik der Änderungen git log --pretty=oneline git log --reverse
Es können beliebige Kombinationen genutzt werden. Zum Beispiel:
git log --pretty=oneline --stat
9 Ein anderer Benutzer
cd ~/Destkop/ git clone ~/git/fallstudie ./test cd test/ git status // nothing to commit (working directory clean) git log // Wir sollten nun alle bisherigen Änderungen sehen.
9.1 Benutzer lokal konfigurieren
Dies ist auch für github.com notwendig.
git config user.name "Hans Meier" // Achtung: OHNE --global git config user.email hans@meier.de cat .git/config // Überprüfen, ob der neue User stimmt.
9.2 Eine neue Datei hinzufügen
nano TEST // "Ein neuer Test."
git status // Untracked files: TEST
git add TEST
git commit
nano TEST // einige Änderungen.
git add TEST
git commit
git status // nothing to commit (working directory clean)
git push // 083fd93..388d171 master -> master
10 Änderungen aus dem globalen Repository holen
Zurück zum ersten geklonten Verzeichnis "fallstudie"
cd ../fallstudie/
git fetch // 083fd93..388d171 master -> origin/master
git rebase origin // First, rewinding head to replay your work on top of it...
// Fast-forwarded master to origin/master.
Hinweis: In der Regel reicht (nachdem anpassen von HEAD unter 6):
git rebase origin
Falls HEAD nicht richtig gesetzt ist, muss das rebase wie folgt gemacht werden:
git rebase origin/master
1. Workflow: Normales arbeiten mit rebase
// Working,working,working touch FILE git add FILE // Working,working,working git commit ... git commit git fetch git rebase origin git push
2. Workflow: Normales arbeiten mit merge
// Working,working,working touch FILE git add FILE // Working,working,working git commit ... git commit git fetch git merge origin git push
Unterschied zwischen merge und rebase
git rebase scheibt die Historie neu, git merge lässt die History und vereint Branches. Vergleiche diesen Link.
Es gibt auch noch git pull welches das locake Repository gleich den Remote-Repository setz:
git pull == git fetch && git merge origin
git pull --rebase == git fetch && git rebase origin
11 Ein Konflikt
Wir befinden uns noch immer in "fallstudie"
nano README // "Das ist ein wunderschöner Test."
git commit // modified: README
git add README
git commit
git status // nothing to commit (working directory clean)
git push // 388d171..6ebc80e master -> master
Zurück zu "test"
cd ../test/ nano README // "Das ist ein toller Test." git add README git commit
An dieser Stelle haben wir nun zwei verschiedene Versionen. Die vom Benuter "Hans Meier" mit dem Inhalt "Das ist ein wunderschöner Test." im Remote-Repository und die vom Benutzer "Dennis Boldt" mit dem Inhalt "Das ist ein schöner Test." im lokalen Repository. Wird nun versucht die lokale Version ins Remote-Repository zu pushen (git push), kommt es zu dem folgenden Fehler:
! [rejected] master -> master (non-fast-forward) error: failed to push some refs to '/home/dennis/git/fallstudie' ... Merge the remote changes before pushing again.
Dies sagt nichts anderes, als das im Repository eine neuere Version liegt, welche wir abholen müssen.
git fetch // 388d171..6ebc80e master -> origin/master git rebase origin // CONFLICT (content): Merge conflict in README
3. Workflow: Einen Konflikt lösen
git status // both modified: README vi README // "Das ist ein toller und wunderschöner Test." git add README // Vereinigte Datei zu Index/Stage hinzufügen // KEIN COMMIT HIER (in anderen Tutorials steht hier ein Commit. Das ist falsch) git status // modified: README git rebase --continue // Applying: Ein wunderschöner Test oder zum Abbrechen git rebase --abort git push // 6ebc80e..2245a77 master -> master
12 Branches & Merges
Wir befinden uns noch immer in "test"
git branch test // Branch mit dem Namen "test" erstellen git branch // Alle Branches anzeigen // * master // test git checkout test // Switched to branch 'test' git branch // Alle Branches anzeigen // master // * test nano TEST // "Ein spannender Test!" git add TEST git commit // [test 51ee4c1] Ein branch test // 1 files changed, 1 insertions(+), 1 deletions(-) git checkout master // Switched to branch 'master' git merge --no-ff test // Merge made by recursive. // Tipp: IMMER --no-ff benutzen. Warum sehen wir im nächten Abschnitt git push // 2245a77..bb71fd5 master -> master git branch -d test // Deleted branch test (was 99fd86d) git show-branch
13 More fancy Logs
Alle Branches & Merges kann man sich sehr schön mit dem zusatz --graph anzeigen lassen.
git log --graph git log --graph --oneline git log --graph --full-history --all --color --date=short --pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%ad %s" git shortlog git shortlog -n -s git instaweb --httpd=webrick // Git im Browser
14 gitk
Das ultinative Werkzeug für git ist gitk.

15 Rückgängig machen
Ein Hinweis vorweg: Mit git reset vorsichtig sein. Insbesondere die Optionen --soft und --hard funktionieren sehr unterschiedlich.
Wir erzeugen etwas Müll...
echo "test" > README
15.1 Alle Änderungen wegwerfen
git checkout -f git reset --hard git reset --hard HEAD git checkout FILE
15.2 Änderungen an einer einzelnen Datei verwerfen
rm filename // I.d.R. nicht notwendig
git checkout -- filename // Geht i.d.R. auch ohne die --, Problematisch wenn eine Datei
// den gleichen Namen wir ein branch hat.
15.3 Die letzte Commit-Nachricht ändern
Solange der Commit noch nicht im Remote-Repository ist, kann die letzte Commit-Nachricht verändert werden.
git commit --amend
16 Den letzten Commit Rückgängig machen
Solange der Commit noch nicht im Remote-Repository ist, kann der letzte Commit zurückgeholt werden. Im Folgenden bleiben die Änderungen im Working-Tree vorhanden:
git reset --soft HEAD^
HEAD^ steht für den Commit vor HEAD. Wenn man auch die Änderungen verwerfen will, nutzt man:
git reset --hard HEAD^
17 Etwas beim letzen Commit vergessen
1. Version
git reset --soft HEAD^ git add forgot.txt git commit
2. Version
git commit -m 'initial commit' git add forgot.txt git commit --amend
18 Stash
Stash ist etwas besonderes und sehr hilfreiches in git. Änderungen, welche sich noch nicht im Index/Stage befinden können zur Seite gepackt werden, ohne diese zu verlieren. Dies ist dann nützlich, wenn man gerade an einer Datei arbeitet, während dessen aber einem anderen Bug korrigieren muss. Somit packt man die aktuellen Änderungen zur Seite und kann erstmal etwas anderes machen. Außerdem kann man einen Branch erstellen, ohne die Änderungen commiten zu müssen.
git stash git stash list git stash pop git stash apply git stash clear git stash branch <branchname> // Seit git 1.6
4. Workflow: Stash
git stash [fix the bug] git commit -a -m "bug is now fixed" git stash pop
5. Workflow: Normales arbeiten mit Stash
// Working,working,working touch FILE git add FILE // Working,working,working git commit ... git commit git stash git fetch git rebase origin git stash apply git push
19 Tags
Ein Tag in git ist nur ein anderer Name für einen bestimmten Commit.
git tag "v1.3" // Die aktuelle Version als v1.3 bennen. git push --tags
Tags anzeigen lassen:
git fetch --tags git show v1.3 git tag -l git tag -l 'v1*'
Tags löschenn:
git -d v1.3
20 Aliase
Es ist hilfreich, sich für komplexere Kommandos Aliase anzulegen. Einige Beispiele:
git config --global alias.st status git config --global alias.unstage 'reset HEAD --' // git unstage aFile == git reset HEAD aFile git config --global alias.last 'log -1 HEAD'
21 Einen Patch erstellen
Manchmal ist es notwendig Änderungen mit jemanden auszutauschen, welche im Remote-Repository nichts zu suchen haben, oder weil man einfach keinen Schreibzugriff hat. In diesem Fall kann man Patches der letzten Commits erstellen:
git format-patch origin git am PATCHFILE // Genau ein Patch hinzufügen git am *.patch // Alle Patches hinzufügen git am *.patch -i // Alle Patches interaktiv hinzufügen
22 Trailing whitespaces
Es kommt vor, dass man an einigen Zeilen des Commits sogenannte trailing whitspaces hat. Diese kann man mittels eines pre-commit hook entfernen. Dafür erstellt man die Datei .git/hooks/pre-commit und füllt sie wie folgt:
#!/bin/sh if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # Find files with trailing whitespace for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -r 's/:[0-9]+:.*//' | uniq` ; do # Fix them! sed -i 's/[[:space:]]*$//' "$FILE" done exit
23 Einige Kommandos kurz erwähnt
git add -u // Alle geänderten Dateien zum Index/Stage hinzufügen git commit -a -m "all" // Schneller commit aller geänderten Dateien git blame FILE // Zeigt, welche Zeile von welchem Autor verändert wurde git mv file_from file_to // Eine Datei Verschieben/Umbenennen git rm FILE // Eine Datei löschen cat .gitignore // Eine Liste von zu ignorierenden Dateien/Orndern, z.B. ./bin git reset HEAD cake.txt // Eine Datei aus dem Index/Stage holen
24 ...
...
25 Weitere Informationen
- http://git-scm.com/
- http://progit.org/book/
- http://book.git-scm.com/
- http://www.kernel.org/pub/software/scm/git/docs/
- http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html
- http://de.whygitisbetterthanx.com
- http://help.github.com/git-cheat-sheets/ (Nicht allen vertrauen, tlw. basiernd auf älteren Versionen)
- http://jonas.nitro.dk/git/quick-reference.html
- http://de.gitready.com/
- http://www-cs-students.stanford.edu/~blynn/gitmagic/
- http://cworth.org/hgbook-git/tour/
- http://www.siteground.com/tutorials/git/commands.htm