26 KiB
Table of Contents
- Git
- Grundlagen
- Dateien hinzufügen und committen
- Branches
- Branch-Grundlagen
- Branch löschen
- Remote Branch als neuen lokalen Branch auschecken
- Branch mit anderem Branch aktualisieren
- Mit Rebase (empfohlen für saubere History)
- Interaktives Rebase für mehr Kontrolle
- Mit Merge (behält alle Commits)
- Neuer Branch aus falschem Branch erstellt
- Merging und Integration
- Cherry-Pick
- Stash - Änderungen temporär speichern
- History und Logs
- Commits rückgängig machen
- Reset - History zurücksetzen
- Revert - Commit rückgängig machen (sicher für Shared Branches)
- Einzelne Datei auf älteren Stand zurücksetzen
- Branch mit Remote synchronisieren
- Tags
- .gitignore
- Synchronisation mit Remote
- Arbeiten mit Patches
- Submodules
- Nützliche Aliase
- Troubleshooting
- Merge-Konflikte lösen
- Versehentlich gelöschte Dateien wiederherstellen
- Commit an falschen Branch
- Große Dateien aus History entfernen
- Detached HEAD State
- Versehentlich überschriebene Änderungen wiederherstellen
- Best Practices
- Fortgeschrittene Befehle
- Bisect - Buggy Commit finden
- Worktree - Mehrere Branches gleichzeitig
- Blame - Änderungen pro Zeile anzeigen
- Clean - Untracked Files entfernen
- Git Hooks
- Nützliche Tipps
Git
Grundlagen
Das Drei-Stufen-Konzept
Git arbeitet mit drei Bereichen:
- Working Directory (Arbeitsverzeichnis) - hier bearbeitest du deine Dateien
- Staging Area - hier sammelst du Änderungen, die du committen möchtest
- Repository - hier werden die Commits gespeichert
Git Konfiguration
Grundlegende Konfiguration nach der Installation:
# Benutzername global setzen
git config --global user.name "Dein Name"
# E-Mail global setzen
git config --global user.email "deine.email@example.com"
# Standard-Editor festlegen
git config --global core.editor "code --wait" # für VS Code
# Aktuelle Konfiguration anzeigen
git config --list
# Nur lokale Konfiguration (für aktuelles Repo)
git config user.name "Anderer Name"
# Spezifischen Wert abfragen
git config user.email
Repository initialisieren
Ein neues Git-Repository erstellen:
git init
Oder ein bestehendes Repository klonen:
git clone <repository-url>
# Beispiel mit HTTPS
git clone https://github.com/user/repository.git
# Beispiel mit SSH
git clone git@github.com:user/repository.git
# Mit spezifischem Verzeichnisnamen
git clone <repository-url> <verzeichnisname>
Remote Repositories verwalten
# Remote-Repositories anzeigen
git remote -v
# Neues Remote-Repository hinzufügen
git remote add <name> <url>
git remote add origin https://github.com/user/repo.git
# Remote-URL ändern
git remote set-url origin <neue-url>
# Remote-Repository entfernen
git remote remove <name>
# Remote-Repository umbenennen
git remote rename <alter-name> <neuer-name>
Dateien hinzufügen und committen
Staging Area
# Einzelne Datei zur Staging Area hinzufügen
git add dateiname.txt
# Alle geänderten Dateien hinzufügen
git add .
# Alle Dateien eines bestimmten Typs hinzufügen
git add *.js
# Interaktives Staging (wähle aus, was gestaged werden soll)
git add -p
# Dateien aus der Staging Area entfernen (unstage)
git reset HEAD dateiname.txt
# oder mit neuerer Git-Version
git restore --staged dateiname.txt
Commits erstellen
# Commit mit Message erstellen
git commit -m "Beschreibung der Änderungen"
# Alle geänderten, bereits getrackten Dateien committen (überspringt git add)
git commit -a -m "Commit-Message"
# Letzten Commit ändern (Message oder Dateien ergänzen)
git commit --amend -m "Neue Commit-Message"
# Leeren Commit erstellen (nützlich für CI/CD Trigger)
git commit --allow-empty -m "Trigger rebuild"
Status und Unterschiede anzeigen
# Status des Working Directory anzeigen
git status
# Kurze Statusanzeige
git status -s
# Unterschiede im Working Directory anzeigen (noch nicht gestaged)
git diff
# Unterschiede in der Staging Area anzeigen
git diff --staged
# oder
git diff --cached
# Unterschiede zwischen zwei Commits
git diff <commit1> <commit2>
# Nur Dateinamen der geänderten Dateien anzeigen
git diff --name-only
# Unterschiede einer bestimmten Datei anzeigen
git diff dateiname.txt
Branches
Branch-Grundlagen
# Alle lokalen Branches anzeigen
git branch
# Alle Branches (lokal und remote) anzeigen
git branch -a
# Nur Remote-Branches anzeigen
git branch -r
# Neuen Branch erstellen
git branch <branch-name>
# Neuen Branch erstellen und direkt dorthin wechseln
git checkout -b <branch-name>
# oder mit neuerer Syntax
git switch -c <branch-name>
# Zu einem Branch wechseln
git checkout <branch-name>
# oder
git switch <branch-name>
# Branch umbenennen
git branch -m <alter-name> <neuer-name>
# Aktuellen Branch umbenennen
git branch -m <neuer-name>
Branch löschen
Lokal Branch löschen, z.B. wenn er auf Remote in master/main gemergt wurde:
# Lokal löschen (nur wenn bereits gemergt)
git branch -d <branch-name>
# Lokal löschen (erzwingen, auch wenn nicht gemergt)
git branch -D <branch-name>
# Remote löschen
git push origin --delete <branch-name>
# Alternative Syntax
git push origin :<branch-name>
Beispiel:
# Feature-Branch nach Merge löschen
git checkout main
git branch -d feature/neue-funktion
git push origin --delete feature/neue-funktion
Remote Branch als neuen lokalen Branch auschecken
# Remote-Änderungen holen (ohne zu mergen)
git fetch origin
# Alle Branches anzeigen
git branch -a
# Remote-Branch als lokalen Branch auschecken
git checkout -b <lokaler-name> origin/<remote-branch>
# Wenn lokaler und remote Name gleich sind (ab Git 2.23)
git checkout --track origin/<branch-name>
# oder einfach
git checkout <branch-name> # Git erstellt automatisch tracking branch
Beispiel:
git fetch origin
git branch -a
git checkout -b INITIATIVE-242_Ru origin/INITIATIVE-242_Ru
Branch mit anderem Branch aktualisieren
Eigenen Feature-Branch mit den neuesten Änderungen aus main/master aktualisieren:
Mit Rebase (empfohlen für saubere History)
# Zuerst main/master aktualisieren
git checkout main
git pull
# Zum Feature-Branch wechseln
git checkout feature/mein-branch
# Rebase durchführen
git rebase main
# Bei Konflikten: Konflikte in den Dateien lösen, dann:
git add .
git rebase --continue
# Falls zu komplex: Rebase abbrechen
git rebase --abort
# Nach erfolgreichem Rebase: Force-Push (mit Sicherheitsnetz)
git push --force-with-lease
Interaktives Rebase für mehr Kontrolle
git checkout main
git pull
git checkout feature/mein-branch
git rebase -i main
# Im Editor: Commits anpassen (pick, squash, edit, drop, etc.)
# Nach dem Speichern: Konflikte lösen falls nötig
git add .
git rebase --continue
git push --force-with-lease
Mit Merge (behält alle Commits)
git checkout feature/mein-branch
git merge main
# Konflikte lösen falls nötig, dann:
git add .
git commit # Merge-Commit erstellen
git push
Neuer Branch aus falschem Branch erstellt
Ausgangslage
Ein neuer Branch (feature-b) wurde fälschlicherweise aus einem anderen Branch (feature-a) anstatt aus main/master erstellt. Die Commits aus feature-a erscheinen nun auch in feature-b.
Problemlösung
# Main aktualisieren
git checkout main
git pull
# Zum problematischen Branch wechseln
git checkout feature-b
git pull
# Interaktives Rebase auf main
git rebase -i main
# Im Editor: Bei den Commits aus feature-a, die nicht in feature-b gehören:
# Ändere "pick" zu "drop" (oder lösche die Zeile komplett)
# Speichern und schließen
# Prüfen ob alles korrekt ist
git log --oneline
# Force-Push mit Sicherheitsnetz
git push --force-with-lease
Alternative: Branch neu erstellen
# Neuen Branch vom richtigen Ausgangspunkt erstellen
git checkout main
git pull
git checkout -b feature-b-neu
# Nur die gewünschten Commits cherry-picken
git cherry-pick <commit-hash-1>
git cherry-pick <commit-hash-2>
# Alten Branch löschen
git branch -D feature-b
git push origin --delete feature-b
# Neuen Branch umbenennen und pushen
git branch -m feature-b
git push -u origin feature-b
Merging und Integration
Feature-Branch in main/master mergen
Vorgehensweise ohne Pull-Request-Workflow:
# 1. Auf main/master wechseln (lokal)
git checkout main
# 2. Aktuellste Änderungen holen und synchronisieren
git pull origin main
# 3. Feature-Branch in lokalen main mergen
git merge feature/mein-branch
# 4. Bei Merge-Konflikten: Konflikte in den Dateien beheben
# Konfliktmarkierungen (<<<<<<<, =======, >>>>>>>) im Code auflösen
# Dann Dateien stagen:
git add <konflikt-dateien>
# Merge abschließen:
git commit
# 5. Änderungen auf Remote pushen
git push origin main
Alternative mit Fast-Forward vermeiden:
# Merge-Commit erzwingen (auch wenn Fast-Forward möglich wäre)
git merge --no-ff feature/mein-branch
Merge abbrechen
# Falls während eines Merges etwas schiefgeht
git merge --abort
Cherry-Pick
Einzelne Commits aus einem Branch in einen anderen übernehmen:
# Einzelnen Commit cherry-picken
git cherry-pick <commit-hash>
# Mehrere Commits cherry-picken
git cherry-pick <commit-hash-1> <commit-hash-2>
# Bereich von Commits cherry-picken (exklusiv start, inklusiv end)
git cherry-pick <start-commit>..<end-commit>
# Cherry-Pick ohne automatischen Commit
git cherry-pick -n <commit-hash>
# Bei Konflikten: Konflikte lösen, dann
git add .
git cherry-pick --continue
# Cherry-Pick abbrechen
git cherry-pick --abort
Beispiel:
# Commit aus feature-a in feature-b übernehmen
git checkout feature-b
git cherry-pick abc123
Stash - Änderungen temporär speichern
# Aktuelle Änderungen in den Stash speichern
git stash
# oder mit Beschreibung
git stash save "WIP: Feature XY"
# Stash mit untracked Dateien
git stash -u
# oder mit allen Dateien (auch ignored)
git stash -a
# Alle Stashes anzeigen
git stash list
# Stash anwenden (behält Stash)
git stash apply
# Spezifischen Stash anwenden
git stash apply stash@{2}
# Stash anwenden und entfernen
git stash pop
# Spezifischen Stash poppen
git stash pop stash@{2}
# Stash-Inhalt anzeigen
git stash show
git stash show -p # mit diff
# Stash löschen
git stash drop stash@{0}
# Alle Stashes löschen
git stash clear
# Branch aus Stash erstellen
git stash branch <branch-name>
Typisches Szenario:
# Arbeit unterbrechen für dringenden Bugfix
git stash
git checkout main
git checkout -b hotfix/bug
# Bugfix durchführen...
git checkout feature/meine-arbeit
git stash pop
History und Logs
Commit-History anzeigen
# Standard Log
git log
# Kompakte einzeilige Darstellung
git log --oneline
# Mit Grafik der Branches
git log --graph --oneline --all
# Letzten N Commits anzeigen
git log -n 5
git log -5
# Logs mit Änderungen
git log -p
# Logs eines bestimmten Autors
git log --author="Name"
# Logs in einem Zeitraum
git log --since="2024-01-01" --until="2024-12-31"
git log --since="2 weeks ago"
# Logs für eine bestimmte Datei
git log -- pfad/zur/datei.txt
# Commits finden, die einen bestimmten String ändern
git log -S "suchtext"
# Schöne formatierte Ausgabe
git log --pretty=format:"%h - %an, %ar : %s"
Commit-Details anzeigen
# Details eines bestimmten Commits
git show <commit-hash>
# Dateien in einem Commit
git show --name-only <commit-hash>
# Statistiken eines Commits
git show --stat <commit-hash>
Reflog - History der HEAD-Bewegungen
# Alle HEAD-Bewegungen anzeigen (auch bei reset, rebase, etc.)
git reflog
# Nützlich um "verlorene" Commits wiederzufinden
git reflog show
# Zu einem früheren Zustand zurückkehren
git reset --hard HEAD@{2}
Commits rückgängig machen
Reset - History zurücksetzen
# Einen Commit zurück (Änderungen bleiben im Working Directory)
git reset --soft HEAD~1
# Einen Commit zurück (Änderungen bleiben unstaged)
git reset HEAD~1
# oder
git reset --mixed HEAD~1
# Einen Commit zurück (ACHTUNG: Änderungen werden gelöscht!)
git reset --hard HEAD~1
# Mehrere Commits zurück
git reset --hard HEAD~3
# Zu einem bestimmten Commit zurück
git reset --hard <commit-hash>
# Nach einem Reset: Remote überschreiben (Vorsicht!)
git push --force
# Sicherer: Mit force-with-lease (schützt vor Überschreiben anderer Änderungen)
git push --force-with-lease
Revert - Commit rückgängig machen (sicher für Shared Branches)
# Einen Commit rückgängig machen (erstellt neuen Commit)
git revert <commit-hash>
# Mehrere Commits rückgängig machen
git revert <commit-hash-1> <commit-hash-2>
# Letzten Commit rückgängig machen
git revert HEAD
# Revert ohne automatischen Commit
git revert -n <commit-hash>
Unterschied Reset vs. Revert:
reset: Ändert die History (problematisch bei Shared Branches)revert: Erstellt neuen Commit (sicher für Shared Branches)
Einzelne Datei auf älteren Stand zurücksetzen
# Datei aus einem bestimmten Commit wiederherstellen
git checkout <commit-hash> -- pfad/zur/datei.txt
# Datei auf Stand von HEAD (letzter Commit) zurücksetzen
git checkout HEAD -- datei.txt
# oder mit neuerer Syntax
git restore datei.txt
# Datei auf Stand von Remote zurücksetzen
git checkout origin/main -- datei.txt
Branch mit Remote synchronisieren
Standard-Synchronisation (normaler Workflow)
Wenn du einfach die neuesten Änderungen vom Remote-Branch holen möchtest:
# Main/Master aktualisieren (Standard-Methode)
git checkout main
git pull
# Expliziter: Von spezifischem Remote pullen
git checkout main
git pull origin main
# Sicherer: Erst fetchen, dann Status prüfen, dann pullen
git checkout main
git fetch origin
git status # Prüfen ob lokale Änderungen existieren
git pull origin main
Wann verwenden: Reguläre Synchronisation, wenn keine lokalen Änderungen vorhanden sind oder diese per Merge integriert werden sollen.
Lokale Änderungen komplett verwerfen (Notfall)
Wenn lokale Änderungen komplett verworfen und durch den Remote-Stand ersetzt werden sollen:
# ACHTUNG: Alle lokalen Änderungen gehen verloren!
git fetch --all
git reset --hard origin/<branch-name>
# Beispiel für main Branch
git checkout main
git fetch origin
git reset --hard origin/main
Wann verwenden:
- Lokale Commits sind fehlerhaft und sollen verworfen werden
- Merge-Konflikte sind zu komplex und ein Neustart ist einfacher
- Experimentelle Änderungen sollen rückgängig gemacht werden
- Feature-Branch soll auf exakt denselben Stand wie Remote
Wichtig:
- ⚠️ Alle lokalen, nicht gepushten Commits gehen verloren!
- ⚠️ Alle uncommitteten Änderungen gehen verloren!
- 💡 Tipp: Vorher Backup mit
git stashodergit branch backup-$(date +%Y%m%d)erstellen
Tags
Tags erstellen
# Lightweight Tag erstellen
git tag v1.0.0
# Annotated Tag erstellen (empfohlen)
git tag -a v1.0.0 -m "Version 1.0.0 Release"
# Tag für einen bestimmten Commit
git tag -a v1.0.0 <commit-hash> -m "Release"
# Tags auf Remote pushen
git push origin v1.0.0
# Alle Tags auf Remote pushen
git push origin --tags
Tags anzeigen
# Alle Tags anzeigen
git tag
# Tags mit Muster suchen
git tag -l "v1.0.*"
# Tag-Details anzeigen
git show v1.0.0
Tags löschen
# Lokal löschen
git tag -d <tag-name>
# Remote löschen
git push --delete origin <tag-name>
# Alternative Syntax
git push origin :refs/tags/<tag-name>
Beispiel:
git tag -d v1.0.0
git push --delete origin v1.0.0
.gitignore
Dateien und Verzeichnisse von der Versionskontrolle ausschließen:
# .gitignore Datei im Root-Verzeichnis erstellen
touch .gitignore
Beispiel .gitignore:
# Kompilierte Dateien
*.class
*.o
*.pyc
__pycache__/
# Build-Verzeichnisse
/build/
/dist/
/target/
# Abhängigkeiten
node_modules/
vendor/
# IDE-spezifische Dateien
.vscode/
.idea/
*.swp
*.swo
*~
# Betriebssystem-Dateien
.DS_Store
Thumbs.db
# Umgebungsvariablen und Secrets
.env
.env.local
secrets.yml
# Logs
*.log
logs/
# Temporäre Dateien
tmp/
temp/
*.tmp
# Spezifische Datei ignorieren
config/database.yml
# Alle Dateien eines Typs in einem Verzeichnis
docs/**/*.pdf
# Negation: Datei NICHT ignorieren
!wichtig.log
Bereits getrackte Dateien ignorieren
# Datei aus Git entfernen, aber lokal behalten
git rm --cached dateiname
# Verzeichnis aus Git entfernen, aber lokal behalten
git rm -r --cached verzeichnis/
# Dann .gitignore aktualisieren und committen
Synchronisation mit Remote
Pull und Fetch
Zusammenspiel von Fetch, Pull, Merge und Rebase
Grundprinzip:
git pull = git fetch + git merge
git pull --rebase = git fetch + git rebase
Was passiert im Detail:
-
git fetch- Holt Änderungen vom Remote, ohne sie zu integrieren- Lädt neue Commits vom Remote-Repository herunter
- Aktualisiert Remote-Tracking-Branches (z.B.
origin/main) - Ändert nichts am lokalen Branch oder Working Directory
- Sicher - kann nichts kaputt machen
-
git pull- Holt Änderungen und merged sie automatisch- Führt intern
git fetchaus - Merged dann automatisch
origin/mainin lokalenmain - Erstellt Merge-Commit bei divergierenden Histories
- Kann zu Merge-Konflikten führen
- Führt intern
-
git pull --rebase- Holt Änderungen und rebaset darauf- Führt intern
git fetchaus - Setzt lokale Commits auf top der neuen Remote-Commits
- Keine Merge-Commits → saubere, lineare History
- Empfohlen für Feature-Branches
- Führt intern
Visueller Vergleich:
# Ausgangssituation: Lokale und Remote-Commits divergieren
C (origin/main)
/
A - B
\
D (main, lokal)
# Nach git pull (merge):
C (origin/main)
/ \
A - B E (main, Merge-Commit)
\ /
D
# Nach git pull --rebase:
A - B - C (origin/main) - D' (main, rebasiert)
Befehle im Detail
# Fetch: Nur Änderungen holen (ohne zu integrieren)
git fetch
git fetch origin
# Jetzt lokal prüfen was sich geändert hat:
git log origin/main # Remote-Commits anschauen
git diff main origin/main # Unterschiede vergleichen
# Dann entscheiden: Merge oder Rebase?
git merge origin/main # Merge-Variante
# oder
git rebase origin/main # Rebase-Variante
# Pull: Änderungen holen und mergen (automatisch)
git pull
# Von spezifischem Remote und Branch
git pull origin main
# Mit Rebase statt Merge (empfohlen für saubere History)
git pull --rebase
git pull --rebase origin main
# Alle Remotes fetchen
git fetch --all
# Remote-Branches prunen (gelöschte entfernen)
git fetch --prune
# Fetch und prune in einem
git fetch --all --prune
Wann was verwenden?
| Szenario | Empfohlener Befehl | Begründung |
|---|---|---|
| Erstmal schauen was sich geändert hat | git fetch |
Kein Risiko, nur Download |
| Main/Master aktualisieren | git pull |
Standard, Merge ist OK |
| Feature-Branch aktualisieren | git pull --rebase |
Saubere lineare History |
| Unsicher bei Konflikten | git fetch + manuell merge/rebase |
Mehr Kontrolle |
| Shared Branch (mehrere Entwickler) | git pull |
Merge preserviert alle Histories |
| Privater Branch | git pull --rebase |
History-Cleanup möglich |
Best Practice - Der sichere Weg:
# 1. Erstmal nur fetchen (kein Risiko)
git fetch origin
# 2. Prüfen was sich geändert hat
git log HEAD..origin/main --oneline
# 3. Unterschiede anschauen
git diff HEAD origin/main
# 4. Dann bewusst entscheiden
git merge origin/main
# oder
git rebase origin/main
Push
# Zum konfigurierten Remote pushen
git push
# Zu spezifischem Remote und Branch
git push origin main
# Neuen Branch auf Remote erstellen und tracken
git push -u origin neuer-branch
# oder
git push --set-upstream origin neuer-branch
# Force Push (Vorsicht!)
git push --force
# Sicherer Force Push
git push --force-with-lease
# Alle Branches pushen
git push --all
# Tags mit pushen
git push --tags
Arbeiten mit Patches
# Patch aus Commits erstellen
git format-patch -1 HEAD
git format-patch HEAD~3..HEAD
# Patch anwenden
git apply patch-datei.patch
# Patch mit Commit-Informationen anwenden
git am < patch-datei.patch
# Prüfen ob Patch anwendbar ist
git apply --check patch-datei.patch
Submodules
# Submodule hinzufügen
git submodule add <repository-url> pfad/zum/submodule
# Repository mit Submodules klonen
git clone --recurse-submodules <repository-url>
# Submodules in bestehendem Repo initialisieren
git submodule init
git submodule update
# Alle Submodules aktualisieren
git submodule update --remote
# Submodule entfernen
git submodule deinit pfad/zum/submodule
git rm pfad/zum/submodule
rm -rf .git/modules/pfad/zum/submodule
Nützliche Aliase
Git-Aliase in der Konfiguration einrichten:
# Kurzformen für häufige Befehle
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
# Log mit Graph
git config --global alias.lg "log --graph --oneline --all --decorate"
# Undo letzter Commit (behält Änderungen)
git config --global alias.undo "reset HEAD~1"
# Kurzform für Status
git config --global alias.s "status -s"
# Branch mit letztem Commit anzeigen
git config --global alias.branches "branch -v"
Troubleshooting
Merge-Konflikte lösen
# Status der Konflikte anzeigen
git status
# Konflikte in den Dateien manuell lösen (<<<<<<, ======, >>>>>>)
# Dann:
git add <gelöste-dateien>
git commit
# Merge abbrechen und zurück zum Ursprung
git merge --abort
# Mergetool verwenden
git mergetool
Versehentlich gelöschte Dateien wiederherstellen
# Datei aus letztem Commit wiederherstellen
git restore datei.txt
# oder
git checkout HEAD -- datei.txt
# Gelöschte Dateien finden
git log --diff-filter=D --summary | grep delete
# Datei aus History wiederherstellen
git checkout <commit-hash>^ -- datei.txt
Commit an falschen Branch
# Szenario: Commit versehentlich an main statt an Feature-Branch
# 1. Neuen Branch vom aktuellen Stand erstellen
git branch feature/neuer-branch
# 2. Main zurücksetzen
git reset --hard HEAD~1
# 3. Zum neuen Branch wechseln
git checkout feature/neuer-branch
Große Dateien aus History entfernen
# Git filter-branch (alte Methode, nicht empfohlen)
git filter-branch --tree-filter 'rm -f grosse-datei.zip' HEAD
# BFG Repo-Cleaner (empfohlen, schneller)
# Zuerst BFG installieren, dann:
bfg --delete-files grosse-datei.zip
# Git filter-repo (moderner Ersatz für filter-branch)
git filter-repo --path grosse-datei.zip --invert-paths
Detached HEAD State
# Zu einem Branch zurückkehren
git checkout main
# Änderungen aus Detached HEAD in neuem Branch speichern
git checkout -b neuer-branch
Versehentlich überschriebene Änderungen wiederherstellen
# Reflog verwenden um verlorene Commits zu finden
git reflog
# Zu einem früheren Zustand zurückkehren
git reset --hard HEAD@{5}
Best Practices
Commit-Messages
Gute Commit-Messages folgen diesem Format:
<Typ>: <Kurzbeschreibung (max 50 Zeichen)>
<Detaillierte Beschreibung (optional, 72 Zeichen pro Zeile)>
<Footer (optional): Issue-Referenzen, Breaking Changes, etc.>
Typen:
feat: Neues Featurefix: Bugfixdocs: Dokumentationstyle: Formatierung, kein Code-Changerefactor: Code-Refactoringtest: Tests hinzufügen oder anpassenchore: Build-Prozess, Dependencies, etc.
Beispiele:
feat: Benutzer-Login mit OAuth implementieren
fix: Null-Pointer Exception beim Speichern
docs: README mit Installationsanleitung aktualisiert
refactor: Datenbankzugriff in separate Klasse ausgelagert
Workflow-Empfehlungen
- Häufig committen: Kleine, logische Commits sind besser als große
- Branch-Strategie: Feature-Branches für neue Entwicklungen
- Pull Requests: Code-Review vor dem Merge
- Main/Master schützen: Direkte Commits vermeiden
- Rebase vor Merge: Saubere, lineare History
- Tests vor Push: Lokale Tests durchführen
- Force-Push vermeiden: Besonders bei Shared Branches
- Regelmäßig pullen: Konflikte früh erkennen
Branch-Naming-Konventionen
feature/kurze-beschreibung
bugfix/issue-nummer-beschreibung
hotfix/kritischer-bug
release/version-nummer
Beispiele:
feature/user-authentication
bugfix/login-validation
hotfix/security-patch
release/v1.2.0
Fortgeschrittene Befehle
Bisect - Buggy Commit finden
# Bisect starten
git bisect start
# Aktuellen Commit als "bad" markieren
git bisect bad
# Bekannten guten Commit markieren
git bisect good <commit-hash>
# Git checked automatisch Commits aus
# Nach jedem Test:
git bisect good # wenn OK
git bisect bad # wenn Bug vorhanden
# Bisect beenden
git bisect reset
Worktree - Mehrere Branches gleichzeitig
# Neuen Worktree erstellen
git worktree add ../projekt-feature feature/neue-funktion
# Alle Worktrees anzeigen
git worktree list
# Worktree entfernen
git worktree remove ../projekt-feature
# Aufräumen
git worktree prune
Blame - Änderungen pro Zeile anzeigen
# Zeigt wer welche Zeile wann geändert hat
git blame dateiname.txt
# Mit Zeilennummern
git blame -L 10,20 dateiname.txt
# Ignore Whitespace-Änderungen
git blame -w dateiname.txt
Clean - Untracked Files entfernen
# Anzeigen was gelöscht würde (Dry-Run)
git clean -n
# Untracked Files löschen
git clean -f
# Auch Verzeichnisse löschen
git clean -fd
# Auch ignored Files löschen
git clean -fdx
Git Hooks
Hooks sind Skripte die bei bestimmten Git-Events ausgeführt werden:
# Hooks befinden sich in:
.git/hooks/
# Beispiel: pre-commit Hook
# Datei: .git/hooks/pre-commit
#!/bin/bash
npm run lint
npm test
# Ausführbar machen
chmod +x .git/hooks/pre-commit
Wichtige Hooks:
pre-commit: Vor jedem Commitpre-push: Vor jedem Pushpost-merge: Nach jedem Mergepost-checkout: Nach Branch-Wechsel
Nützliche Tipps
Farbige Ausgabe aktivieren
git config --global color.ui auto
Automatisches Stash bei Rebase
git config --global rebase.autoStash true
Default Branch Name
git config --global init.defaultBranch main
Pull Strategie festlegen
# Rebase als Standard beim Pull
git config --global pull.rebase true
# Fast-Forward only
git config --global pull.ff only
Editor für Commit-Messages
git config --global core.editor "nano"
# oder für VS Code
git config --global core.editor "code --wait"
Globales .gitignore
# Erstellen
touch ~/.gitignore_global
# Konfigurieren
git config --global core.excludesfile ~/.gitignore_global
# Beispiel-Inhalt: IDE und OS-spezifische Dateien
echo ".DS_Store" >> ~/.gitignore_global
echo ".vscode/" >> ~/.gitignore_global
echo "*.swp" >> ~/.gitignore_global