Review before merging
Fetch and compare main with origin/main (or run git log HEAD..origin/main) so you can see incoming commits before you merge or rebase them.
Git · Command
git fetch downloads commits, trees, blobs and refs (branches and tags) from one or more other repositories and updates your remote-tracking branches. It does not merge anything into your own branches or change your working tree.
Last updated
Fetch first contacts the remote and works out which commits you already have. It then downloads only the objects you are missing. Next, it uses a refspec (+src:dst) to decide which remote refs to fetch and where to store them locally. If you give no refspec on the command line, Git uses the remote.<name>.fetch config values, which normally map refs/heads/* to refs/remotes/<name>/*. Updates that are not fast-forwards are refused unless the refspec starts with + or you pass --force. Fetch also writes the refs it got to FETCH_HEAD, which git pull and scripts can read.
git fetch [<options>] [<repository> [<refspec>…]]
git fetch [<options>] <group>
git fetch --multiple [<options>] [(<repository>|<group>)…]
git fetch --all [<options>]| Name | Type | Description |
|---|---|---|
<repository> | URL or remote name | The repository to fetch from. This can be a URL or the name of a configured remote. |
<group> | string | A name defined by remotes.<group> in your config that stands for a list of repositories. |
<refspec> | [+]<src>:<dst> | Says which remote refs to fetch and which local refs to update. A leading + allows non-fast-forward updates, a ^ prefix makes it a negative (exclusion) refspec, and * acts as a pattern. |
--prune / -p | flag | Before fetching, deletes remote-tracking refs whose branches no longer exist on the remote. |
--tags / --no-tags | flag | --tags fetches every tag. --no-tags turns off automatic tag following. |
--depth=<depth> / --unshallow | int / flag | --depth limits or changes how much history a shallow repository has. --unshallow turns a shallow repository into a complete one. |
--all / --multiple | flag | --all fetches from every remote. --multiple lets you name several repositories or groups. |
--dry-run | flag | Shows what would happen without changing anything. |
For each ref, fetch prints a status line of the form '<flag> <summary> <from> -> <to> [<reason>]' to stderr. The flags are: space = fast-forward, + = forced update, - = pruned, t = tag update, * = new ref, ! = rejected, = = up to date. With --porcelain it prints a machine-readable format to stdout instead.
#!/usr/bin/env bash
set -euo pipefail
# Update all remote-tracking branches for origin, dropping deleted ones
git fetch --prune origin
# See what arrived on main that you don't have yet
git log --oneline main..origin/main
# Fetch one branch into a local branch of your choice
git fetch origin feature/login:review-login
# Peek at a branch from an unconfigured repo via FETCH_HEAD
git fetch https://git.kernel.org/pub/scm/git/git.git maint
git log -3 --oneline FETCH_HEAD
# Integrate only when ready
git merge --ff-only origin/mainThe script updates and prunes origin's remote-tracking branches, shows the new upstream commits, fetches one branch under a local name, peeks at another repository through FETCH_HEAD, and fast-forwards main only at the end.
Fetch and compare main with origin/main (or run git log HEAD..origin/main) so you can see incoming commits before you merge or rebase them.
Run git fetch --prune, or set fetch.prune=true, so remote-tracking branches deleted on the server stop showing up in git branch -a.
A CI job cloned with --depth=1 and now needs more history for git describe or a merge-base. Run git fetch --deepen=N or git fetch --unshallow.
Use git fetch --all -j 4 to update origin, upstream and the remotes of forks in parallel.
git fetch only downloads objects and updates refs: remote-tracking branches and FETCH_HEAD. Your local branches and working tree stay as they were. git pull runs a fetch and then merges or rebases the fetched branch into your current branch, using the information fetch wrote. That makes fetch the safe choice when you only want to look at upstream changes.
Follow-up: Why won't fetch update the branch you have checked out, even with a matching refspec? By default fetch refuses to update the ref for your current branch, because that would leave your working tree out of step with it. The --update-head-ok flag turns this check off, but it is meant only for git pull's internal use.
The left side picks the source refs on the remote, here every branch. The right side is where each one is stored locally, with * replaced by the matched name. The leading + allows non-fast-forward updates, so the remote-tracking branches still update after someone force-pushes or rebases. This is the default remote.origin.fetch value that git clone sets up.
Follow-up: How do you leave out some branches that a pattern matches? Add a negative refspec with a ^ prefix, for example ^refs/heads/tmp/*. A ref is fetched only if it matches at least one positive refspec and no negative one.
They are refs/remotes/<name>/* entries whose branches have been deleted on the server. Git keeps them because it holds on to data until you explicitly remove it. Over time they clutter commands like git branch -a and can slow down busy repositories. You can remove them with git fetch --prune <name>, or with git remote prune <name> if you don't want to fetch, or set fetch.prune / remote.<name>.prune to prune on every fetch.
Follow-up: Does --prune delete local tags? Usually not. Tags fetched through auto-following or --tags are never pruned. They are pruned only when an explicit tag refspec is in effect, which is what --prune-tags adds.
git pullgit pushgit remotegit clonegit configgit submodulegit maintenancegit gc