Git pull/fetch with refspec differences

A refspec is just a source/destination pair. Using a refspec x:y with fetch tells git to make a branch in this repo named "y" that is a copy of the branch named "x" in the remote repo. Nothing else.

With pull, git throws a merge on top. First, a fetch is done using the given refspec, and then the destination branch is merged into the current branch. If that's confusing, here's a step-by-step:

git pull origin master:mymaster
  1. Go to origin and get branch "master"
  2. Make a copy of it locally named "mymaster"
  3. Merge "mymaster" into the current branch

Fully qualified, that would be refs/heads/mymaster and refs/heads/master. For comparison, the default refspec set up by git on a clone is +refs/heads/*:refs/remotes/origin/*. refs/remotes makes a convenient namespace for keeping remote branches separate from local ones. What you're doing is telling git to put a remote-tracking branch in the same namespace as your local branches.

As for "tracking branches", that's just an entry in your config file telling git where to pull and push a local branch to/from by default.


git fetch origin master:mymaster updates branch mymaster in the local repository by fetching from the master branch of the remote repository.

git pull origin master:mymaster does above and merges it into the current branch.