In the simplest terms, git pull does a git fetch followed by a git merge.
git fetch updates your remote-tracking branches under refs/remotes/<remote>/. This operation is safe to run at any time since it never changes any of your local branches under refs/heads.
git pull brings a local branch up-to-date with its remote version, while also updating your other remote-tracking branches.
From the Git documentation for git pull:
In its default mode,
git pullis shorthand forgit fetchfollowed bygit merge FETCH_HEAD.
git-pull - Fetch from and merge with another repository or a local branch SYNOPSIS git pull … DESCRIPTION Runs git-fetch with the given parameters, and calls git-merge to merge the retrieved head(s) into the current branch. With --rebase, calls git-rebase instead of git-merge. Note that you can use . (current directory) as the <repository> to pull from the local repository — this is useful when merging local branches into the current branch. Also note that options meant for git-pull itself and underlying git-merge must be given before the options meant for git-fetch.
You would pull if you want the histories merged, you'd fetch if you just 'want the codez' as some person has been tagging some articles around here.
In simple terms, if you were about to hop onto a plane without any Internet connection… before departing you could just do git fetch origin <branch>. It would fetch all the changes into your computer, but keep it separate from your local development/workspace.
On the plane, you could make changes to your local workspace and then merge it with what you've previously fetched and then resolve potential merge conflicts all without a connection to the Internet. And unless someone had made new changes to the remote repository then once you arrive at the destination you would do git push origin <branch> and go get your coffee.
From this awesome Atlassian tutorial:
The
git fetchcommand downloads commits, files, and refs from a remote repository into your local repository.Fetching is what you do when you want to see what everybody else has been working on. It’s similar to SVN update in that it lets you see how the central history has progressed, but it doesn’t force you to actually merge the changes into your repository. Git isolates fetched content as a from existing local content, it has absolutely no effect on your local development work. Fetched content has to be explicitly checked out using the
git checkoutcommand. This makes fetching a safe way to review commits before integrating them with your local repository.When downloading content from a remote repository,
git pullandgit fetchcommands are available to accomplish the task. You can considergit fetchthe 'safe' version of the two commands. It will download the remote content, but not update your local repository's working state, leaving your current work intact.git pullis the more aggressive alternative, it will download the remote content for the active local branch and immediately executegit mergeto create a merge commit for the new remote content. If you have pending changes in progress this will cause conflicts and kickoff the merge conflict resolution flow.
With git pull:
git merge.git fetch where it only affects your .git/refs/remotes, git pull will affect both your .git/refs/remotes and .git/refs/heads/Hmmm...so if I'm not updating the working copy with git fetch, then where am I making changes? Where does Git fetch store the new commits?
Great question. First and foremost, the heads or remotes don't store the new commits. They just have pointers to commits. So with git fetch you download the latest git objects (blob, tree, commits. To fully understand the objects watch this video on git internals), but only update your remotes pointer to point to the latest commit of that branch. It's still isolated from your working copy, because your branch's pointer in the heads directory hasn't updated. It will only update upon a merge/pull. But again where? Let's find out.
In your project directory (i.e., where you do your git commands) do:
ls. This will show the files & directories. Nothing cool, I know.
Now do ls -a. This will show dot files, i.e., files beginning with . You will then be able to see a directory named: .git.
Do cd .git. This will obviously change your directory.
Now comes the fun part; do ls. You will see a list of directories. We're looking for refs. Do cd refs.
It's interesting to see what's inside all directories, but let's focus on two of them. heads and remotes. Use cd to check inside them too.
Any git fetch that you do will update the pointer in the /.git/refs/remotes directory. It won't update anything in the /.git/refs/heads directory.
Any git pull will first do the git fetch and update items in the /.git/refs/remotes directory. It will then also merge with your local and then change the head inside the /.git/refs/heads directory.
A very good related answer can also be found in Where does 'git fetch' place itself?.
Also, look for "Slash notation" from the Git branch naming conventions post. It helps you better understand how Git places things in different directories.
Just do:
git fetch origin master
git checkout master
If the remote master was updated you'll get a message like this:
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
If you didn't fetch and just did git checkout master then your local git wouldn't know that there are 2 commits added. And it would just say:
Already on 'master'
Your branch is up to date with 'origin/master'.
But that's outdated and incorrect. It's because git will give you feedback solely based on what it knows. It's oblivious to new commits that it hasn't pulled down yet...
Some IDEs (e.g. Xcode) are super smart and use the result of a git fetch and can annotate the lines of code that have been changed in remote branch of your current working branch. If that line has been changed by both local changes and remote branch, then that line gets annotated with red. This isn't a merge conflict. It's a potential merge conflict. It's a headsup that you can use to resolve the future merge conflict before doing git pull from the remote branch.
If you fetched a remote branch e.g. did:
git fetch origin feature/123
Then this would go into your remotes directory. It's still not available to your local directory. However, it simplifies your checkout to that remote branch by DWIM (Do what I mean):
git checkout feature/123
you no longer need to do:
git checkout -b feature/123 origin/feature/123
For more on that read here
Git allows chronologically older commits to be applied after newer commits. Because of this, the act of transferring commits between repositories is split into two steps:
Copying new commits from remote branch to copy of this remote branch inside local repo.
(repo to repo operation) master@remote >> remote/origin/master@local
Integrating new commits to local branch
(inside-repo operation) remote/origin/master@local >> master@local
There are two ways of doing step 2. You can:
In git terminology, step 1 is git fetch, step 2 is git merge or git rebase
git pull is git fetch and git merge
All branches are stored in .git/refs
All local branches are stored in .git/refs/heads
All remote branches are stored in .git/refs/remotes
The
git fetchcommand downloads commits, files, and refs from a remote repository into your local repo. Fetching is what you do when you want to see what everybody else has been working on.
So when you do git fetch all the files, commits, and refs are downloaded in
this directory .git/refs/remotes
You can switch to these branches to see the changes.
Also, you can merge them if you want.
git pulljust downloads these changes and also merges them to the current branch.
Example
If you want see the work of remote branch dev/jd/feature/auth, you just need to do
git fetch origin dev/jd/feature/auth
to see the changes or work progress do,
git checkout dev/jd/feature/auth
But, If you also want to fetch and merge them in the current branch do,
git pull origin dev/jd/feature/auth
If you do git fetch origin branch_name, it will fetch the branch, now you can switch to this branch you want and see the changes. Your local master or other local branches won't be affected. But git pull origin branch_name will fetch the branch and will also merge to the current branch.
Simple explanation:
git fetch
fetches the metadata. If you want to check out a recently created branch you may want to do a fetch before checkout.
git pull
Fetches the metadata from remote and also moved the files from remote and merge on to the branch
This graphic could be of help. git pull is essentially equivalent to git fetch then git merge
git fetch will tell the local git to retrieve the latest meta-data info from the original (No file transferring).
git pull = git fetch AND brings (copy) all changes from the remote repository. (Includes file transferring)
git pull also tries to merge with local changes.