Git-Installation und -Konfiguration#
Installation#
Für iX-Distributionen sollte Git im Standard-Repository vorhanden sein.
Das Paket git-all stellt euch eine vollständige Umgebung für Git bereit. Dieses installiert ihr wie folgt:
$ sudo apt install git-all
Geht es ausschliesslich um Git, genügt das Paket namens git:
$ sudo apt install git
Mit der Bash-Autovervollständigung lässt sich Git auf der Kommandozeile einfacher bedienen. Das entsprechende Paket dazu heisst bash-completion und ihr installiert es wie folgt:
$ sudo apt install bash-completion
Es gibt verschiedene Möglichkeiten, Git auf einem Mac zu installieren. Am
einfachsten ist es vermutlich, die Xcode Command Line Tools zu installieren.
Hierfür müsst ihr nur git
das erste Mal vom Terminal aufrufen:
$ git --version
git-completion
könnt ihr mit Homebrew installieren:
Anschließend müsst ihr folgende Zeile in der Datei ~/.bash_profile
hinzufügen:
[[ -r "$(brew --prefix)/etc/profile.d/bash_completion.sh" ]] && . "$(brew --prefix)/etc/profile.d/bash_completion.sh"
Ruft dazu https://git-scm.com/download/win auf und startet den passenden Download dazu.
Siehe auch
Konfiguration#
Für jede Änderung muss ersichtlich sein, wer diese verursacht hat. Dazu hinterlegt ihr euren Namen und eure E-Mail-Adresse wie folgt:
$ git config --global user.name "NAME"
legt den Namen
NAME
fest, der mit euren Commit-Transaktionen verknüpft wird.$ git config --global user.email "EMAIL-ADDRESS"
legt die E-Mail-Adresse
EMAIL-ADDRESS
fest, die mit euren Commit-Transaktionen verknüpft wird.
Für eine bessere Lesbarkeit der Ausgabe sorgt die Kolorierung der Befehlszeilenausgabe. Diese schaltet ihr mit Hilfe dieses Aufrufs ein:
$ git config --global color.ui auto
aktiviert die Kolorierung der Befehlszeilenausgabe.
Die ~/.gitconfig
-Datei#
Mit den oben angegebenen Befehlen wird dir folgende ~/.gitconfig
-Datei
erstellt:
[user]
name = veit
email = veit@cusy.io
[color]
ui = auto
In der ~/.gitconfig
-Datei können jedoch auch Aliase festgelegt werden:
[alias]
st = status
ci = commit
br = branch
co = checkout
df = diff
dfs = diff --staged
Siehe auch
Shell-Konfiguration:
Sowohl der Editor lässt sich angeben, als auch die Hervorhebung von Leerzeichenfehlern
in git diff
:
[core]
editor = vim
# Highlight whitespace errors in git diff:
whitespace = tabwidth=4,tab-in-indent,cr-at-eol,trailing-space
Bemerkung
Neben ~/.gitconfig
sucht Git seit Version 1.17.12 auch in
~/.config/git/config
nach einer globalen Konfigurationsdatei.
Unter Linux kann ~/.config
manchmal ein anderer Pfad sein, der durch
die Umgebungsvariable XDG_CONFIG_HOME
festgelegt wird. Dieses
Verhalten ist Teil der Spezifikation der X Desktop Group (XDG). Den
anderen Pfad erhaltet ihr mit:
$ echo $XDG_CONFIG_HOME
Siehe auch
Da ihr Optionen an mehreren Ebenen festlegen könnt, möchtet ihr vielleicht
nachvollziehen, woher Git einen bestimmten Wert liest. Mit git config --list
[1] könnt ihr alle überschriebenen Optionen und Werte auflisten. Dies könnt
ihr kombinieren mit --show-scope
[2] um zu sehen, woher Git den Wert
bezieht:
$ git config --list --show-scope
system credential.helper=osxkeychain
global user.name=veit
global user.email=veit@cusy.io
…
Ihr könnt auch --show-origin
[3] verwenden, um die Namen der
Konfigurationsdateien aufzulisten:
$ git config --list --show-origin
file:/opt/homebrew/etc/gitconfig credential.helper=osxkeychain
file:/Users/veit/.config/git/config user.name=veit
file:/Users/veit/.config/git/config user.email=veit@cusy.io
…
Alternative Konfigurationsdatei#
Ihr könnt für bestimmte Arbeitsverzeichnisse andere Konfigurationsdateien verwenden, z.B. um zwischen privaten und beruflichen Projekten zu unterscheiden. Dazu könnt ihr eine lokale Konfiguration in eurem Repository verwenden oder aber Conditional Includes am Ende eurer globalen Konfiguration:
…
[includeIf "gitdir:~/private"]
path = ~/.config/git/config-private
Dieses Konstrukt sorgt dafür, dass Git zusätzliche Konfigurationen einbezieht
oder bestehende überschreibt, wenn ihr in ~/private
arbeitet.
Erstellt dazu nun die Datei ~/.config/git/config-private
und legt dort
eure alternative Konfiguration fest, z.B.:
[user]
email = kontakt@veit-schiele.de
[core]
sshCommand = ssh -i ~/.ssh/private_id_rsa
Siehe auch
Anmeldedaten verwalten#
Seit der Git-Version 1.7.9 lassen sich die Zugangsdaten zu git-Repositories mit gitcredentials verwalten. Um diese zu nutzen, könnt ihr z.B. folgendes angeben:
$ git config --global credential.helper Cache
Hiermit wird euer Passwort für 15 Minuten im Cache-Speicher gehalten. Der Timeout kann ggf. erhöht werden, z.B. mit:
$ git config --global credential.helper 'cache --timeout=3600'
Unter macOS lässt sich mit osxkeychain
die Schlüsselbundverwaltung
(Keychain) nutzen um die Zugangsdaten zu speichern. osxkeychain
setzt
Git in der Version 1.7.10 oder neuer voraus und kann im selben Verzeichnis
wie Git installiert werden mit:
$ git credential-osxkeychain
git: 'credential-osxkeychain' is not a git command. See 'git --help'.
$ curl -s -O http://github-media-downloads.s3.amazonaws.com/osx/git-credential-osxkeychain
$ chmod u+x git-credential-osxkeychain
$ sudo mv git-credential-osxkeychain /usr/bin/
Password:
git config --global credential.helper osxkeychain
Dies trägt folgendes in die ~/.gitconfig
-Datei ein:
[credential]
helper = osxkeychain
Für Windows steht der Git Credential Manager (GCM) zur Verfügung. Er ist integriert in Git for Windows und wird standardmäßig mitinstalliert. Zusätzlich besteht jedoch auch ein eigenständiges Installationsprogramm in Releases.
GCM wird mit dem nachfolgenden Aufruf konfiguriert:
$ git credential-manager configure
Configuring component 'Git Credential Manager'...
Configuring component 'Azure Repos provider'...
Dies trägt den [credential]
-Abschnitt in eure ~/.gitconfig
-Datei
ein:
[credential]
helper =
helper = C:/Program\\ Files/Git/mingw64/bin/git-credential-manager.exe
Nun öffnet sich beim Clonen eines Repository ein Fenster des GCM und fordert euch zur Eingabe eurer Zugangsdaten auf.
Zudem wird die ~/.gitconfig
-Datei ergänzt, z.B. um die folgenden beiden Zeilen:
[credential "https://ce.cusy.io"]
provider = generic
Bemerkung
Ein umfangreiches Beispiel einer Konfigurationsdatei findet ihr in meinem dotfiles-Repository: .gitconfig.
Die .gitignore
-Datei#
In der .gitignore
-Datei eines Repository könnt ihr Dateien von der
Versionsverwaltung ausschließen. Eine typische .gitignore
-Datei kann
z.B. so aussehen:
/logs/*
!logs/.gitkeep
/tmp
*.swp
Dabei verwendet Git Globbing-Muster, u.a.:
Muster |
Beispiel |
Erläuterung |
---|---|---|
**/logs
|
|
Ihr könnt zwei Sternchen voranstellen um Verzeichnisse an einer beliebigen Stelle im Verzeichnisbaum zu finden. |
**/logs/instance.log
|
|
Ihr könnt zwei Sternchen voranstellen um Dateien anhand ihres Namens in einem übergeordneten Verzeichnis zu finden. |
*.log
|
|
Ein Sternchen ist ein Platzhalter für null oder mehr Zeichen. |
/logs
!/logs/.gitkeep
|
|
Ein vor ein Muster gestelltes Anführungszeichen ignoriert dieses. Wenn eine Datei mit einem Muster übereinstimmt, aber auch mit einem negierenden, das später definiert ist, wird sie nicht ignoriert. |
/instance.log
|
|
Mit dem vorangestellten Schrägstrich passt das Muster nur zu Dateien im Stammverzeichnis des Repository. |
instance.log
|
|
Üblicherweise passen die Muster zu Dateien in jedem Verzeichnis. |
instance?.log
|
|
Ein Fragezeichen passt genau zu einem Zeichen. |
instance[0-9].log
|
|
Eckige Klammern können verwendet werden um ein einzelnes Zeichen aus einem bestimmten Bereich zu finden. |
instance[01].log
|
|
Eckige Klammern passen auf ein einzelnes Zeichen aus einer bestimmten Menge. |
instance[!01].log
|
|
Ein Ausrufezeichen kann verwendet werden um ein beliebiges Zeichen aus einer angegebenen Menge zu finden. |
logs
|
|
Wenn kein Schrägstrich anhängt, passt das Muster sowohl auf Dateien als auch auf den Inhalt von Verzeichnissen mit diesem Namen. |
logs/
|
|
Das Anhängen eines Schrägstrichs zeigt an, dass das Muster ein Verzeichnis ist. Der gesamte Inhalt jedes Verzeichnisses im Repository, das diesem Namen entspricht – einschließlich all seiner Dateien und Unterverzeichnisse – wird ignoriert. |
var/**/instance.log
|
|
Zwei Sternchen passen zu null oder mehr Verzeichnissen. |
logs/instance*/error.log
|
|
Wildcards können auch in Verzeichnisnamen verwendet werden. |
logs/instance.log
|
|
Muster, die eine Datei in einem bestimmten Verzeichnis angeben, sind relativ zum Stammverzeichnis des Repository. |
Git-commit eines leeren Verzeichnisses#
In obigem Beispiel seht ihr, dass mit /logs/*
keine Inhalte des
logs
-Verzeichnisses mit Git versioniert werden sollen, in der Folgezeile
jedoch eine Ausnahme definiert wird:
!logs/.gitkeep
Diese Angabe erlaubt, dass die Datei .gitkeep
mit Git verwaltet werden
darf. Damit wird dann auch das logs
-Verzeichnis in das Git-Repository
übernommen. Diese Hilfskonstruktion ist erforderlich, da leere Verzeichnisse
nicht mit Git verwaltet werden können.
Eine andere Möglichkeit besteht darin, in einem leeren Verzeichnis eine
.gitignore
-Datei mit folgendem Inhalt zu erstellen:
# ignore everything except .gitignore
*
!.gitignore
Dateien zentral mit excludesfile
ausschließen#
Ihr könnt jedoch auch zentral für alle Git-Repositories Dateien ausschließen.
Hierfür wird üblicherweise in der ~/.gitconfig
-Datei folgendes
angegeben:
[core]
# Use custom `.gitignore`
excludesfile = ~/.gitignore
…
Bemerkung
Hilfreiche Vorlagen findet ihr in meinem dotfiles-Repository oder auf der Website gitignore.io.
Ignorieren einer Datei aus dem Repository#
Wenn ihr eine Datei ignorieren wollt, die in der Vergangenheit bereits dem Repository hinzugefügt
wurde, müsst ihr die Datei aus eurem Repository löschen und dann eine
.gitignore
-Regel für sie hinzufügen. Die Verwendung der Option --cached
bei git rm
bedeutet, dass die Datei aus dem Repository gelöscht wird, aber
als ignorierte Datei in eurem Arbeitsverzeichnis verbleibt.
$ echo *.log >> .gitignore
$ git rm --cached *.log
rm 'instance.log'
$ git commit -m "Remove log files"
Bemerkung
Ihr könnt die Option --cached
weglassen, wenn ihr die Datei sowohl aus
dem Repository als auch aus eurem lokalen Dateisystem löschen wollt.
Commit einer ignorierten Datei#
Es ist möglich, den Commit einer ignorierten Datei an das Repository mit der
Option -f
(oder --force
) bei git add
zu erzwingen:
$ cat data/.gitignore
*
$ git add -f data/iris.csv
$ git commit -m "Force add iris.csv"
Ihr könnt dies in Erwägung ziehen, wenn ihr ein allgemeines Muster (wie *
)
definiert habt, aber eine bestimmte Datei übertragen wollt. Eine bessere Lösung
ist meist jedoch, eine Ausnahme von der allgemeinen Regel zu definieren:
$ echo '!iris.csv' >> data/.gitignore
$ cat data/.gitignore
*
!iris.csv
$ git add data/iris.csv
$ git commit -m "Add iris.csv"
Dieser Ansatz dürfte für euer Team offensichtlicher und weniger verwirrend sein.
Fehlersuche in .gitignore
-Dateien#
Bei komplizierten .gitignore
-Mustern oder bei Mustern, die über mehrere
.gitignore
-Dateien verteilt sind, kann es schwierig sein,
herauszufinden, ob oder warum eine bestimmte Datei ignoriert wird.
Mit dem Aufruf git status --ignored=matching
[4] wird der Ausgabe ein
Abschnitt Ignorierte Dateien hinzugefügt, der zusätzlich alle von Git
ignorierten Dateien und Verzeichnisse beinhaltet:
$ git status --ignored=matching
Auf Branch main
Ignorierte Dateien:
(benutzen Sie "git add -f <Datei>...", um die Änderungen zum Commit vorzumerken)
.DS_Store
docs/.DS_Store
docs/_build/doctrees/
docs/_build/html/
docs/clean-prep/.ipynb_checkpoints/
…
nichts zu committen, Arbeitsverzeichnis unverändert
Ihr könnt den Befehl git check-ignore
[5] mit der Option -v
(Langform:
--verbose
) verwenden, um festzustellen, welches Muster die Ursache für das
Ignorieren einer bestimmten Datei ist:
$ git check-ignore -v data/iris.csv
data/.gitignore:2:!iris.csv data/iris.csv
Obige Ausgabe besteht aus vier Feldern (Trennzeichen sind drei Doppelpunkte und ein Leerzeichen) und beinhaltet:
FILE_CONTAINING_THE_PATTERN
den Namen der Datei, die das Muster enthält.
LINE_NUMBER_OF_THE_PATTERN
die Zeilennummer, in der in der Datei
FILE_CONTAINING_THE_PATTERN
das Muster gefunden wurde.PATTERN
das gefundene Muster.
FILE_NAME
den Namen der Datei inklusive Pfad, die Git ignoriert.
Ihr könnt mehrere Dateinamen an git check-ignore
übergeben, wenn ihr
möchtet, und die Namen selbst müssen nicht einmal den Dateien entsprechen, die
in eurem Repository existieren.
Eine vollständige Liste aller ignorierten Dateien erhaltet ihr mit git
ls-files --ignored --exclude-standard --others
[6]. Mit
--exclude-standard
werden die Standard-ignore
-Dateien gelesen und
mit --others
werden die nicht-versionierten Dateien statt der versionierten
angezeigt:
$ git ls-files --ignored --exclude-standard --others
.DS_Store
_build/doctrees/clean-prep/bulwark.doctree
_build/doctrees/clean-prep/dask-pipeline.doctree
_build/doctrees/clean-prep/deduplicate.doctree
…
Gelegentlich möchtet ihr vielleicht die globale ~/.gitignore
-Datei
umgehen um zu sehen, welche Dateien Git unabhängig von eurer Konfiguration immer
ignoriert. Ihr könnt dies tun, indem ihr zu einer anderen exclude
-Option
wechselt, --exclude-per-directory
, die nur die .gitignore
-Dateien
des Repositorys verwendet:
$ git ls-files --ignored --exclude-per-directory=.gitignore --others
docs/_build/doctrees/clean-prep/bulwark.doctree
docs/_build/doctrees/clean-prep/dask-pipeline.doctree
docs/_build/doctrees/clean-prep/deduplicate.doctree
…
Beachtet, dass die Datei .DS_Store
nicht mehr als ignoriert aufgeführt
wird.
Wenn ihr --others
durch --cached
ersetzt, listet git ls-files
Dateien auf, die ignoriert werden würden, es sei denn, sie wurden bereits
übertragen:
$ git ls-files --ignored --exclude-per-directory=.gitignore --cached
data/iris.csv
Möglicherweise habt ihr solche Dateien, weil jemand sie vor den relevanten
Mustern in einer .gitignore
-Datei hinzugefügt hat, oder weil jemand sie
mit git add --force
hinzugefügt hat. So oder so, wenn ihr die Datei nicht
mehr mit Git verwalten wollt, könnt ihr sie mit dem folgenden Einzeiler aus der
Git-Verwaltung nehmen, sie aber nicht löschen:
$ git ls-files --ignored --exclude-per-directory=.gitignore --cached | xargs -r git rm --cached
rm 'data/iris.csv'