--- topic: fetch source_keys: - git-scm-fetch-docs - context7-git-htmldocs --- # Fetching Fetch **with no refspec** updates remote-tracking branches (`refs/remotes//*`) and leaves every local branch alone. That safety comes from the default refspec, not from `fetch` itself. Give it an explicit one and it writes to local branches: verified on Git 2.39.5, `git fetch origin main:probe` fast-forwarded the local `probe` branch, and a `+` prefix force-updates the destination, discarding whatever commits it held. Treat any `fetch` carrying a `:` refspec as a branch update, not a read. - **One remote**: `git fetch ` — all branches - **One branch**: `git fetch ` — the result lands in `FETCH_HEAD`, not a tracking ref - **All remotes**: `git fetch --all` - **Prune properly**: `git fetch --all --prune --prune-tags` cleans stale branches *and* tags - **Auto-prune**: `git config --global fetch.prune true` (or `remote..prune` to scope it to one remote), and `fetch.pruneTags true` for tags ## Shallow and partial fetch ```bash git fetch --depth= # deepen history, or create a shallow clone git fetch --unshallow # convert a shallow clone to full history git fetch --update-shallow # allow the fetch to update the shallow boundary git fetch --refmap='' # fetch without updating any tracking ref (FETCH_HEAD only) ``` ## Default fetch refspec The default is `+refs/heads/*:refs/remotes//*`. The leading `+` forces the update — remote-tracking branches always mirror the remote exactly and offer no protection for local history.