Hier ist die Git-Konfiguration, die ich auf jedem Rechner laufen lasse, elf globale Einstellungen und zwanzig Aliase, jede einzelne da, weil sie ein konkretes tägliches Ärgernis killt. Klau dir das alles.
Vor einer Weile sah mir ein Kollege dabei zu, wie ich einen brandneuen Branch pushte, und hielt mich an:
"Moment, wie hat das gerade funktioniert? Kein
--set-upstream?"
Eine Zeile Konfiguration. Er hatte den Workaround jahrelang getippt.
Dieses Gespräch ist der Grund, warum dieser Artikel existiert. Die meisten Entwickler betreiben Git mit Werkseinstellungen, und Gits Werkseinstellungen sind nicht für dich gemacht. Sie sind für Kompatibilität gemacht. Git unterbricht dich lieber tausendmal, als dich einmal zu überraschen.
Also zahlt jeder still dieselbe tägliche Steuer, meist ohne es noch zu bemerken:
fatal: The current branch has no upstream branch, den Fix so oft getippt, dass er Muskelgedächtnis ist- Merge-Commits, die die Historie verschmutzen, weil ein einfacher Pull mergt
.DS_Store, das in jedemgit statusin jedem Mac-Projekt auftaucht- Denselben Rebase-Konflikt zum fünften Mal lösen
- Mit privater E-Mail ins Firmen-Repo committen
Jedes davon ist ein Ein-Zeilen-Fix, den Git mitliefert, aber standardmäßig ausgeschaltet lässt.

Was folgt, ist meine tatsächliche Konfiguration, die, die mit mir auf jeden Rechner reist. Kein Dump von allem, was Git unterstützt: Jede Zeile hier hat sich ihren Platz verdient, indem sie ein echtes Ärgernis killt. Zwei Akte: zuerst die globalen Einstellungen, weil sie Gits Verhalten überall ändern; dann die Aliase, weil sie ändern, wie schnell man es steuern kann.
🪪 Akt eins: Identität, die Einstellung, die dir peinlich werden kann
Beginnen wir mit der, die Konsequenzen hat:
git config --global user.name "Paurush Rai"
git config --global user.email "personal@email.com"Offensichtlich. Aber hier ist der Teil, den die meisten Entwickler nie einrichten: automatisches Arbeit/Privat-Routing.
Ich halte Arbeitgeber-Code unter ~/Developer/company/. Ein Block in ~/.gitconfig:
[includeIf "gitdir:~/Developer/company/"]
path = ~/.gitconfig-workUnd ~/.gitconfig-work enthält genau eine Sache:
[user]
email = work@company.com
Jetzt wird die Identität davon entschieden, wo das Repo liegt. Alles nach company/ klonen → automatisch Arbeits-E-Mail. Alles andere → privat. Kein Merken, kein Pro-Repo-Setup, keine private E-Mail im Firmen-Audit-Log, und keine Arbeits-E-Mail bei Wochenend-Nebenprojekten.
(Beachte, was nicht in der Arbeitsdatei steht: der Name. includeIf legt sich über die globale Konfiguration, also deklariert die Arbeitsdatei nur das, was abweicht, die E-Mail. Alles andere erbt.)
Das zählt mehr, als es aussieht, weil Commit-E-Mails dauerhaft sind. Mit der falschen Identität pushen, und es steht für immer in der Historie; GitHub schreibt den Commit dem Account zu, dem diese E-Mail gehört. Identität sollte eine Eigenschaft des Repos sein, nicht dessen, was man zuletzt zu tippen wusste.
⚙️ Akt eins, fortgesetzt: Die Verhaltenseinstellungen
Elf Zeilen. Jede killt ein konkretes, wiederkehrendes Ärgernis.
Nie wieder "no upstream branch" sehen
git config --global push.autoSetupRemote trueDer Fehler, den sich jeder Entwickler eingeprägt hat, fatal: The current branch has no upstream branch, existiert, damit Git um Erlaubnis fragen kann, das Offensichtliche zu tun. Diese Einstellung erteilt sie dauerhaft. Der erste Push auf einem neuen Branch funktioniert einfach. (Das ist die Zeile, die meinen Kollegen mitten im Satz stoppte.)
Aufhören, versehentliche Merge-Commits zu erzeugen
git config --global pull.rebase trueEin Standard-git pull ist Fetch + Merge, so entstehen die "Merge branch 'main' of github.com..."-Commits, die die Historie tapezieren. Damit spielt Pull deine lokalen Commits oben auf das, was ankam. Lineare Historie, kein Rauschen.
Neue Repos auf main starten lassen
git config --global init.defaultBranch mainSonst startet jedes git init auf master, und man benennt es später um. Eine Zeile, nie wieder daran denken.
Aufhören, tote Branches zu horten
git config --global fetch.prune trueWenn ein Branch remote gelöscht wird (meist gemergte PRs), bleibt die lokale Kopie von origin/that-branch für immer bestehen. Das löscht die veralteten Referenzen bei jedem Fetch automatisch. Die Branch-Liste bleibt ehrlich.
.DS_Store für immer aus jedem Repo verbannen
git config --global core.excludesfile ~/.gitignore_global
echo ".DS_Store" > ~/.gitignore_globalEine globale Ignore-Datei gilt zusätzlich zur eigenen .gitignore jedes Repos. macOS-Hinterlassenschaften, Editor-Swap-Dateien, einmal geregelt, rechnerweit, statt pro Projekt.
Die Dreifaltigkeit der Konfliktlösung
git config --global merge.conflictstyle zdiff3
git config --global rerere.enabled true
git config --global rebase.autostash trueDrei Einstellungen, die zusammen die Konfliktlösung verwandeln:
zdiff3 fügt Konfliktmarkern einen dritten Abschnitt hinzu, den ursprünglichen Text, von dem beide Seiten ausgingen. Standardmarker zeigen "yours" und "theirs" und lassen dich die Absicht erraten. Den gemeinsamen Vorfahren zu sehen macht aus Raten Lesen.

rerere ("reuse recorded resolution") ist der Überraschungshit aller elf. Git merkt sich, wie du jeden Konflikt löst, und wenn derselbe Konflikt wieder auftaucht (Rebases lieben es, Konflikte zu wiederholen), spielt es deine Lösung automatisch ab. Der fünfte identische Konflikt löst sich von selbst.
autostash beseitigt den "cannot rebase: you have unstaged changes"-Tanz. Git stasht deine Arbeit, rebased, stellt sie wieder her. Was du gerade gemacht hast, überlebt.
Lebensqualität, zwei Zeilen
git config --global diff.algorithm histogram
git config --global branch.sort -committerdateHistogram erzeugt spürbar sauberere Diffs als der Myers-Standardalgorithmus, weniger von diesen verwürfelten Blöcken, in denen Git unzusammenhängende Zeilen paart. Und Branches nach letzter Aktivität zu sortieren bedeutet, dass git branch zuerst zeigt, woran man tatsächlich arbeitet, nicht alphabetische Archäologie.
⌨️ Akt zwei: Die Aliase
Einstellungen ändern Gits Verhalten. Aliase ändern dein Tempo. Ich halte zwanzig kuratierte, gruppiert nach dem, was sie sparen.

Die Daily Drivers
st = status -sb
cm = commit -m
sw = switch
co = checkout
amend = commit --amend --no-editstatus -sb verdient eine Anmerkung: Es ist der Zwei-Zeilen-Status. Branch-Zustand plus geänderte Dateien, ohne Absätze von Ratschlägen, die man schon lange nicht mehr liest.
Klar sehen
lg = log --oneline --graph --decorate -20
last = log -1 HEAD --stat
d = diff
ds = diff --staged
whoami = !echo "$(git config user.name) <$(git config user.email)>"git lg ist mein "wo bin ich", zwanzig Commits, als Graph gezeichnet. Und git whoami schließt den Kreis zu Akt eins: in jedem Repo ausgeführt, zeigt es genau, welche Identität den nächsten Commit signiert. In company/ zeigt es meine Arbeits-E-Mail, überall sonst die private. Vertrauen, mit einem Befehl verifiziert.
Rückgängig ohne Angst
unstage = restore --staged
undo = reset --soft HEAD~1
wip = !git add -A && git commit -m "wip: checkpoint"undo macht Commits rückgängig, ohne etwas zu zerstören, Änderungen landen zurück im Staging. wip schnappschießt alles vor riskanten Eingriffen. Die meiste Git-Angst kommt daher, den sicheren Weg zurück nicht zu kennen; das sind die sicheren Wege zurück.
Die Profi-Moves
pf = push --force-with-lease
fixup = commit --fixup
ri = rebase -i --autosquash
cleanup = !git branch --merged | grep -vE "^\*|main|master" | xargs git branch -dpf ist der wichtige: --force-with-lease force-pusht nur, wenn das Remote dort ist, wo man es zuletzt gesehen hat, es weigert sich also physisch, die Arbeit eines Kollegen zu überschreiben, die in der Zwischenzeit gelandet ist. Es gibt keine Situation, in der rohes --force die bessere Wahl wäre. Es zu aliasen bedeutet, dass meine Finger nie die gefährliche Version tippen.
Das Paar fixup + ri ist der Clean-History-Workflow: einen Fix committen, der auf einen früheren Commit zielt, dann faltet ein interaktives Rebase alles automatisch an seinen Platz.
🎯 Der Teil, der es dauerhaft macht
Hier ist die Sache mit Konfiguration: Sie zu bauen ist einfach. Sie zu behalten ist das eigentliche Problem. Eine Konfiguration, die nur auf deinem aktuellen Rechner lebt, ist eine Konfiguration, die du auf deinem nächsten aus dem Gedächtnis wieder aufbauen wirst.
Meine ~/.gitconfig ist keine lose Datei, sie ist ein Symlink in ein Dotfiles-Repo, das jede Änderung im Moment ihres Entstehens automatisch committet und pusht. Als ich kürzlich einen neuen Alias hinzufügte, hatte ein Hintergrund-Agent ihn schon auf GitHub committet, bevor ich mit dem Testen fertig war.
(Dieses System, Symlinks plus ein launchd-Agent, kein cron, keine Drittanbieter-Tools, ist eine eigene Geschichte, die ich separat aufgeschrieben habe.)
Die Konsequenz: Dieses ganze Setup, Identitäts-Routing und alle zwanzig Aliase inklusive, landet mit einem install.sh auf jedem Rechner. Einmal konfigurieren, für immer behalten.
📋 Das Ganze, kopierfertig
# identity (edit these!)
git config --global user.name "Your Name"
git config --global user.email "you@personal.com"
# behavior
git config --global init.defaultBranch main
git config --global push.autoSetupRemote true
git config --global pull.rebase true
git config --global fetch.prune true
git config --global core.excludesfile ~/.gitignore_global
echo ".DS_Store" > ~/.gitignore_global
git config --global merge.conflictstyle zdiff3
git config --global rerere.enabled true
git config --global rebase.autostash true
git config --global diff.algorithm histogram
git config --global branch.sort -committerdate
# aliases
git config --global alias.st "status -sb"
git config --global alias.cm "commit -m"
git config --global alias.sw "switch"
git config --global alias.co "checkout"
git config --global alias.amend "commit --amend --no-edit"
git config --global alias.lg "log --oneline --graph --decorate -20"
git config --global alias.last "log -1 HEAD --stat"
git config --global alias.d "diff"
git config --global alias.ds "diff --staged"
git config --global alias.unstage "restore --staged"
git config --global alias.undo "reset --soft HEAD~1"
git config --global alias.wip '!git add -A && git commit -m "wip: checkpoint"'
git config --global alias.pf "push --force-with-lease"
git config --global alias.fixup "commit --fixup"
git config --global alias.ri "rebase -i --autosquash"
git config --global alias.cleanup '!git branch --merged | grep -vE "^\*|main|master" | xargs git branch -d'
git config --global alias.root "rev-parse --show-toplevel"
git config --global alias.aliases "config --get-regexp ^alias"
git config --global alias.whoami '!echo "$(git config user.name) <$(git config user.email)>"'Plus das Identitäts-Routing, falls du Arbeitscode in einem eigenen Verzeichnis hältst:
git config --global includeIf."gitdir:~/Developer/company/".path ~/.gitconfig-work
printf '[user]\n email = you@work.com\n' > ~/.gitconfig-workDie Lektion
Keine dieser Einstellungen ist für sich genommen beeindruckend. Das ist der Punkt.
Gits Standardeinstellungen optimieren dafür, niemanden zu überraschen, was bedeutet, dass sie jeden unterbrechen. Jede Zeile oben verwandelt eine wiederkehrende Unterbrechung in Stille, und Stille summiert sich. Multipliziere ein paar gesparte Sekunden und einen vermiedenen Falsch-E-Mail-Commit über jedes Repo, das du je anfassen wirst, und diese halbe Stunde Konfiguration ist eine der höchst-hebelnden Zeiten, die du in Tooling investieren wirst.
Mein Kollege hat push.autoSetupRemote am selben Nachmittag eingerichtet, an dem er es sah. Der Workaround, den er jahrelang getippt hatte, verschwand mit einer Zeile, es brauchte nur zu sehen, wie jemand die Steuer nicht zahlt, um zu merken, dass sie optional war.
Betrachte diesen Artikel als diesen Moment, in schriftlicher Form. Führ cat ~/.gitconfig aus und schau dir an, was da tatsächlich drin steht.
Standardeinstellungen sind für Kompatibilität da. Konfiguration ist für dich da.
Was steht in deiner gitconfig?
Ich bin immer auf der Suche nach dem nächsten Ein-Zeilen-Fix. Wenn du eine Einstellung oder einen Alias hast, der sich seinen Platz verdient hat, so habe ich die Hälfte meiner gefunden.


