What's the difference between git fetch vs git pull?

Umer Mansoor Umer Mansoor Follow Apr 18, 2016 · 5 mins read

Git has two types of repositories: local and remote. The local repository is on your computer and has all the files, commit history etc. Remote repositories are usually hosted on a central server or on the Internet.

Downloading data from the remote repo to local is an essential part of working with git.

Both git pull and git fetch are used to download data from remote repository. These two commands have important differences and similarities. Let’s explore them in more detail.

The main difference between git fetch and git pull

$ git fetch origin

git fetch only downloads the latest data from the remote repository. It does not merge any of this new data into the current branch or changes the working files. Fetch is completely safe and is an excellent way of downloading new changes from the remote repository without creating any conflicts or messing up local files or work in progress. Fetch can be done as often as you want.

$ git pull origin master

git pull in contrast not only downloads the latest data, but it also automatically merges it into your current branch and updates the working files automatically. It doesn’t give you a chance to review the changes before merging, and as a consequence, ‘merge conflicts’ can and do occur. One important thing to keep in mind is that it will merge only into the current working branch. Other branches will stay unaffected.

Here’s a diagram to illustrate the difference between git fetch and git pull.

git pull and fetch

I have covered the main difference between git fetch and get pull above. But if you want more details, read on.

git fetch explained in detail

As we’ve seen, git fetch only downloads latest changes into the local repository, and does not merge into the current branch. It downloads fresh changes that other developers have pushed to the remote repo since the last fetch and allows you to review and merge manually at a later time using git merge. Because it doesn’t change your working directory or the staging area, it is entirely safe, and you can run it as often as you want.

You may be thinking where are the changes are stored after a fetch since they are not merged into the working file? The answer is that they are stored in your local repository in what is called remote tracking branches. A remote tracking branch is a local copy (or mirror) of a remote branch, e.g. origin/master. You’ll need to run git branch -a to see all local and remote branches. After doing a fetch, if you want to check out what has changed, you can do:

  • git log origin/master ^master: to get a list of all commits that are in remote master but not in your local branch.
  • git diff ..origin: to see the diff.
  • git checkout origin/master: to checkout the remote master branch and see what files have changed.

Once you have reviewed the changes and are ready to merge, you can switch back to the master branch and run git merge. It will merge changes from the remote branch into local.

Here’s an example. Let’s switch to develop branch and do git fetch. To keep it simple, I’ll omit the output.

$ git checkout develop
$ git fetch

Now let’s see the list of commits that are in remote develop but not in local.

$ git log origin/develop ^develop

commit 6123ef537f0dac5410f409a8dfc2719491e13fc9 (origin/master, origin/HEAD)
Author: Umer Mansoor <[email protected]>
Date:   Sat Feb 1 08:11:52 2020 -0800

    fixed toc

commit 7143fccddce97405b05f51facf9e1560301027ab
Author: Umer Mansoor <[email protected]>
Date:   Sat Feb 1 08:10:01 2020 -0800

    Update README.md

When you are ready to merge, simply run:

$ git merge

Updating 89aaded..5926bf5
Fast-forward
 README.md | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

git pull example

The git pull command downloads from the remote repository to the local repository and automatically merges those changes into the current branch.

$ git checkout master
...

$ git pull

remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/repo/arepo
   7548eeb..8599bfe  master     -> origin/master
Updating 7548eeb..8599bfe
Fast-forward
 README.md | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 README.md

You can see that in the output above, the changes were downloaded from the remote master and then merged using fast-forward method into the local master branch.

Summary

In summary, pull and fetch are similar in the sense that they both download latest changes from the remote repo to local. The difference is that pull automatically merges changes into the current branch while fetch doesn’t. If you are interested, here are some more commands and details that I didn’t cover in the post to keep it simple.

  • Under the hood, git pull is equivalent to running git fetch origin HEAD followed by git merge HEAD.
  • To run git pull in verbose mode, add the verbose switch i.e. git pull --verbose
  • To put all your changes on top of what everyone else has committed, you can pull using the rebase flag i.e. git pull --rebase origin.

If you’re interest, check out my next tutorial on git stash. Stashing is a useful tool in git that allows users to save their partially complete changes and reapply them at a later time.

#git

You May Also Enjoy


If you like this post, please share using the buttons above. It will help CodeAhoy grow and add new content. Thank you!


Comments (5)


Ankur

Good explanation. I always fetch first and review pulled changes before merging.

git fetch
git diff …origin

Keep up the good work.


kirankotari

Always had the confusion on git pull and git fetch it’s clear now. Thanks


Alan Hill

To get rid of local changes and avoid a merge conflict mess, you could do git fetch followed by git reset --hard origin/master. Stash any changes that you might need and that way you won’t lose work.


RedHat J

I don’t use pull at all. My workflow is always fetch, review and then merge.

git fetch origin new_branch
git checkout new_branch
git cherckout -b local_branch

fetch is the default option in many UI clients because it is safe no matter how many times you execute it


Speak Your Mind