Inside the Git pull command
The git pull
command is probably one of the most used. But how does it really work?
git pull [options] [<repository> [<refspec>...]]
As we can read in the git pull
documentation, what this command does is running a git fetch
with the given parameters and then a git merge
to incorporate the retrieved heads into the current branch.
We now need to understand what fetch
does, what are the parameters used for, and what merge
does.
fetch
This is the command to use to get up to date refs__ from a given repository
. _Refs is the git term used to group branches and tags.
The optional refspec
parameter specifies which refs to and which local refs to update.
The format of a
parameter is an optional plus `+`, followed by the source ref , followed by a colon `:`, followed by the destination ref . The colon can be omitted when is empty.
It’s nice to have the power to map a source to a differently named destination, but in my opinion keeping everything aligned with the remote makes things simpler.
merge
The merge
command is certainly another famous one. What it does is incorporating changes from the named commits, since the time their histories diverged from the current branch, into the current branch.
Using the same example used in the documentation, given this tree:
A---B---C topic
/
D---E---F---G master
Running git merge topic
from the master
branch will replay the changes made on topic
since it diverged from master
on top of it, and make a new commit with the result.
This means that the changes from E
introduced by A
, B
, and C
will all end up all together into a single new commit.
A---B---C topic
/ \
D---E---F---G---H master
To recap, git pull origin
under the hood calls git fetch origin
, which gets all the changes made in the remote repository named origin
. Then git merge
is called, which creates a new commit in the current branch to add all the changes fetched.
Food for thoughts:
- What are the most interesting options for
pull
,fetch
andmerge
? - Usage examples of the refspec syntax of
fetch
- How are the default values picked for these commands?