Inhaltsverzeichnis

Git

Branches anlegen

Branches löschen

Angelegte Branches müssen lokal und auf dem Server separat gelöscht werden.

Lokal:

git checkout master
git branch -d <branchname>

Auf dem Server:

git push origin :<branchname>

Branches umbenennen

Stellt man während der Arbeit fest, dass der Branchname nicht gut passt, lassen sich lokale Branches einfach umbenennen:

git branch -m old_branch new_branch

Staging

git add -A #alle Änderungen in den Stagingbereich übernehmen
git add .  #neue und geänderte (keine gelöschten) Dateien in Stagingbereich übernehmen
git add -u #geänderte und gelöschte (keine neuen) Dateien in Stagingbereich übernehmen

Nur Teile einer Datei stagen

Um nur einen Teil der Änderungung in einer Datei zu stagen, gibt es den Befehl

git add -p filename.x
TasteBedeutung
s teilt in kleinere Teile
y staged den aktuellen Teil
n aktuellen Teil nicht stagen
? Hilfe

Lokales Git Repo auf Server pushen

Hat man ein lokales Git-Repo, kann man es mit

git remote add origin https://server/user/repo.git
git push -u origin master # --all für alle lokalen Branches

auf den Server pushen. Wichtig ist das -u beim push, dann wird der branch getrackt. Das bedeutet, das Änderungen vom Server auch wieder zurück in das lokale Repo übernommen werden.

Farbige Ausgabe

Um die farbige Ausgabe global zu aktivieren:

git config --global color.ui true

Nur aktuellen Branch pushen

Ein „git push“ in der Standardeinstellung pusht alle lokalen Branches. Möchte man mit git push nur den aktuellen Branch pushen, kann man git entsprechend konfigurieren:

git config --global push.default simple

Fehlerhafte Commit-Message korrigieren

Hat man sich bei der letzten Commit-Message vertippt, kann diese mit

git commit --amend

(öffnet einen Editor, in dem die fehlerhafte Nachricht bearbeitet werden kann) bzw.

git commit --amend -m "correct commit message"

korrigiert werden.

URL des Repositorys anzeigen

Um sich die URL des aktuellen Repositorys anzeigen zu lassen, kann man diesen Befehl verwenden:

git remote show origin

Ein (fast) vollständiger Ersatz für „svn info“ ist hier beschrieben.

Einzelne Dateien aus Stash holen

Um einzelne Dateien aus dem Stash zurückzuholen, kann man den Befehl

git checkout stash@{0} filename

benutzen. Diese Datei ist dann automatisch im Staging-Bereich.

Inhalt des Stash anzeigen

Um den Inhalt des Stash anzuzeigen, kann der Befehl

git stash show -p

verwendet werden. Ältere Stashes können mit

git stash show -p stash@{1}

angezeigt werden.

Grafisches git blame

Mit

git gui blame filename

lässt sich ein grafischen Tool starten, mit dem man sich alle Änderung an einer Zeile in der Vergangenheit ansehen kann.

Zeilenumbruch (CRLF und LF)

Windows verwendet die beiden Zeichen CRLF, während Linux nur LF als Zeilenumbruch verwendet. Dies kann zu Problemen führen, wenn man ein Repo mit beiden Systemen benutzt oder Code mit unpassender Zeilenumbruchskodierung einfügen möchte. git kann diese Probleme automatisch beheben. Dazu existieren zwei Möglichkeiten: die eine, ältere setzt eine Konfiguration bei jedem Benutzer voraus, die andere wird im Repo abgelegt und gilt daher für alle.

Genauere Beschreibungen:

Konfiguration für jeden Benutzer

Bei dieser Vorgehensweise wird abhängig vom Betriebssystem der Parameter autocrlf gesetzt, unter Linux

git config --global core.autocrlf = input

bzw. unter Windows

git config --global core.autocrlf = true

Als zusätzlich Sicherheitsmaßname sollte safecrlf gesetzt werden, damit git prüft, ob eine Rückumwandlung möglich ist:

git config --global core.safecrlf = true

Konfiguration für ganzes Repo

Seit git 1.7.2 lässt sich eine Datei .gitattributes anlegen, mit der das Verhalten für das gesamte Repo konfiguriert werden kann. Durch Einträge wie

*.txt text 

lässt sich für jede Dateiendung einzeln entscheiden, ob git eine Normalisierung der Zeilenumbrüche auf LF beim commiten durchführt. Beim Ausschecken wird gemäß der Konfigurationsvariablen core.eol ggfls. eine Rückumwandlung durchgeführt. Den Defaultwert nativ sollte man nicht verändern, so dass man unter Windows CRLF und unter Linux LF als Zeilenumbruch erhält. Git kann in .gitattributes auch angewiesen werden, alle Textdateien automatisch zu erkennen und umzuwandeln.

*       text=auto

Wortbasierter Diff

Mit

git diff --word-diff 

lässt sich ein wortbasierter Diff durchführen. Für viele Sprachen enthält Git angepasste Parser. Um diese auszuwählen muss in .gitattributes für die Dateieindung die entsprechene Sprache ausgewählt werden, z.B.:

*.m diff=matlab

Dabei dürfen keine Leerzeichen zwischen diff, dem Gleichheitszeichen und der Sprache stehen. Eine Liste der unterstützten Sprachen findet sich im Abschnitt "Defining a custom hunk-header".

Editor für Commit-Message setzen

Der Editor, den Git zum Bearbeiten der Commit-Messages aufruft, kann auf mehrere Arten konfiguriert werden. Mit der Konfigurationsvariablen core.editor

git config --global core.editor "nano"

oder den Umgebungsvariablen GIT_EDITOR, VISUAL, EDITOR

export GIT_EDITOR=nano
export VISUAL=nano
export EDITOR=nano

Die Reihenfolge der Auswertung ist GIT_EDITOR, core.editor, VISUAL, EDITOR.

Mehrere Remotes

git kann mehrere remotes verwalten. Das ist für das Pushen auf mehrere Server praktisch.

Remote hinzufügen:

git remote add <name> <url>

Pushen:

git push <name>

Dateien, die nicht im Repo sind, entfernen

Dateien, die nicht im Repository sind (untracked), können mit git clean entfernt werden. Mit

git clean -n

wird ein Trockenlauf durchgeführt. Mit dem Parameter -f statt -n wird dann tatsächlich gelöscht. Um ungetrackte Verzeichnisse zu entfernen, muss das Argument -d hinzugefügt werden.

Alle Commits eines Autors anzeigen

Um alle Commits eines bestimmten Autors aufzulisten, kann man folgenden Befehl verwendet:

git log --author="name"

Der Name muss nicht vollständig angegeben werden. Statt des Namens kann auch eine Email-Adresse (oder ein Teil davon) angegeben werden. Um nicht nur den aktuellen Branch, sondern alle zu durchsuchen, kann der Parameter --all hinzugefügt werden.

Prüfen, ob Branch einen Commit enthält

Um zu prüfen, ob ein Branch einen gegebenen Commit enthält kann man den folgenden Befehl verwenden:

git branch -a --contains <commitish>

Commits, die über einen Rebase oder Cherry-Pick ins Repo gekommen sind, werden so nicht gefunden.

Autor nachträglich ändern

Um den Autor oder die Emailadresse nachträglich zu korrigieren, müssen folgendene Schritte durchgeführt werden:

Diese Operation schreibt die History neu. Wenn die Commits schon öffentlich sind, sollte man dies nur in Ausnahmefällen tun.

Sparse Checkout

Um nur Teile (z.B. ein Unterzeichnis) eines Repositories auszuchecken, kann ein sog. Sparse Checkout gemacht werden:

Branch in eigenes Repository

Um einen Branch branch-to-move in ein eigenes Repository zu kopieren kann folgendes verwendet werden:

git push url://to/new/repository.git branch-to-move:new-branch-name

new-branch-name ist der Name, den der Branch im neuen Repository gekommen soll. url://to/new/repository.git ist der Pfad zum git-Repository, dies kann auch ein lokaler Pfad sein.

Leere Verzeichnisse commiten

Leere Verzeichnisse lassen sich nicht einchecken, der hier empfohlenen Workaround ist eine .gitignore-Datei in dem Verzeichnis mit folgendem Inhalt:

# Ignore everything in this directory
*
# Except this file
!.gitignore

Andere Möglichkeit sind leere Dateien wie .keep oder .gitkeep in dem Verzeichnis. Eine Diskussion dazu findet sich auch in obigem Link.

git pull oder fetch hängt

Wenn git pull oder fetch hängt, kann man git mit

GIT_TRACE=true git pull

ein Trace einschalten. Auch die Verwendung des von Github deaktivierten, unverschlüsselten ''git://''-Protokolls ruft dieses Verhalten hervor (dies lässt sich im o.g. Trace allerdings nicht erkennen).

git Archive

Um einen Branch in eine Zip-Datei zu packen, können die folgenden Kommandos verwendet werden:

git archive -o zipfile.zip master #master Branch
git archive -o zipfile.zip HEAD   #aktueller Branch

Nützliche Aliases

Diese Aliases können in die ~/.gitconfig eingetragen werden:

[alias]
	st = status
  	ci = commit
  	br = branch
  	co = checkout
  	df = diff
        sed = ! git grep -z --full-name -l '.' | xargs -0 sed -i -e
        ack = grep --break --heading --line-number #git grep with output like ack
        # List all aliases.
        aliases = config --get-regexp alias
        # Fix whitespace from here: 
        # http://code.google.com/p/nathan-collins--conf/source/browse/dot.gitconfig
	# Fix whitespace in the index while preserving a dirty tree, if
	# any.
	#
	# Assuming your index is empty, some useful variations are:
	#
	# - fix whitespace in all changes in all versioned files:
	#
	# git add -u :/ && git fixws && git reset
	#
	# - fix whitespace in all unversioned files and in all changes in
	# all versioned files:
	#
	# git add --all :/ && git fixws && git reset
	#
	# Logic:
	#
	# The 'git stash save' fails if the tree is clean (instead of
	# creating an empty stash :P). So, we only 'stash' and 'pop' if
	# the tree is dirty.
	#
	# The 'git rebase --whitespace=fix HEAD~' throws away the commit
	# if it's empty, and adding '--keep-empty' prevents the whitespace
	# from being fixed. So, we first check that the index is dirty.
	#
	# Also:
	# - '(! git diff-index --quiet --cached HEAD)' is true (zero) if
	# the index is dirty
	# - '(! git diff-files --quiet .)' is true if the tree is dirty
	#
	# The 'rebase --whitespace=fix' trick is from here:
	# http://stackoverflow.com/a/19156679/470844
	fixws = !"\
	if (! git diff-files --quiet .) && \
	(! git diff-index --quiet --cached HEAD) ; then \
	git commit -m FIXWS_SAVE_INDEX && \
	git stash save FIXWS_SAVE_TREE && \
	git rebase --whitespace=fix HEAD~ && \
	git reset --soft HEAD~ && \
	git stash pop ; \
	elif (! git diff-index --quiet --cached HEAD) ; then \
	git commit -m FIXWS_SAVE_INDEX && \
	git rebase --whitespace=fix HEAD~ && \
	git reset --soft HEAD~ ; \
	fi" 
        #resets binary permission to the ones in the repo
        # from https://gist.github.com/jtdp/5443498
        permission-resetb = "!git diff -p --no-ext-diff --no-color --diff-filter=d | grep -E \"^(diff|old mode|new mode)\" | sed -e \"s/^old/NEW/;s/^new/old/;s/^NEW/new/\" | git apply"

git sed ersetzt in allen Dateien im Repository old-name durch new-name (siehe Bespiel). Dies ist sicherer als die entsprechende Lösung mit „find .“, da dabei Verwaltungsdateien von Git mit verändert werden können.

Beispiel:

git sed 's/old-name/new-name/g'