GitFetching Changes (git fetch)

Fetching Changes (git fetch)

git fetch downloads new commits, branches, and tags from a remote — but does not touch your local branches. Everything new is stored under origin/<branch> references. You then choose what to do with it: merge, rebase, inspect, or ignore. Fetch is the safe, read-only “show me what’s new” operation.

The basic invocation

Bash
git fetch              # fetch from the default remote (origin)
git fetch origin       # fetch from origin explicitly
git fetch --all        # fetch from every remote configured
What fetch does
  • Connects to the remote.

  • Downloads all new commits, branches, and tags.

  • Updates remote-tracking pointers (e.g., origin/main).

  • Leaves your local branches completely untouched.

What fetch does NOT do
  • Does not modify your working directory.

  • Does not modify your local branches.

  • Does not produce conflicts (it never merges).

  • Cannot lose work — it is read-only locally.

After fetching: inspect the changes

What did the remote learn?

Bash
git fetch

# What commits did origin/main get since I last fetched?
git log HEAD..origin/main --oneline

# Just show me how many
git rev-list --count HEAD..origin/main

# Visual graph
git log --graph --oneline --all -20
Integrating fetched changes

After inspecting, decide how to integrate

Bash
# Option A: fast-forward / merge into the current branch
git merge origin/main

# Option B: rebase your local commits on top
git rebase origin/main

# Option C: just look — do nothing else

git pull does the fetch + integrate in one step. Many developers prefer the two-step approach (fetch, then explicitly merge or rebase) because it gives them a chance to inspect first.

Useful flags
  • --all — fetch from every configured remote.

  • --prune (or -p) — also remove local pointers for branches deleted on the remote.

  • --tags — also fetch tags. Tags are not fetched by default in some configurations.

  • --depth=N — fetch only the last N commits of each branch (shallow fetch).

  • --unshallow — turn a shallow clone into a full clone.

  • --dry-run — show what would be fetched without doing it.

  • --no-tags — skip tags.

  • <remote> <branch> — fetch only one branch.

Fetching one specific branch

Bash
git fetch origin feature-x
# Downloads only feature-x's new commits.
# After this, you can:
git switch feature-x   # auto-creates local branch tracking origin/feature-x
Pruning stale branches

Remove local pointers to branches deleted on the remote

Bash
git fetch --prune
#  - [deleted] (none) -> origin/old-branch

# Make it the default
git config --global fetch.prune true
Inspecting all remote branches at once

Bash
git fetch --all
git branch -r
# origin/HEAD -> origin/main
# origin/main
# origin/develop
# origin/feature-x

# See log of every remote branch
git log --all --oneline --graph -20
Fetch vs pull — when to choose which
  • fetch — “show me what’s on the remote.” You decide what to do next. Recommended default.

  • pull — “show me what’s on the remote AND merge it into my current branch.” Saves a step but commits you to an immediate merge.

The cautious dance

Bash
git fetch
git status              # check whether your branch is behind, ahead, or in sync
git log HEAD..origin/$(git branch --show-current) --oneline   # what's new?
# Decide: merge, rebase, or ignore
Common errors
  • “fatal: could not read from remote repository” — wrong URL, network issue, or auth problem.

  • “refusing to fetch into current branch” — almost never happens with default config; check git config receive.denyCurrentBranch.

  • Tags or branches piling up — use --prune regularly.

Fetch is non-destructive
You can always run `git fetch`. The worst case is downloading nothing new. Make it part of your morning routine.
Tip
Run git fetch before git status if you want the “ahead / behind” counts to reflect today’s remote — Git only knows what it has seen on the last fetch.