Ecco la configurazione git che uso su ogni macchina, undici impostazioni globali e venti alias, ognuno lì perché elimina un fastidio quotidiano specifico. Rubali tutti.
Un po' di tempo fa, un collega mi ha visto fare push di un branch nuovo di zecca e mi ha fermato:
"Aspetta, come ha fatto a funzionare? Niente
--set-upstream?"
Una riga di configurazione. Lui digitava quella soluzione manuale da anni.
Quella conversazione è il motivo per cui esiste questo articolo. La maggior parte degli sviluppatori usa git con le impostazioni di fabbrica, e le impostazioni di fabbrica di git non sono progettate per te. Sono progettate per la compatibilità. Git preferirebbe interromperti mille volte piuttosto che sorprenderti una volta.
Quindi tutti pagano in silenzio la stessa tassa quotidiana, per lo più senza più accorgersene:
fatal: The current branch has no upstream branch, digitato la soluzione così spesso che è diventata automatica- Commit di merge che inquinano la storia perché un pull semplice fa un merge
.DS_Storeche compare in ognigit statussu ogni progetto Mac- Risolvere per la quinta volta lo stesso conflitto di rebase
- Fare commit sul repository dell'ufficio con l'email personale
Ognuno di questi è una soluzione da una riga che git spedisce, ma disattivata.

Quello che segue è la mia configurazione reale, quella che mi porto dietro su ogni macchina. Non uno scarico di tutto ciò che git supporta: ogni riga qui si è guadagnata il posto eliminando un fastidio vero. Due atti: prima le impostazioni globali, perché cambiano il comportamento di git ovunque; poi gli alias, perché cambiano quanto velocemente lo guidi.
🪪 Atto primo: identità, l'impostazione che può metterti in imbarazzo
Si parte da quella con conseguenze:
git config --global user.name "Paurush Rai"
git config --global user.email "personal@email.com"Ovvio. Ma ecco la parte che quasi nessuno sviluppatore configura mai: l'instradamento automatico lavoro/personale.
Tengo il codice del datore di lavoro sotto ~/Developer/company/. Un blocco in ~/.gitconfig:
[includeIf "gitdir:~/Developer/company/"]
path = ~/.gitconfig-workE ~/.gitconfig-work contiene esattamente una cosa:
[user]
email = work@company.com
Ora l'identità è decisa da dove vive il repository. Clona qualsiasi cosa in company/ → email di lavoro, automaticamente. Tutto il resto → personale. Niente da ricordare, niente setup per repository, niente email personale nel registro di audit aziendale, e niente email di lavoro sui side project del weekend.
(Nota cosa non c'è nel file di lavoro: il nome. includeIf si sovrappone sopra la configurazione globale, quindi il file di lavoro dichiara solo ciò che cambia, l'email. Tutto il resto viene ereditato.)
Questo conta più di quanto sembri, perché le email dei commit sono permanenti. Fai push con l'identità sbagliata e resterà nella storia per sempre; GitHub attribuisce il commit a qualunque account possieda quell'email. L'identità dovrebbe essere una proprietà del repository, non di quello che ti sei ricordato di digitare l'ultima volta.
⚙️ Atto primo, continua: le impostazioni di comportamento
Undici righe. Ognuna elimina un fastidio specifico e ricorrente.
Non vedere mai più "no upstream branch"
git config --global push.autoSetupRemote trueL'errore che ogni sviluppatore ha memorizzato, fatal: The current branch has no upstream branch, esiste perché git possa chiedere il permesso di fare la cosa ovvia. Questa impostazione lo concede in modo permanente. Il primo push su un branch nuovo funziona e basta. (È la riga che ha interrotto il mio collega a metà frase.)
Smetti di generare commit di merge accidentali
git config --global pull.rebase trueUn git pull di default è fetch + merge, ed è così che i commit "Merge branch 'main' of github.com..." finiscono per tappezzare la tua storia. Con questa impostazione, pull rigioca i tuoi commit locali sopra quello che è arrivato. Storia lineare, niente rumore.
Fai partire i nuovi repository su main
git config --global init.defaultBranch mainAltrimenti ogni git init parte su master e lo rinomini dopo. Una riga, non ci pensi più.
Smetti di accumulare branch morti
git config --global fetch.prune trueQuando un branch viene cancellato sul remoto (per lo più PR mergiati), la tua copia locale di origin/quel-branch resta lì per sempre. Questa cancella automaticamente i riferimenti obsoleti a ogni fetch. La tua lista di branch resta onesta.
Bandisci .DS_Store da ogni repository per sempre
git config --global core.excludesfile ~/.gitignore_global
echo ".DS_Store" > ~/.gitignore_globalUn file di ignore globale si applica sopra il .gitignore di ogni singolo repository. Detriti di macOS, file di swap dell'editor, gestiti una volta, a livello di macchina, invece che una volta per progetto.
La trinità del risolutore di conflitti
git config --global merge.conflictstyle zdiff3
git config --global rerere.enabled true
git config --global rebase.autostash trueTre impostazioni che insieme trasformano la risoluzione dei conflitti:
zdiff3 aggiunge una terza sezione ai marcatori di conflitto, il testo originale da cui entrambe le parti sono partite. I marcatori standard mostrano "il tuo" e "il loro" e ti fanno indovinare l'intento. Vedere l'antenato comune trasforma l'indovinare in un leggere.

rerere ("reuse recorded resolution") è la sorpresa migliore di tutte e undici. Git registra come risolvi ogni conflitto, e quando lo stesso conflitto riappare (i rebase adorano ripetere i conflitti), rigioca automaticamente la tua risoluzione. Il quinto conflitto identico si risolve da solo.
autostash elimina la danza del "cannot rebase: you have unstaged changes". Git mette in stash il tuo lavoro, fa il rebase e lo ripristina. Quello che stavi facendo sopravvive.
Qualità della vita, due righe
git config --global diff.algorithm histogram
git config --global branch.sort -committerdateHistogram produce diff sensibilmente più puliti rispetto all'algoritmo Myers di default, meno di quei blocchi confusi dove git accoppia righe non correlate. E ordinare i branch per attività recente significa che git branch mostra prima quello su cui stai davvero lavorando, non un'archeologia alfabetica.
⌨️ Atto secondo: gli alias
Le impostazioni cambiano il comportamento di git. Gli alias cambiano la tua velocità. Ne tengo venti curati, raggruppati per ciò che risparmiano.

La guida quotidiana
st = status -sb
cm = commit -m
sw = switch
co = checkout
amend = commit --amend --no-editstatus -sb merita una nota: è lo status su due righe. Stato del branch più file cambiati, senza paragrafi di consigli che hai smesso di leggere anni fa.
Vedere chiaramente
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 è il mio "dove sono", venti commit, disegnati come un grafo. E git whoami chiude il cerchio dell'Atto primo: eseguilo in qualsiasi repository e stampa esattamente quale identità firmerà il prossimo commit. In company/ mostra la mia email di lavoro; ovunque altro, quella personale. Fiducia, verificata in un comando.
Annullare senza paura
unstage = restore --staged
undo = reset --soft HEAD~1
wip = !git add -A && git commit -m "wip: checkpoint"undo annulla il commit senza distruggere nulla, le modifiche tornano nello staging. wip fa uno snapshot di tutto prima di un intervento rischioso. La maggior parte dell'ansia da git non è sapere la via di ritorno sicura; questi sono la via di ritorno sicura.
Le mosse da professionista
pf = push --force-with-lease
fixup = commit --fixup
ri = rebase -i --autosquash
cleanup = !git branch --merged | grep -vE "^\*|main|master" | xargs git branch -dpf è quello importante: --force-with-lease fa force-push solo se il remoto è dove l'hai visto l'ultima volta, cioè si rifiuta fisicamente di sovrascrivere il lavoro di un collega che è arrivato nel frattempo. Non c'è situazione in cui il --force grezzo sia la scelta migliore. Aliasarlo significa che le mie dita non digitano mai la versione pericolosa.
La coppia fixup + ri è il flusso di lavoro per una storia pulita: fai il commit di una correzione mirata a un commit precedente, poi un rebase interattivo piega tutto al proprio posto automaticamente.
🎯 La parte che la rende permanente
Ecco la cosa sulla configurazione: costruirla è facile. Mantenerla è il problema vero. Una configurazione che vive solo sulla tua macchina attuale è una configurazione che ricostruirai a memoria sulla prossima.
Il mio ~/.gitconfig non è un file sciolto, è un symlink dentro un repository di dotfiles che fa auto-commit e push di ogni modifica nel momento in cui accade. Quando ho aggiunto di recente un nuovo alias, un agente in background l'aveva già committato su GitHub prima ancora che finissi di testarlo.
(Quel sistema, symlink più un agente launchd, niente cron, niente strumenti di terze parti, è una storia a sé, che ho scritto separatamente.)
La conseguenza: l'intero setup, instradamento dell'identità e tutti e venti gli alias inclusi, arriva su qualsiasi macchina con un solo install.sh. Configura una volta, mantieni per sempre.
📋 Il tutto, pronto per il copia-incolla
# 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)>"'Più l'instradamento dell'identità, se tieni il codice di lavoro in una directory dedicata:
git config --global includeIf."gitdir:~/Developer/company/".path ~/.gitconfig-work
printf '[user]\n email = you@work.com\n' > ~/.gitconfig-workLa lezione
Nessuna di queste impostazioni è impressionante da sola. È proprio questo il punto.
Le impostazioni di default di git ottimizzano per non sorprendere mai nessuno, il che significa che interrompono tutti. Ogni riga qui sopra converte un'interruzione ricorrente in silenzio, e il silenzio si accumula. Moltiplica pochi secondi risparmiati e un commit con l'email sbagliata evitato su ogni repository che toccherai mai, e questa mezz'ora di configurazione è tra il tempo più ad alto rendimento che spenderai sui tuoi strumenti.
Il mio collega ha configurato push.autoSetupRemote lo stesso pomeriggio in cui l'ha visto. La soluzione manuale che digitava da anni è sparita con una riga, ci è voluto solo vedere qualcuno non pagare la tassa per capire che era facoltativa.
Considera questo articolo quel momento, in forma scritta. Esegui cat ~/.gitconfig e guarda cosa c'è davvero dentro.
Le impostazioni di default sono per la compatibilità. La configurazione è per te.
Cosa c'è nel tuo gitconfig?
Sono sempre a caccia della prossima soluzione da una riga. Se hai un'impostazione o un alias che si è guadagnato il posto, è così che ho trovato metà dei miei.


