git fetch
Download commits, branches, and tags from a remote repository without automatically merging them into your work.
Your teammate just pushed new commits to the remote repository, and you want to
see what changed without immediately merging those changes into your current
work. git fetch downloads new commits, branches, and tags from the remote
repository, updating your local copy of the remote's state without touching your
working directory or current branch. It's the safe way to check what's new
before deciding how to integrate it.
When you run git fetch, Git contacts the remote repository (usually called
origin) and downloads any commits you don't have yet. These commits go into
remote-tracking branches like origin/main or origin/feature-branch, which
represent the remote's branches on your local machine. Your actual local
branches—main, feature-branch, etc.—remain unchanged. This separation lets you
review what's new before deciding whether to merge or rebase.
After fetching, you can examine the new commits with git log origin/main to
see what your teammates pushed, or git diff main..origin/main to see how your
local main differs from the remote version. If you like what you see, you can
merge with git merge origin/main or rebase with git rebase origin/main. If
you don't, you can wait and fetch again later when you're ready. This two-step
process (fetch then merge) gives you more control than git pull, which fetches
and merges in one command.
Fetching Specific Branches and Remotes
By default, git fetch downloads from the remote your current branch tracks,
but you can specify a remote explicitly: git fetch origin. If you have
multiple remotes (like origin and upstream for forked repositories), you can
fetch from a specific one. To fetch from all configured remotes at once, use
git fetch --all.
You can also fetch a specific branch with git fetch origin branch-name, which
only downloads that branch's commits instead of everything. This saves time and
bandwidth in large repositories with many active branches when you only care
about one specific branch.
Pruning Stale References
Over time, branches get deleted from the remote after PRs merge, but your local
repository keeps references to those deleted remote branches. Running
git fetch --prune removes these stale references, cleaning up your view of
what exists on the remote. Many developers configure Git to always prune when
fetching with git config fetch.prune true, so deleted remote branches
automatically disappear from their local remote-tracking branches.
Pull Request Workflows
In pull request workflows, fetch is essential for reviewing other people's code
locally. When someone opens a PR, you fetch to download their branch, then check
it out to test it on your machine. The workflow looks like git fetch origin,
then git checkout feature-branch, which creates a local branch tracking the
remote one. Now you can run the code, test it, and verify it works as claimed.
Fetch also helps you stay aware of changes without disrupting your current work. You can fetch periodically throughout the day to download new commits, then review what's new when convenient. This is safer than pulling, which would immediately merge changes into your current branch possibly at an inconvenient time.
When working on a long-running feature branch, fetching main regularly helps you
stay aware of how far your branch has diverged. After fetching,
git log HEAD..origin/main shows commits that were added to main while you've
been working. You can decide when to merge or rebase those changes into your
feature branch, rather than discovering a huge divergence when you try to open
your PR.
Tags and Releases
Fetch also downloads tags from the remote. When maintainers create release tags
like v1.0.0, those tags don't appear in your local repository until you fetch.
Running git fetch --tags specifically fetches all tags without fetching
commits, which is useful if you just want to see what versions have been
released.
Understanding fetch means understanding the distinction between remote repositories and remote-tracking branches. The remote repository lives on GitHub or another server. Remote-tracking branches are your local mirror of the remote's branch pointers, updated only when you fetch. Your local branches are your actual working branches, independent of the remote until you explicitly merge or push. Fetch updates the middle layer—the remote-tracking branches—giving you visibility into the remote without affecting your work.
