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.