Git
Spickzettel für die Versionsverwaltung Git.
Weblinks
- Offizielles Git-Handbuch
- Das Git-Community-Buch
- Quick-Start für Umsteiger von SVN (Falls Link nicht gehen sollte: alte Version).
- Anderes Cheat-Sheet: http://cheat.errtheblog.com/s/git
- Blog-Artikel How to create and apply a patch with Git
- Subtree (TODO einarbeiten):
Tägliches Arbeiten
Lokales Repo aktualisieren:
git pull
Lokales Repo aktualisieren mit Rebase statt Merge:
git pull --rebase
Entferntes Repo aktualisieren:
git push
Status zeigen:
git status
Dateien ignorieren:
echo "filename" > .gitignore
Interaktiv per Diff Code-Teile zum commit vormerken:
git add -p
Dateien hinzufügen (= zum commit vormerken):
git add filename
Alles hinzufügen aber trotzdem im Diff anzeigen:
git add -N .
Datei doch nicht in commit aufnehmen (git add
rückgängig machen):
git reset filename
Datei reverten:
git checkout filename
Gelöschte Datei wieder herstellen:
git checkout HEAD^ filename
Diff anzeigen - Änderungen, die noch nicht staged (also für den Commit vorgesehen) sind:
git diff
Diff anzeigen - Änderungen, die mit "git commit" (ohne -a) committed würden:
git diff --cached
Diff anzeigen - Änderungen, die mit "git commit -a" committed würden:
git diff HEAD
Die letzte commit-Message ändern oder Dateien zum letzten Commit hinzufügen:
git commit --amend
Letzten Commit rückgängig machen (Details siehe Quelle):
git reset --soft HEAD^
Ins lokale Repo commiten:
git commit -m "Commit message"
Ins lokale Repo commiten und alles adden (Achtung: Neue Dateien werden nicht geaddet):
git commit -am "Commit message"
Graphische Oberfläche anzeigen:
gitk
Dateien entfernen (vor erstem Commit):
git rm --cached filename
Verzeichnisse entfernen (vor erstem Commit):
git rm --cached -r dirname
Diff einer eingecheckten Revision anzeigen:
git show <rev>
Git-Repo prüfen:
git fsck
Garbage Collection durchführen - entfernt staged, aber nie committete Dateien (dangling blob) und Commits, die nicht im Baum hängen (dangling commits):
git gc
Branchen und mergen
Details siehe Basic Branching and Merging
git branch experimental # Neuen Branch anlegen
git branch # Vorhandene Branches anzeigen
git checkout experimental # Zu anderem Branch wechseln
git commit -am "Bla" # Commit im Branch experimental
git checkout master # Zum Master-Branch wechseln
git commit -am "Blubb" # Commit im Master-Branch
git merge experimental # Branch experimental in master hinein mergen
git diff # Eventuelle Konflikte anzeigen
git commit -am "Blablubb" # Konfliktlösung committen
gitk # History ansehen
git branch -d experimental # Branch experimental löschen
Branch pushen:
git push -u origin mybranch
Alle Branches (auch Remote-Branches) anzeigen:
git branch -a
Remote-Branch auschecken:
git checkout -b mybranch origin/mybranch
Remote-Branch löschen:
git push origin --delete mybranch
Branch mergen ohne Auto-Commit (So dass man den Merge noch bearbeiten kann):
git merge mybranch --no-commit --no-ff
Merge abbrechen:
git reset --hard HEAD
Branch auf bestimmten Commit setzen:
git checkout mybranch
git reset --hard 1258f0d0aae
Taggen
Tag erstellen:
git tag mytag
Tag verschieben:
git tag -f mytag
git push --tags
Tag in Remote-Repo löschen:
git tag -d mytag
git push origin :refs/tags/mytag
Tag umbenennen:
git tag new old
git tag -d old
git push origin :refs/tags/old
git push --tags
Stashen
Stash schnell erstellen (alle Dateien außer neue):
git stash
Stash mit Beschreibung erstellen (alle Dateien außer neue):
git stash save 'My description'
Stash erstellen, 'staged' Dateien behalten (-k
für 'keep index'):
git stash save -k 'My description'
Stash erstellen mit allen Dateien (-u
für 'untracked'):
git stash save -u 'My description'
Stash-Stack ansehen:
git stash list
Letzten Stash zurückholen:
git stash pop
Patchen
Details siehe Blog-Artikel Patch-Workflows: git format-patch, git apply-patch, git am
Patch aus Änderungen im aktuellen Arbeitsverzeichnis erzeugen:
git diff --cached > mypatch.patch
"Normalen" Patch anwenden (ohne Mail-Header, also ohne Commit-Message und Autor):
git apply mypatch.patch
Patch Series erzeugen (als Mail - mit Commit-Message und Autor):
git format-patch -M [rev1]..[rev2]
Patch-Mails anwenden (am
= apply mail - übernimmt Commit-Message und Autor):
git am < 0001-first-change.patch
git am < 0002-next-change.patch
...
3-Wege-Merge, wenn sich Patch-Mail nicht anwenden lässt:
git am -3 < 0001-first-change.patch
Repo anlegen
Repo anlegen (lokal):
cd myproject
git init
git add .
Repo anlegen (auf Server):
cd www-data/my-dav
sudo -u www-data mkdir my-new-repo.git
cd my-new-repo.git
sudo -u www-data git --bare init
sudo -u www-data git --bare update-server-info
mv hooks/post-update.sample hooks/post-update
Repo klonen (von Server nach lokal):
export GIT_SSL_NO_VERIFY=1
git clone https://<server-host>/some/path/my-repo.git
Entferntes Repo das erste mal aktualisieren (nach Fehlermeldung "No refs in common and none specified; doing nothing."):
git push origin master
Remote-Repo aus einem lokalen Repo erstellen
Details siehe Create a new Git Remote Repository from some local files (or local git repository)
Leeres Remote-Repo anlegen:
mkdir /path/to/new-remote-repo.git
cd /path/to/new-remote-repo.git
git --bare init
Remote-Repo bei lokalem Repo anmelden:
cd /path/to/existing-local-repo
git remote add origin /path/to/new-remote-repo.git
Nur Master-Branch pushen:
git push -u origin master
Alle Branches pushen:
git push origin --all
Alle Tags pushen:
git push origin --tags
Remote-Repo umstellen
URL des Remote-Repo anzeigen:
git remote -v
URL des Remote-Repo ändern:
git remote set-url origin myuser@myserver:/path/to/remote-repo.git
Fork-Repo erstellen
Quelle: Keeping a fork up to date
Fork klonen:
git clone https://github.com/myuser/myforkrepo.git
Original-Repo in Fork-Repo als Remote eintragen und "importieren":
cd into/cloned/fork-repo
git remote add upstream https://github.com/otheruser/originalrepo.git
git fetch upstream
Eingetragene Remotes (origin und upstream) anzeigen:
git remote -v
Fork-Main-Branch anlegen und nach origin pushen:
git checkout [rev]
git branch my-main
git push -u origin my-main
Fork aktualisieren:
git checkout main
git fetch upstream
git fetch origin
git pull upstream main
git push
Submodules
Details siehe:
- Kapitel "Submodules" im Git Book
- Blog-Artikel Using submodules in Git
- Stack-Overflow über Submodules mit SSH-Nutzernamen
Submodule zu lokalem Repo hinzufügen:
git submodule add /path/to/lib-repo.git path/to/submodule
Diff mit schönerem Output für Submodules anzeigen:
git diff --submodule
Submodules bei bereits bestehendem lokalen Repo auschecken:
git submodule update --init
Repo zusammen mit Submodules auschecken:
git clone --recurse-submodules /path/to/remote-repo.git
Submodule aktualisieren (master-Branch):
git submodule update --remote name-of-submodule
Anzeigen, welchen Commit Submodule verwendet:
git submodule
Submodule auf anderen Commit umstellen:
cd path/to/submodule
git checkout hash-of-commit
Submodule auf anderen Branch umstellen:
git config -f .gitmodules submodule.name-of-submodule.branch name-of-branch
git submodule update --remote
Submodule entfernen (Details siehe stackoverflow):
git submodule deinit -f -- path/to/submodule
rm -rf .git/modules/path/to/submodule
git rm -f path/to/submodule
git status
um Informationen zu Submodules erweitern:
git config status.submodulesummary 1
Nutzer umstellen
Nutzername und Mail-Adresse für ein Repo ändern (für künftige Commits):
cd myrepo
git config user.name "Tim Buktu"
git config user.email "tim@example.com"
Nutzername und Mail-Adresse global ändern (für künftige Commits):
git config --global user.name "Tim Buktu"
git config --global user.email "tim@example.com"
Nutzername und Mail-Adresse bei bestehenden Commits ändern:
git filter-branch --commit-filter 'if [ "$GIT_AUTHOR_EMAIL" = "otto@example.com" ]; then
export GIT_AUTHOR_NAME="Tim Buktu";
export GIT_AUTHOR_EMAIL=tim@example.com;
export GIT_COMMITTER_NAME="Tim Buktu";
export GIT_COMMITTER_EMAIL=tim@example.com;
fi; git commit-tree "$@"'
Commits squashen
Beschreibung: http://www.gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html
Interaktives Rebase starten:
git rebase -i HEAD~5
Installation
Mac - Client
Mit Homebrew:
brew install git
Ubuntu - Client
Kommandozeilen-Client unter Ubuntu:
sudo apt-get install git-core
Konfiguration
git auf englisch umstellen:
echo "alias git='LANG=en_US.UTF-8 git'" >> ~/.bashrc
Farbige Konsolenausgabe aktivieren:
git config --global color.ui auto
Eigene Benutzerdaten festlegen:
git config --global user.name "Your Name"
git config --global user.email you@example.com
Unter Mac verhindern, dass man ständig das Passwort eingeben muss:
Datei ~/.ssh/config
mit folgendem Inhalt anlegen (Quelle):
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa
Client für HTTP-Repository konfigurieren
Datei ~/.netrc
mit folgendem Inhalt anlegen (sonst muss man sehr oft das Passwort angeben):
machine <server-host>
login <username>
password <password>
Dateirechte anpassen:
chmod 600 ~/.netrc
Entfertes Repo klonen:
git clone https://<server-host>/some/path/my-repo.git
Wenn GIT wegen dem SSL-Zertifikat rumnervt, kann man GIT dazu veranlassen, es nicht zu prüfen:
export GIT_SSL_NO_VERIFY=1
Ubuntu - Shared repository über https
Anleitung angelehnt an: http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt
Verzeichnis einrichten, das über WebDAV erreichbar ist. Im folgenden heißt dieses Verzeichnis www-data/my-dav
.
Neues, leeres Git-Repository anlegen:
cd www-data/my-dav
sudo -u www-data mkdir my-new-repo.git
cd my-new-repo.git
sudo -u www-data git --bare init
Danach:
sudo -u www-data git --bare update-server-info
mv hooks/post-update.sample hooks/post-update