Fehlerbehebung bei Git-Konfigurationsproblemen: Häufige Lösungen und bewährte Methoden
Beheben Sie Git-Konfigurationsprobleme, indem Sie die Herkunft der Einstellungen zurückverfolgen, Identitäts-, Alias-, Hook-, Zeilenendungs-, Pull- und Anmeldeinformationsprobleme lösen.
Fehlerbehebung bei Git-Konfigurationsproblemen: Häufige Lösungen und bewährte Methoden
Die meisten Git-Konfigurationsprobleme wirken seltsamer, als sie sind. Git tut normalerweise genau das, was ihm eine seiner Konfigurationsdateien sagt. Der schwierige Teil ist, die richtige Datei zu finden, da die Einstellung im Repository, in Ihrer Benutzerkonfiguration, einer Systemkonfiguration, einer eingebundenen Datei oder einem bedingten Include leben kann, das nur in einem bestimmten Verzeichnis gilt.
Der Befehl, den ich zuerst verwende, ist dieser:
git config --list --show-origin --show-scope
Wenn Ihre Git-Version --show-scope nicht unterstützt, verwenden Sie:
git config --list --show-origin
Die Herkunft sagt Ihnen, welche Datei jeden Wert geliefert hat. Das ist wichtiger als der Wert allein. [email protected] zu sehen, reicht nicht; Sie müssen wissen, ob es aus .git/config, ~/.gitconfig, /etc/gitconfig oder einem eingebundenen Arbeitsprofil stammt.
Git-Konfiguration hat eine Prioritätsreihenfolge. Die lokale Repository-Konfiguration überschreibt normalerweise die globale Benutzerkonfiguration, und die globale Konfiguration überschreibt die Systemkonfiguration. Befehlszeilenoptionen und Umgebungsvariablen können alle für einen Befehl überschreiben. Bedingte Includes fügen eine weitere Ebene hinzu: Eine globale Datei kann sagen: "Wenn ich mich in diesem Verzeichnis befinde, lade auch diese andere Konfiguration."
Sie können eine Einstellung mit ihrer Quelle überprüfen:
git config --show-origin --get user.email
git config --show-origin --get core.autocrlf
git config --show-origin --get-regexp '^alias\.'
Diese Gewohnheit verhindert viel unnötiges Bearbeiten. Wenn ein Repository user.email lokal gesetzt hat, wird das Ändern von git config --global user.email keine Commits in diesem Repository beeinflussen.
Falscher Name oder falsche E-Mail bei Commits
Das Symptom ist einfach: Commits zeigen den falschen Autor. Dies passiert oft, wenn Sie denselben Laptop für Arbeit und private Projekte verwenden oder wenn Sie ein Firmen-Repository klonen, bevor Sie Ihre Arbeits-E-Mail eingerichtet haben.
Überprüfen Sie, was Git im aktuellen Repository verwenden wird:
git config user.name
git config user.email
git config --show-origin --get user.email
Setzen Sie Ihre Standardidentität global:
git config --global user.name "Ihr Name"
git config --global user.email "[email protected]"
Für ein Repository setzen Sie es lokal:
git config --local user.name "Ihr Name"
git config --local user.email "[email protected]"
Wenn Sie möchten, dass Git Commits ablehnt, wenn die Identität nicht explizit konfiguriert ist, verwenden Sie:
git config --global user.useConfigOnly true
Diese Einstellung ist nützlich für Personen, die zwischen Identitäten wechseln. Sie kann Anfänger verärgern, da Git nicht mehr aus dem Systembenutzernamen und Hostnamen rät. Verwenden Sie sie, wenn Sie lieber einen Commit fehlschlagen lassen, als einen mit der falschen Adresse zu erstellen.
Für eine sauberere Arbeit/Privat-Trennung verwenden Sie bedingte Includes:
# ~/.gitconfig
[user]
name = Ihr Name
email = [email protected]
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work
Fügen Sie dann dies in ~/.gitconfig-work ein:
[user]
email = [email protected]
Der abschließende Schrägstrich in gitdir:~/work/ ist wichtig, da er Repositories in diesem Verzeichnis bedeutet. Wenn es nicht ausgelöst wird, führen Sie git config --list --show-origin von einem Arbeits-Repository aus und überprüfen Sie, ob die eingebundene Datei erscheint.
Wenn Sie bereits Commits mit der falschen E-Mail erstellt haben, behebt die Änderung der Konfiguration nur zukünftige Commits. Für unveröffentlichte Commits können Sie amend oder rebase verwenden. Fragen Sie bei bereits auf einen gemeinsamen Branch gepushten Commits, bevor Sie die Geschichte umschreiben.
Aliase, die nicht funktionieren
Git-Aliase werden unter alias.* gespeichert. Listen Sie sie so auf:
git config --get-regexp '^alias\.'
Ein normaler Alias erweitert sich zu einem Git-Unterbefehl:
git config --global alias.st 'status -sb'
git st
Wenn der Alias eine Shell-Pipeline, Variablenexpansion, cd oder einen anderen Nicht-Git-Befehl benötigt, muss er mit ! beginnen:
git config --global alias.recent '!git for-each-ref --sort=-committerdate --count=10 --format="%(refname:short)" refs/heads/'
Ohne ! versucht Git, das erste Wort als Git-Befehl zu behandeln. ls -la wird zu "führe den Git-Befehl namens ls aus", was nicht gemeint ist.
Anführungszeichen sind der andere häufige Fehler. Wenn Sie Aliase von der Shell aus definieren, verwenden Sie nach Möglichkeit einfache Anführungszeichen um den gesamten Alias und dann doppelte Anführungszeichen darin, wenn nötig. Verschiedene Shells behandeln Anführungszeichen unterschiedlich, insbesondere PowerShell und cmd.exe. Wenn ein komplexer Alias immer wieder bricht, bearbeiten Sie die Konfigurationsdatei direkt:
git config --global --edit
Ein praktischer Debug-Trick ist, mit dem Befehl außerhalb von Git zu beginnen. Sobald es funktioniert, fügen Sie es in den Alias ein. Wenn es ein Shell-Alias ist, stellen Sie ! voran und testen Sie erneut.
Achten Sie auch auf Aliase, die mentale Modelle überschatten. Ein Alias namens pull oder merge kann Git-Verhalten überraschend machen. Git erlaubt es Aliassen nicht, eingebaute Befehle direkt zu überschreiben, aber Shell-Aliase und Wrapper-Skripte können es. Wenn git pull sich seltsam verhält, überprüfen Sie auch Ihre Shell-Konfiguration:
type git
alias | grep git
Hooks, die nie ausgeführt werden
Hooks schlagen aus drei langweiligen Gründen fehl: Git sucht in einem anderen Hooks-Verzeichnis, die Datei ist nicht ausführbar, oder das Skript nimmt eine Umgebung an, die es nicht hat.
Überprüfen Sie den konfigurierten Hooks-Pfad:
git config --show-origin --get core.hooksPath
Wenn dies .githooks ausgibt, verwendet Git .githooks/pre-commit, nicht .git/hooks/pre-commit. Wenn es nichts ausgibt, verwendet Git .git/hooks.
Unter macOS und Linux überprüfen Sie die Berechtigungen:
ls -l .git/hooks/pre-commit .githooks/pre-commit 2>/dev/null
chmod +x .githooks/pre-commit
Ein Hook, der mit einem Nicht-Null-Status beendet wird, blockiert die Git-Operation. Fügen Sie temporäres Tracing nahe dem Anfang hinzu:
#!/usr/bin/env bash
set -x
pwd
env | sort
Lassen Sie kein lautes Tracing in einem gemeinsamen Hook. Es wird schnell unlesbar.
Pfadprobleme sind bei GUI-Clients häufig. Ein Hook, der in Ihrem Terminal funktioniert, kann in einer IDE fehlschlagen, weil die IDE Ihr Shell-Profil nicht geladen hat. Bevorzugen Sie projektlokale Befehle, wo möglich:
./node_modules/.bin/eslint .
oder überprüfen Sie den Befehl und geben Sie eine nützliche Nachricht aus:
if ! command -v npm >/dev/null 2>&1; then
echo "npm wird für diesen Hook benötigt, wurde aber nicht im PATH gefunden."
exit 1
fi
Zeilenenden ändern sich ständig
Probleme mit Zeilenenden zeigen sich als Dateien, die nach dem Auschecken sofort als geändert erscheinen, große Diffs, bei denen jede Zeile geändert wurde, oder Skripte, die unter Linux nach der Bearbeitung unter Windows fehlschlagen.
Überprüfen Sie Ihre Einstellung:
git config --show-origin --get core.autocrlf
git config --show-origin --get core.eol
Häufige Optionen sind:
# Windows-freundlich: CRLF beim Auschecken, LF im Repository
git config --global core.autocrlf true
# macOS/Linux-freundlich: Nur CRLF in LF beim Commit konvertieren
git config --global core.autocrlf input
# Keine automatische Konvertierung
git config --global core.autocrlf false
Für ein Team ist .gitattributes zuverlässiger, als jedem Entwickler zu sagen, er solle globale Einstellungen korrekt setzen. Legen Sie Projektregeln im Repository fest:
* text=auto
*.sh text eol=lf
*.bat text eol=crlf
*.png binary
*.jpg binary
*.pdf binary
Nach dem Hinzufügen oder Ändern von .gitattributes normalisieren Sie Dateien bewusst:
git add --renormalize .
git status
Überprüfen Sie diesen Diff sorgfältig. Er kann viele Dateien betreffen, und Sie möchten die Zeilenendennormalisierung nicht mit Feature-Arbeit mischen.
Pull, Push oder Merge verwendet die falsche Standardeinstellung
Manchmal ist das Konfigurationsproblem nicht die Identität oder die Zeilenenden. Es ist Git, das eine Pull-Strategie wählt, die Sie nicht erwartet haben.
Überprüfen Sie Pull-bezogene Einstellungen:
git config --show-origin --get pull.rebase
git config --show-origin --get pull.ff
git config --show-origin --get branch.main.rebase
Wenn git pull ständig rebased, wenn Sie einen Merge erwartet haben, kann pull.rebase oder eine branch-spezifische Einstellung aktiviert sein. Wenn es Nicht-Fast-Forward-Pulls ablehnt, kann pull.ff=only gesetzt sein. Diese Einstellungen sind an sich nicht falsch; sie müssen nur zum Workflow des Teams passen.
Setzen Sie einen expliziten Standard, anstatt mit Warnungen und Überraschungen zu leben:
# Merge bei Pull
git config --global pull.rebase false
# Rebase bei Pull
git config --global pull.rebase true
# Nur Fast-Forward-Pulls erlauben
git config --global pull.ff only
Für einen Branch:
git config branch.main.rebase true
Verwirrung mit dem Credential Helper
Authentifizierungsprobleme sehen oft wie Remote-Probleme aus, kommen aber von der lokalen Konfiguration. Git kann einen Credential Helper verwenden, der ein altes Token zwischengespeichert hat.
Überprüfen Sie die Helper:
git config --show-origin --get-all credential.helper
Sie können osxkeychain, manager, manager-core, store oder cache sehen. Mehrere Helper können existieren. Wenn Git weiterhin die falschen Anmeldeinformationen sendet, entfernen Sie sie aus der OS-Schlüsselverwaltung oder dem Credential Manager, anstatt zufällige Remote-URLs zu ändern.
Überprüfen Sie auch das Remote:
git remote -v
SSH und HTTPS verwenden unterschiedliche Authentifizierungspfade. Wenn ein Repository [email protected]:org/repo.git und ein anderes https://github.com/org/repo.git verwendet, verwenden sie nicht unbedingt dieselben Anmeldeinformationen.
Eine zuverlässige Debugging-Routine
Wenn die Git-Konfiguration inkonsistent erscheint, verwenden Sie eine Routine anstatt zu raten:
- Führen Sie den fehlschlagenden Befehl vom Repository-Stamm aus.
- Überprüfen Sie die genaue Einstellung mit
git config --show-origin --get <name>. - Listen Sie verwandte Einstellungen mit
git config --list --show-origin --show-scopeauf. - Überprüfen Sie die lokale Konfiguration in
.git/config, bevor Sie die globale Konfiguration ändern. - Überprüfen Sie bedingte Includes, wenn das Problem nur in einem Verzeichnis auftritt.
- Nehmen Sie die kleinste Konfigurationsänderung vor und führen Sie den ursprünglichen Befehl erneut aus.
Git-Konfiguration ist mächtig, weil sie geschichtet werden kann. Das ist auch der Grund, warum sie verwirrend wird. Die Lösung ist, die Schichten sichtbar zu machen und dann die Schicht zu ändern, die tatsächlich gewinnt.
Wenn die Konfiguration innerhalb einer IDE anders ist
Eine verwirrende Klasse von Git-Problemen tritt nur innerhalb eines Editors oder einer GUI auf. Das Terminal verwendet eine Identität, aber die IDE committet mit einer anderen. Ein Hook funktioniert in Ihrer Shell, schlägt aber im Commit-Panel fehl. Eine Credential-Abfrage erscheint im Terminal, während die GUI stillschweigend mit einem alten Token wiederholt.
Der Grund ist normalerweise die Umgebung. Ihre interaktive Shell kann .bashrc, .zshrc, SDK-Manager, Sprachversionsmanager und benutzerdefinierte PATH-Einträge laden. Eine GUI, die vom Desktop gestartet wird, lädt möglicherweise nichts davon. Git selbst liest dieselben Konfigurationsdateien, aber Hooks und Credential Helper können eine andere Welt sehen.
Um es zu debuggen, erstellen Sie einen temporären Hook, der die Umgebung in eine lokale Datei ausgibt:
#!/usr/bin/env bash
{
date
pwd
git --version
git config --list --show-origin
env | sort
} > /tmp/git-hook-debug.log
exit 1
Führen Sie die Git-Aktion von der IDE aus, dann überprüfen Sie /tmp/git-hook-debug.log. Entfernen Sie den Hook danach. Dies sagt Ihnen, was Git und der Hook tatsächlich gesehen haben, anstatt was Ihr Terminal sieht.
Für Identitätsprobleme in GUI-Clients überprüfen Sie, ob das Tool eigene Git-Einstellungen hat. Einige Clients verwenden System-Git; andere bündeln Git oder speichern die Benutzeridentität in Anwendungseinstellungen. Wenn der Client über Git committet, zeigt git log --format=fuller -1 den resultierenden Autor und Committer. Dies hilft zu unterscheiden zwischen "Git-Konfiguration war falsch" und "die GUI hat ihre eigene Einstellung verwendet".
Wenn Sie unsicher sind, machen Sie Repository-lokale Einstellungen für wichtige Projekte explizit:
git config --local user.email "[email protected]"
git config --local core.hooksPath .githooks
Lokale Konfiguration reduziert Überraschungen, da sie mit den Repository-Metadaten auf diesem Rechner reist. Sie wird immer noch nicht committet, daher sollten gemeinsame Regeln in getrackten Dateien wie .gitattributes, .editorconfig, Hook-Skripten und Projektdokumentation leben.
Halten Sie eine bekannte gute Basislinie
Wenn Konfigurationsprobleme immer wieder auftreten, speichern Sie eine kleine bekannte gute Basislinie für Ihre eigenen Rechner. Sie muss nicht ausgefallen sein. Eine kommentierte ~/.gitconfig mit Ihrer Identität, Editor, Standard-Branch-Verhalten, Credential Helper und Includes ist ausreichend. Wenn sich dann ein neuer Laptop anders verhält, können Sie vergleichen, anstatt jede Einstellung neu zu entdecken.
Nützliche Basislinien-Checks umfassen:
git config --global --list --show-origin
git config --global --get core.editor
git config --global --get init.defaultBranch
git config --global --get-all credential.helper
Seien Sie vorsichtig beim Kopieren von Konfiguration aus dem Internet oder von einem Kollegen. Aliase können Tools voraussetzen, die Sie nicht haben. Credential Helper sind plattformspezifisch. Zeilenendeneinstellungen können für ihr Betriebssystem richtig und für Ihres falsch sein. Behandeln Sie Git-Konfiguration wie Shell-Konfiguration: Übernehmen Sie Ideen, aber verstehen Sie jede Zeile, bevor Sie sie behalten.
Für Projektbetreuer ist die beste Lösung, gemeinsame Erwartungen aus der persönlichen Konfiguration zu verschieben. Legen Sie Zeilenenden in .gitattributes, Formatierung in der Formatiererkonfiguration, ignorierte Dateien in .gitignore und erforderliche Prüfungen in CI fest. Je weniger ein Projekt von unsichtbaren globalen Einstellungen abhängt, desto weniger Konfigurationstickets erzeugt es.
Wenn Sie eine Einstellung ändern, um ein Problem zu beheben, notieren Sie, ob sie lokal oder global war. Viele zukünftige Git-Mysterien beginnen mit einer guten temporären lokalen Lösung, an die sich sechs Monate später niemand erinnert.