Einführung
git fetch ist die Netzwerkoperation, die neue Objekte herunterlädt und Remote-Tracking-Refs aktualisiert. Sie ändert Ihre Branches oder den Working Tree nicht, was sie zum sichersten "Was gibt es Neues?"-Befehl macht.
Die Sequenz
- Remote-URL auflösen.
- Verbindung öffnen (HTTPS, SSH oder git://).
- Capabilities verhandeln (Protokollversion, Multi-Ack, Partial-Clone-Filter usw.).
- Server kündigt Refs an (oder, in Protokoll v2, nur die mit den angeforderten Mustern übereinstimmenden).
- Client meldet, was er bereits hat.
- Server sendet ein Pack-File mit den fehlenden Objekten.
- Client schreibt das Pack nach
.git/objects/pack/und indexiert es. - Client aktualisiert Remote-Tracking-Refs (
refs/remotes/origin/*). - Optional Pruning gelöschter Refs.
Befehle
git fetch
git fetch origin
git fetch --all
git fetch --prune
git fetch origin main:my-main # in eine lokale Ref fetchen
Die Doppelpunkt-Syntax main:my-main erstellt oder aktualisiert eine lokale Ref direkt; vorsichtig verwenden.
Inspizieren, was gefetcht wurde
git fetch origin
cat .git/FETCH_HEAD
git log HEAD..origin/main --oneline
FETCH_HEAD listet jede vom letzten Fetch aktualisierte Ref auf, in der angeforderten Reihenfolge.
Refspecs
Jeder Remote hat eine oder mehrere Fetch-Refspecs. Der Standard für origin:
+refs/heads/*:refs/remotes/origin/*
Sie können weitere hinzufügen, etwa um Pull-Request-Refs von GitHub zu fetchen:
git config --add remote.origin.fetch '+refs/pull/*/head:refs/remotes/origin/pr/*'
git fetch
git switch -c review/123 origin/pr/123
Pruning
Ohne Prune verbleiben auf dem Server gelöschte Branches als veraltete origin/*-Refs:
git fetch --prune
git config --global fetch.prune true
Tags
Standardmäßig lädt fetch Tags herunter, die auf gefetchte Commits zeigen. Erzwingen oder deaktivieren:
git fetch --tags
git fetch --no-tags
Trace und Debug
GIT_TRACE=1 GIT_TRACE_PACKET=1 git fetch
GIT_CURL_VERBOSE=1 git fetch # HTTPS
Diese offenbaren exakte Anfragen, nützlich beim Debuggen von Proxies oder Authentifizierung.
Verhandlung und haves
Der Fetch-Handshake ist ein Tanz aus "wants" und "haves". Der Client listet auf, was er will (die Spitzen-SHAs der Remote-Branches), und bietet haves an (jüngste lokale Commits), damit der Server ein minimales Pack berechnen kann. Modernes Git verwendet den skipping-Verhandlungsalgorithmus, der selbst auf langen Historien in O(log n)-Runden konvergiert. Sie können ihn einstellen:
git config fetch.negotiationAlgorithm skipping
git config fetch.negotiationAlgorithm consecutive
GIT_TRACE_PACKET=1 git fetch 2>&1 | grep -E 'have|want' | head
Häufige Fehler
Glauben, git fetch ändere Ihre Branches; tut es nie. Verwenden Sie git pull oder git merge origin/main zur Integration. --prune in langlebigen Klonen überspringen und Dutzende veralteter origin/*-Refs ansammeln. Eine Refspec von Hand falsch konfigurieren und lokale Branches überschreiben; doppelt prüfen mit git config -e. Schließlich: Aus einem Partial Clone fetchen ohne zu merken, dass beim Zugriff auf einige Objekte ein Folge-Netzwerkaufruf nötig wird; Partial Clones tauschen Up-Front-Geschwindigkeit gegen gelegentliche Latenz später.