git fetch vs git pull: What Is the Difference?

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 branch | git fetch |
| Download and immediately integrate remote changes | git pull |
| Preview incoming commits before merging | git fetch + git log HEAD..origin/main --oneline |
| Update your branch but refuse merge commits | git pull --ff-only |
| Rebase local commits on top of remote changes | git 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.
git fetch originremote: 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-xThe 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:
git log main..origin/mainThis 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:
git pull --no-rebase origin mainThis is roughly equivalent to:
git fetch origin
git merge origin/mainAfter 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.
| Aspect | git fetch | git pull |
|---|---|---|
| Downloads new commits from remote | Yes | Yes |
Updates remote-tracking branches (origin/*) | Yes | Yes |
| Updates your current local branch | No | Yes |
| Modifies the working directory | No | Yes |
| Can create merge conflicts | No | Yes |
| Safe to run at any time | Yes | Only 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:
git log HEAD..origin/main --onelineThis 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:
git fetch origin mainFrom github.com:example/project
* branch main -> FETCH_HEAD
560d418..f1e5856 main -> origin/mainGit 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:
git log HEAD..FETCH_HEAD --onelineThis 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:
git fetch origin
git statusOn 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:
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:
git checkout main
git pull origin mainThis 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:
git config --global pull.rebase trueFrom 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:
git fetch origin
git log HEAD..origin/main --oneline
git merge origin/mainYou 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:
git log --oneline --decorate -n 5This 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.
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:
git reset --hard ORIG_HEADUseful Flags
A few flags make both commands more predictable in real workflows.
git fetch --all- Fetch from every configured remote, not onlyorigin.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:
git config --global pull.rebase falseUse 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.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

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