~ $

git cheatsheet

— basics · intermediate · advanced · tags
Basics Intermediate Advanced Tags & Releases

Setup & Init

Basics
Name konfigurieren
git config --global user.name "Name"
E-Mail konfigurieren
git config --global user.email "…"
Standard-Editor
git config --global core.editor vim
Alle Einstellungen anzeigen
git config --list
Neues Repository
git init
Repository klonen
git clone <url>
Clone in Ordner
git clone <url> ordner/
Nur einen Branch klonen
git clone -b main --single-branch <url>

Stage & Commit

Basics
Status anzeigen
git status
Alle Änderungen stagen
git add .
Datei stagen
git add datei.txt
Interaktiv stagen
git add -p
Datei unstagen
git restore --staged datei.txt
Änderung verwerfen
git restore datei.txt
Commit erstellen
git commit -m "message"
Stage + Commit
git commit -am "message"
Letzten Commit ändern
git commit --amend
Amend ohne Message-Edit
git commit --amend --no-edit
Leerer Commit
git commit --allow-empty -m "trigger"

Branches — Basics

Basics
Alle Branches anzeigen
git branch -a
Branch erstellen
git branch feature/xyz
Branch wechseln
git switch feature/xyz
Erstellen + wechseln
git switch -c feature/xyz
Branch umbenennen
git branch -m alt neu
Branch löschen (safe)
git branch -d feature/xyz
Branch löschen (force)
git branch -D feature/xyz
Remote-Branch löschen
git push origin --delete feature/xyz
Mergen
git merge feature/xyz
Merge ohne Fast-Forward
git merge --no-ff feature/xyz
Merge abbrechen
git merge --abort

Remote — Basics

Basics
Remotes anzeigen
git remote -v
Remote hinzufügen
git remote add origin <url>
Remote-URL ändern
git remote set-url origin <url>
Remote entfernen
git remote remove origin
Pushen
git push origin main
Push + Upstream setzen
git push -u origin main
Pullen
git pull
Pull mit Rebase
git pull --rebase
Fetch (kein Merge)
git fetch origin
Alle Remotes fetchen
git fetch --all
Pruning (gelöschte sync)
git fetch --prune

Log & Diff — Basics

Basics
Log (kompakt)
git log --oneline
Log mit Graph
git log --oneline --graph --all
Log einer Datei
git log -- datei.txt
Log nach Autor
git log --author="Name"
Log seit Datum
git log --since="2 weeks ago"
Letzten N Commits
git log -n 10
Nicht-gestagede Diff
git diff
Gestagede Diff
git diff --staged
Zwischen Branches
git diff main..feature
Statistik
git diff --stat
Blame
git blame datei.txt

Stash

Intermediate
Änderungen sichern
git stash
Mit Namen sichern
git stash push -m "WIP: login"
Inkl. Untracked
git stash -u
Alle Stashes anzeigen
git stash list
Letzten anwenden
git stash pop
Bestimmten anwenden
git stash apply stash@{2}
Stash anzeigen
git stash show -p stash@{0}
Stash löschen
git stash drop stash@{1}
Alle Stashes löschen
git stash clear
Stash als Branch
git stash branch feature/xyz stash@{0}

Rebase

Intermediate
Rebase auf main
git rebase main
Interaktiver Rebase
git rebase -i HEAD~3
Rebase fortsetzen
git rebase --continue
Rebase abbrechen
git rebase --abort
Rebase überspringen
git rebase --skip
i-Rebase: squash
s
i-Rebase: fixup (kein Msg)
f
i-Rebase: edit
e
i-Rebase: drop
d
i-Rebase: reword
r
Autosquash (fixup! msgs)
git rebase -i --autosquash

Reset & Revert

Intermediate
Soft reset (Stage bleibt)
git reset --soft HEAD~1
Mixed reset (Standard)
git reset HEAD~1
Hard reset (alles weg)
git reset --hard HEAD~1
Auf Remote-Stand
git reset --hard origin/main
Commit rückgängig (sicher)
git revert <hash>
Revert ohne Commit
git revert -n <hash>
Revert eines Merges
git revert -m 1 <merge-hash>
Datei auf Commit-Stand
git checkout <hash> -- datei.txt
ORIG_HEAD (nach Merge)
git reset --hard ORIG_HEAD

Cherry-pick & Bisect

Intermediate
Commit übernehmen
git cherry-pick <hash>
Ohne Commit anwenden
git cherry-pick -n <hash>
Mehrere Commits
git cherry-pick A..B
Cherry-pick abbrechen
git cherry-pick --abort
Cherry-pick fortsetzen
git cherry-pick --continue
Bisect starten
git bisect start
Aktuell als schlecht markieren
git bisect bad
Guten Commit angeben
git bisect good v1.2.0
Bisect beenden
git bisect reset
Bisect automatisieren
git bisect run ./test.sh

Submodules

Intermediate
Submodule hinzufügen
git submodule add <url> pfad/
Klonen inkl. Submodules
git clone --recurse-submodules <url>
Submodules initialisieren
git submodule update --init
Alle updaten
git submodule update --remote
Status anzeigen
git submodule status
Submodule entfernen
git submodule deinit pfad/
In allen ausführen
git submodule foreach 'git pull'

Reflog & Recovery

Advanced
Reflog anzeigen
git reflog
Reflog eines Branches
git reflog show main
Auf alten Stand springen
git checkout HEAD@{3}
Gelöschten Branch recovery
git branch recovered HEAD@{2}
Dangling Commits finden
git fsck --lost-found
Objekte aufräumen
git gc --prune=now
Commit suchen (Inhalt)
git log -S "suchbegriff"
Commit suchen (Regex)
git log -G "regex"
Wann Zeile geändert
git log -L :funktion:datei.go

Worktrees & Hooks

Advanced
Worktree hinzufügen
git worktree add ../hotfix hotfix/v2
Worktrees anzeigen
git worktree list
Worktree entfernen
git worktree remove ../hotfix
Hooks-Verzeichnis
.git/hooks/
Pre-commit Hook
.git/hooks/pre-commit
Commit-msg Hook
.git/hooks/commit-msg
Pre-push Hook
.git/hooks/pre-push
Post-receive Hook
.git/hooks/post-receive
Hooks global setzen
git config --global core.hooksPath ~/.githooks
Hook überspringen
git commit --no-verify

Advanced Config & Aliases

Advanced
Alias erstellen
git config --global alias.lg "log --oneline --graph"
Alias aufrufen
git lg
Shell-Alias in git
git config --global alias.who "!whoami"
Auto-CRLF (Windows)
git config core.autocrlf true
Merge-Strategie
git config pull.rebase true
Push-Default
git config push.default current
Rerere aktivieren
git config rerere.enabled true
Sparse Checkout
git sparse-checkout set ordner/
Partial Clone
git clone --filter=blob:none <url>
Große Repos (LFS)
git lfs track "*.psd"

Tags — Erstellen & Verwalten

Tags
Lightweight Tag
git tag v1.0.0
Annotierter Tag
git tag -a v1.0.0 -m "Release v1.0.0"
Tag auf alten Commit
git tag -a v1.0.0 <hash>
Signierter Tag (GPG)
git tag -s v1.0.0 -m "Signed release"
Alle Tags anzeigen
git tag
Tags filtern
git tag -l "v1.*"
Tag-Details
git show v1.0.0
Tag pushen
git push origin v1.0.0
Alle Tags pushen
git push origin --tags
Tag lokal löschen
git tag -d v1.0.0
Tag remote löschen
git push origin --delete v1.0.0
Tag umbenennen
git tag new old && git tag -d old
Letzten Tag finden
git describe --tags --abbrev=0
Commits seit letztem Tag
git describe --tags
Tags fetchen
git fetch --tags

Branching-Strategien — Überblick

Intermediate

Feature Branch Workflow

Der einfachste Ansatz — jedes Feature bekommt einen eigenen Branch. main bleibt immer deploybar.

$ git switch -c feature/login

# … arbeiten, committen …

$ git switch main
$ git merge --no-ff feature/login
$ git branch -d feature/login
$ git push origin main

Git Flow (klassisch)

Strukturiert mit main, develop, release/, hotfix/ und feature/ Branches.

# Feature starten
$ git switch -c feature/xyz develop

# Release vorbereiten
$ git switch -c release/1.2.0 develop

# Hotfix
$ git switch -c hotfix/crash main
$ git merge hotfix/crash # → main + develop

# Release mergen + taggen
$ git merge release/1.2.0
$ git tag -a v1.2.0 -m "Release 1.2.0"

Trunk-Based Development

Alle committen direkt auf main — Feature Flags statt Long-Lived Branches. Bevorzugt von Google, Meta, Shopify.

# Sehr kurze Feature-Branches
$ git switch -c feat/btn
# max. 1-2 Tage, dann merge

# Feature Flags im Code
# if (featureFlags.newUI) { … }

# Direkt auf main mit CI
$ git push origin main
# → CI läuft, Deploy wenn grün

Rebase deep-dive — History aufräumen

Advanced

Merge vs. Rebase

Merge bewahrt die komplette History — ein Merge-Commit dokumentiert wann Branches zusammengeführt wurden. Rebase schreibt die History um — linearer, sauberer Log, aber Commits bekommen neue Hashes.

# Merge: bewahrt History, extra Commit
$ git switch main
$ git merge feature/xyz
# → Merge commit: "Merge branch 'feature/xyz'"

# Rebase: linearer Log, neue Hashes
$ git switch feature/xyz
$ git rebase main
$ git switch main
$ git merge feature/xyz   # Fast-Forward

# Goldene Regel:
# Niemals public/shared Branches rebases!

Interaktiver Rebase — Commits aufräumen

Vor dem Merge: History squashen, Messages verbessern, Commits neu ordnen.

# Letzten 4 Commits bearbeiten
$ git rebase -i HEAD~4

# Im Editor erscheint:
# pick abc1234 WIP
# pick def5678 fix typo
# pick ghi9012 more fixes
# pick jkl3456 feat: login done

# → ändern zu:
# pick abc1234 WIP
# f    def5678 fix typo        (fixup)
# f    ghi9012 more fixes      (fixup)
# r    jkl3456 feat: login done (reword)

# Ergebnis: 1 sauberer Commit
$ git push --force-with-lease origin feature/login

Tags — Releases & CI/CD Pipeline Trigger

Tags

Lightweight vs. Annotiert

Ein Lightweight Tag ist nur ein Zeiger auf einen Commit — kein eigenes Objekt. Ein Annotierter Tag ist ein vollständiges Git-Objekt mit Autor, Datum, Message und optional GPG-Signatur.

# Lightweight — nur ein Pointer
$ git tag v1.0.0

# Annotiert — eigenes Objekt, empfohlen!
$ git tag -a v1.0.0 -m "Release v1.0.0"

# Details vergleichen:
$ git show v1.0.0
# Annotiert zeigt: Tagger, Datum, Message
# Lightweight: direkt der Commit

# Signiert (GPG-Key nötig)
$ git tag -s v1.0.0 -m "Signed release"
$ git tag -v v1.0.0   # verifizieren

Semantic Versioning mit Tags

Tags folgen typischerweise SemVer: v{MAJOR}.{MINOR}.{PATCH}. Pre-release und Build-Metadata sind auch möglich.

# Stabile Releases
v1.0.0   → Initial Release
v1.1.0   → Neues Feature (backward compat.)
v1.1.1   → Bugfix
v2.0.0   → Breaking Change

# Pre-releases
v2.0.0-alpha.1
v2.0.0-beta.3
v2.0.0-rc.1

# Letzte Version ermitteln
$ git describe --tags --abbrev=0
# v1.1.1

# Commits seit letztem Tag
$ git describe --tags
# v1.1.1-14-gabcd123

Tags als CI/CD Trigger

Das Pushen eines Tags ist das Signal, dass eine Version release-ready ist. Die meisten CI/CD-Systeme können auf Tag-Pushes reagieren und so automatisch Pipelines, Deployments oder GitHub Releases auslösen — komplett separat vom normalen Branch-Push.

# GitHub Actions — on tag push
# .github/workflows/release.yml
on:
  push:
    tags:
      - 'v*'          # v1.0.0, v2.3.1 …

# GitLab CI — only on tags
deploy:
  only:
    - tags

# Tag erstellen + pushen → löst Pipeline aus
$ git tag -a v1.2.0 -m "Release v1.2.0"
$ git push origin v1.2.0
# → CI baut, testet, deployed automatisch
⚡ Wichtig: Tags werden nicht automatisch mit git push gepusht — immer explizit git push origin <tagname> oder git push --tags verwenden. Annotierte Tags sind für Releases vorzuziehen, da sie Metadaten und einen sauberen Changelog ermöglichen.

Advanced Workflows — Praxis-Beispiele

Advanced

Nützliche Aliases (.gitconfig)

[alias]
  # Übersichtlicher Log-Graph
  lg = log --oneline --graph --all \
       --decorate --color

  # Letzten Commit rückgängig (soft)
  undo = reset --soft HEAD~1

  # Aktuellen Branch + Status
  st = status -sb

  # Alle Branches nach letztem Commit
  recent = branch --sort=-committerdate -v

  # Staged Diff anzeigen
  staged = diff --staged

  # Leeren Commit (Pipeline triggern)
  trigger = commit --allow-empty -m "chore: trigger CI"

  # Alle gemergten Branches löschen
  cleanup = "!git branch --merged | \
    grep -v 'main\\|master\\|develop' | \
    xargs git branch -d"

Release-Workflow (End-to-End)

# 1. Feature fertig, History aufräumen
$ git rebase -i HEAD~5
$ git push --force-with-lease

# 2. Nach PR-Merge: main updaten
$ git switch main
$ git pull --rebase

# 3. Changelog aus Commits generieren
$ git log v1.1.0..HEAD --oneline

# 4. Tag erstellen und pushen
$ git tag -a v1.2.0 -m "$(cat CHANGELOG.md)"
$ git push origin v1.2.0
# → GitHub Actions Release-Pipeline startet
# → Docker Image wird gebaut & gepusht
# → Deployment auf Production

# 5. GitHub Release aus Tag (CLI)
$ gh release create v1.2.0 \
  --title "v1.2.0" \
  --notes-file CHANGELOG.md