git fetch vs git pull: What Is the Difference?

By 

•

Updated on

•

9 min read

Comparing git fetch and git pull commands in Git

Sooner or later, every Git user runs into the same question: should you use git fetch or git pull to get the latest changes from the remote? The two commands look similar, and both talk to the remote repository, but they do very different things to your working branch.

This guide explains the difference between git fetch and git pull, how each command works, and when to use one over the other.

Quick Reference

For a printable quick reference, see the Git cheatsheet .

If you want to…Use
Download remote changes without touching your branchgit fetch
Download and immediately integrate remote changesgit pull
Preview incoming commits before merginggit fetch + git log HEAD..origin/main --oneline
Update your branch but refuse merge commitsgit pull --ff-only
Rebase local commits on top of remote changesgit pull --rebase

What git fetch Does

git fetch downloads commits, branches, and tags from a remote repository and stores them locally under remote-tracking references such as origin/main or origin/feature-x. It does not touch your working directory, your current branch, or the index.

Terminal
git fetch origin
output
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 11 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
From github.com:example/project
   9dfa932..560d418  main       -> origin/main
   261da74..b52ebc7  feature-x  -> origin/feature-x

The output shows which remote branches were updated. After the fetch, the local branch main is still pointing to whatever commit it was on before. Only the remote-tracking branch origin/main has moved.

You can then inspect what changed before doing anything with it:

Terminal
git log main..origin/main

This is the safe way to look at new work without merging or rebasing yet. It gives you a preview of what the remote has that your branch does not.

What git pull Does

git pull is a convenience command. Under the hood, it runs git fetch and then integrates the fetched changes according to your options and configuration. To use a merge explicitly, run:

Terminal
git pull --no-rebase origin main

This is roughly equivalent to:

Terminal
git fetch origin
git merge origin/main

After git pull, your current branch has moved forward, and your working directory may contain new files, updated files, or merge conflicts that need resolving. The change is immediate and affects your checked-out branch.

Side-by-Side Comparison

The difference between the two commands comes down to what they change in your repository.

Aspectgit fetchgit pull
Downloads new commits from remoteYesYes
Updates remote-tracking branches (origin/*)YesYes
Updates your current local branchNoYes
Modifies the working directoryNoYes
Can create merge conflictsNoYes
Safe to run at any timeYesOnly when ready to integrate

git fetch is read-only from your branch’s perspective. git pull actively changes your branch.

When to Use git fetch

Use git fetch when you want to see what changed on the remote without integrating anything yet. This is useful before you start new work, before rebasing a feature branch, or when you want to inspect a teammate’s branch safely.

For example, after fetching, you can compare your branch with the remote like this:

Terminal
git log HEAD..origin/main --oneline

This shows commits that exist on the remote but not in your current branch. Running git fetch often is cheap and has no side effects on your work, which is why many developers do it regularly throughout the day.

To list the remote-tracking branches that the fetch downloaded, run git branch -r. The git branch command guide covers the other listing options.

Fetching a Single Branch

With the usual fetch configuration, git fetch origin fetches all remote branches. A single-branch clone fetches only its configured branch. When you only care about one branch, pass its name after the remote:

Terminal
git fetch origin main
output
From github.com:example/project
 * branch            main       -> FETCH_HEAD
   560d418..f1e5856  main       -> origin/main

Git downloads the main branch and records its tip in FETCH_HEAD. With the usual fetch configuration, it also updates origin/main. In a single-branch clone configured to track a different branch, origin/main is not updated, but you can still review the fetched commits with:

Terminal
git log HEAD..FETCH_HEAD --oneline

This shows commits from the fetched main branch that are not in your current branch. The other remote-tracking branches are not updated, and your local main branch stays where it was.

Checking If Your Branch Is Behind

The git status command tells you how your branch compares to its upstream, but it does not contact the remote. It compares your branch with the local copy of origin/main, which is only as fresh as your last fetch. That is why git status can say your branch is up to date even when a teammate pushed new commits an hour ago.

Fetch first, then check the status:

Terminal
git fetch origin
git status
output
On branch main
Your branch is behind 'origin/main' by 3 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Your branch has no commits of its own, so Git can move it forward without a merge. A plain git pull or git pull --ff-only will work.

If you have local commits and the remote has new commits too, the status looks different:

output
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" if you want to integrate the remote branch with yours)

A diverged branch cannot be fast-forwarded. You need to merge or rebase, and Git will ask you to choose if no default is configured (see the Troubleshooting section below).

When to Use git pull

Use git pull when you are ready to bring remote changes into your current branch and keep working on top of them. The common flow looks like this:

Terminal
git checkout main
git pull origin main

This is the quickest way to sync a branch with its upstream when you know the integration will be straightforward, such as on a shared main branch where you rarely have local commits. git pull always updates the branch you currently have checked out, so it is worth confirming where you are before you run it.

If you want a cleaner history without merge commits, configure pull to rebase:

Terminal
git config --global pull.rebase true

From that point on, git pull runs git fetch followed by git rebase instead of git merge. Your local commits are replayed on top of the fetched changes, producing a linear history.

Avoiding Merge Surprises

The biggest reason to prefer git fetch over git pull in day-to-day work is control. Depending on your configuration, a git pull on a branch where you have local commits can create a merge commit, introduce conflicts, or rewrite history during a rebase, all in one step. If no pull strategy is configured, recent Git versions refuse to pull a diverged branch and ask you to choose one first.

A safer pattern is:

Terminal
git fetch origin
git log HEAD..origin/main --oneline
git merge origin/main

You fetch first, review what is coming, then decide whether to merge, rebase, or defer the integration. For active feature branches, this workflow avoids most of the “what just happened to my branch” moments.

If you already ran git pull and need to inspect what happened, start with:

Terminal
git log --oneline --decorate -n 5

This helps you confirm whether Git created a merge commit, fast-forwarded the branch, or rebased your local work.

If the pull created a merge commit that you do not want, ORIG_HEAD often points to the commit your branch was on before the pull.

Warning
git reset --hard discards uncommitted changes. Use it only when you are sure you do not need the current state of your working tree.

In that case, you can reset back to it:

Terminal
git reset --hard ORIG_HEAD

Useful Flags

A few flags make both commands more predictable in real workflows.

  • git fetch --all - Fetch from every configured remote, not only origin.
  • git fetch --prune - Remove remote-tracking branches that no longer exist on the remote.
  • git fetch --tags - Fetch all tags from the remote, not only the tags that point to fetched commits.
  • git pull --rebase - Rebase your local commits on top of the fetched changes instead of merging.
  • git pull --ff-only - Update the branch only if Git can fast-forward it; prevents unexpected merge commits.

--ff-only is especially useful on shared branches. If your branch cannot move forward by simply advancing the pointer, the pull stops with fatal: Not possible to fast-forward, aborting., and you decide what to do next.

Troubleshooting

fatal: Need to specify how to reconcile divergent branches
Your local branch and the remote branch both have commits the other does not have, and Git does not know whether to merge or rebase. Pass the strategy for a single pull with git pull --no-rebase (merge) or git pull --rebase, or set a default once:

Terminal
git config --global pull.rebase false

Use pull.rebase true to rebase by default, or pull.ff only to allow fast-forward pulls only.

fatal: Not possible to fast-forward, aborting
You ran git pull --ff-only (or set pull.ff only), and the branches have diverged. Review the incoming commits with git log HEAD..origin/main --oneline, then merge or rebase manually.

error: Your local changes to the following files would be overwritten by merge
The incoming commits touch files you modified but did not commit. Commit your changes, or set them aside with git stash , then pull again and run git stash pop to restore them.

FAQ

Does git fetch modify any local files?
Yes, inside the Git repository: it downloads objects and updates remote-tracking references, fetched tags, and .git/FETCH_HEAD. Your working-directory files and staging area stay unchanged.

Is git pull the same as git fetch plus git merge?
Mostly. When your branch can be fast-forwarded, git pull behaves like git fetch followed by git merge. When the branches have diverged, Git stops and asks you to choose between merge and rebase, unless pull.rebase or pull.ff is configured. With pull.rebase set to true (or --rebase on the command line), it runs git fetch followed by git rebase.

Which one should I use daily?
Prefer git fetch for visibility and git pull --ff-only (or git pull --rebase) for the integration step. A bare git pull works, but it hides two operations behind one command.

How do I see what git fetch downloaded?
Use git log main..origin/main to see commits on the remote that are not yet in your local branch, or git diff main origin/main to compare the content directly.

Can git fetch cause conflicts?
No. Conflicts only happen when you merge or rebase the fetched commits into your branch. Fetching itself is conflict-free.

Conclusion

git fetch lets you inspect remote changes without touching your branch, while git pull fetches and integrates those changes in one step. Fetch first, review the incoming commits with the git log command or git diff command , then merge or rebase on your own terms.

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page