The difference between git pull, git fetch and git clone (and git rebase)

Update: So, over a year later and I’ve had some feedback from a colleague (thanks Ben!). Nothing here is drastically wrong, but some clarifications should help!

When I started out with git …

… who am I kidding, I’m still a git n00b. Today, I tweeted about git. I wanted to know what the differene between pull, fetch and clone is. After discovering that, really, 140 characters isn’t enough to answer the questions, I had a play around.

Git Pull

From what I understand, git pull will pull down from a remote whatever you ask (so, whatever trunk you’re asking for) and instantly merge it into the branch you’re in when you make the request. Pull is a high-level request that runs ‘fetch’ then a ‘merge’ by default, or a rebase with ‘–rebase’. You could do without it, it’s just a convenience.

%> git checkout localBranch
%> git pull origin master
%> git branch
* localBranch

The above will merge the remote “master” branch into the local “localBranch”.

Git fetch

Fetch is similar to pull, except it won’t do any merging.

 %> git checkout localBranch
 %> git fetch origin remoteBranch
%> git branch
* localBranch

So, the fetch will have pulled down the remoteBranch and put it into a local branch called “remoteBranch”. creates a local copy of a remote branch which you shouldn’t manipulate directly; instead create a proper local branch and work on that. ‘git checkout’ has a confusing feature though. If you ‘checkout’ a local copy of a remote branch, it creates a local copy and sets up a merge to it by default.

Git clone

Git clone will clone a repo int a newly created directory. It’s useful for when you’re setting up your local doodah

%> cd newfolder
%> git clone
%> git branch
 * master

Git clone additionally creates a remote called ‘origin’ for the repo cloned from, sets up a local branch based on the remote’s active branch (generally master), and creates remote-tracking branches for all the branches in the repo

Git rebase

Finally, git rebase is pretty cool. Anything you’ve changed by committing to your current branch but are no in the upstream are saved to a temporary area, so your branch is the same as it was before you started your changes, IE, clean. It then grabs the latest version of the branch from the remote If you do ‘git pull –rebase’, git will pull down the remote changes, rewind your local branch, then replays all your changes over the top of your current branch one by one, until you’re all up to date. Awesome huh?


If you get stuck, run ‘git branch -a’ and it will show you exactly what’s going on with your branches. You can see which are remotes and which are local. This is a good headsup before you start to break things! It’s worth remembering that git branches are basically just a pointer, so to be able to work with those commits you need a local branch which points to somewhere from which those commits are reachable.

Thanks to Ben for the extra stuff, clarifications and calling me an idiot when I get git wrong, because I am, as it’s really pretty simple, except for the simple.

34 thoughts on “The difference between git pull, git fetch and git clone (and git rebase)

  1. So in fetch what kind of data are we pulling exactly? Is it code? If so, where does it go? The manual seems to hint that we are grabbing some kind of structural information but I don’t really know what.

    1. So, from the git book:

      The command goes out to that remote project and pulls down all the data from that remote project that you don’t have yet.

      and a but further down it says:

      So, git fetch origin fetches any new work that has been pushed to that server since you cloned (or last fetched from) it.

      So, to me, it sounds like it pulls everything down. But it won’t merge, you’ll need to do that manually. When you do a git status you’ll probably see unstaged modifications.

      1. Everything said by Mike was correct except for: “When you do a git status you’ll probably see unstaged modifications.”. You will only see unstaged modifications if you had unstaged modifications before you fetched. Git fetch will not change any unstaged modifications at all. This is what git fetch really does. Lets say you are on your master branch and you’re pulling from the origin remote’s master branch (which is probably what will happen by default if you do a “git fetch”). Your master branch will be unchanged and your staged files will also be unchanged. Your origin/master branch will be updated. The origin/master branch represents that state of the files on the origin’s master branch if you do a git pull it also updates the origin/master branch and then merges origin/master to your master. So with the scenario listed above a git pull is equivelent to a git fetch && git merge origin/master.

  2. Nice day,

    Can I ask something… maybe its not too related to your post but I just want to ask… I am also new to GIT… I am trying to pull, fetch, rebase and clone as well as push… I dont know why, I cant do it because of an error stating “The remote end hung up unexpectedly” :This is the code I wrote: git push file://// repo.git …. Can you help me with it?…. TYSM

  3. Will git pull just pull on the current working branch and not all your remotely tracking branches? For example, I have a dev/homepage and a dev/footer. If I’m in dev/homepage and I git pull will it only pull on that branch or my dev/footer as well?

  4. I’m still having problems wrapping my head around all this. What is the purpose of “checkout” as compared to “clone”, “fetch”, and “pull”? In what cases does one use this?

    1. `checkout` allows you to turn your working directory into a particular revision or branch of a repo. For example, you can do `checkout 82jj282` and it will checkout a particular revision or `checkout my-lovely-branch` and it’ll switch from whatever branch you’re on (probably master) to the my-lovely-branch branch.

      `checkout` is almost entirely local, whereas clone, fetch and pull are working with remote versions of your repo.


      1. Mike, thank you, but this is only partly clear. If I understand your explanation correctly, “checkout” puts a copy of a particular branch from the remote repo in your local working directory. But so do clone, fetch, and pull. The differences that I see:
        – clone if you don’t have anything yet in your working directory;
        – pull to update your working directory with the edits from the same branch on the remote repository, and merge with your local edits;
        – fetch will overwrite your working directory with the current revision of the current branch on the remote repo;
        – checkout to overwrite your existing working directory with a particular branch from the remote repository.

  5. What I want usually is not any of these.. What I’m usually wanting to do is a command that will force my local branch to 100% match the remote, downloading anything it needs and deleting anything that doesn’t belong. No “replay” of local changes at all, I want to UNDO them. I’d like to see that as a huge button in the Git Extensions GUI. What I end up doing instead is to completely delete my local tree and then I clone the repository anew. I guess I need to write a script to do the delete/re-clone since it’s not clear anything else produces the same result. Delete/re-clone seems clumsy, like most everything in Git. Yeah, Git is more powerful but what I actually need is ease of use.

    1. Your changes should all be done on a new branch so you’re not breaking master. That way, if things get out of hand, you can delete your branch, switch back to your master branch and create a new branch from the untouched master.

  6. Ok, so I will try to word this correctly.
    1. I did a git clone of a remote repo in order to do something. The repo I cloned is updated by developers daily
    2. I need to update my clone weekly, basically overwrite what I currently have.
    3. Is it git pull?

  7. What the hell is an “upstream”? And what do you mean by “replays”. I think it might help to explain your explanations.

  8. Yeah, got so confused with checkout. I only did checkout and thought the staged changes will be based to the related remote origin. I committed the changes. My colleague came and did a fetch. When I push, I had to merge remote branch with my local branch. Just the source tree looks bad. Instead of a direct push, there’s a merge branch from outside.

  9. I would argue that branches aren’t just _pointers, as you so put it;

    Asume you have two branches on your remote: DEV and MASTER.

    If you work on a hotfix, you make a branch for it, titled “HOTFIX#”. Modify the respective file, then, after the commit, Git will add just those changes that you made to that file when you want to merge it to the MASTER branch on the live site, even if other changes have been made TO THE SAME FILE, that are inbound from other branches that your colleagues have edited.

    This way you can have a major release on Monday by merging the DEV branch to MASTER. And minor releases on Tuesday, Wednesday,… by merging small HOTFIX branches to MASTER. And this can be done by modifying the same file. You can also merge the HOTFIX branches to the DEV branch, if you so please.

  10. So branches take with them, upon the merge, only the respective file modification that you’ve made and Git knows on which row to place it and to not let it be overwritten by colleagues; except when you’re actually working on the same row. That will generate a conflict.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s