Does a git pull update all tracked branches?
The short answer is "no"—or maybe even "no and yes", if one reads only the title of your question—but this is somewhat misleading.
The pull command allows options, and many of these have interesting (and confusing and potentially very un-nice) effects.
Sidebar: Make sure you correctly understand the differences between what the Git documentation calls remote branches, remote-tracking branches and tracking branches to take full advantage of the following explanations. Note that these are terms that Git (and git-scm.com) use. Long after I wrote this answer originally, I find these terms just confuse people—including me!—and these days, I prefer my own terminology. Instead of remote branch, I like to say branch name as seen on the other (remote) Git repository; instead of remote-tracking branch name (e.g.,
origin/master
), I call this a remote-tracking name; and instead of tracking branch, I use the phrase branch name with an upstream set. But be prepared for Git documentation to use their terminology.
Remember, git pull
is basically shorthand for git fetch
followed by git merge
.1 The pull
command passes most of its arguments right through to the fetch
step. For instance, if you git fetch origin br
, the fetch
step gets the name of the remote (origin
) and br
as a "refspec". In versions of Git predating 1.8.4, this prevented git fetch
from updating any of your remote-tracking branches, but since 1.8.4, explicitly fetching branch br
also updates your origin/br
(assuming the remote in question is named origin
).
If you don't pass extra arguments, git fetch
will fetch the default set of refspecs for the remote, which is normally2 "all branches". This means that either git fetch
(assuming origin
) or git fetch origin
will update all your remote-tracking branches for origin
, provided you are running a reasonably modern (1.8.4 or later) Git. (In sufficiently old versions of Git I think the pull
command gets more restrictive during the fetch step.)
But, having potentially fetched and updated all the origin/*
remote-tracking branches, the pull
code moves on to the git merge
step. For this part, Git cares mightily about which branch you're on now, and which "remote branch"3 it merges with. If, as in your example, you're currently on master
and it merges with origin
's master
, Git will run the git merge
step using whatever new stuff it brought in that went under origin/master
(note the slash here).
Technical nitty details: the "refspec"
I used the word "refspec" above several times, without ever defining it.
The "refspec" is, at its second-simplest, just a pair of branch names, like master:master
, develop:develop
, and the like.
The pair usually, but not always, has the same two branch names on both sides of the colon :
between them. One of these is your name—your branch, in your repository—and the other is their name, that is, the name they use for their branch in their repository.
Usually you see this two-names form when pushing: git push origin master:master
for instance. This means "pack up what I have in my master, call up the remote named origin
over the Internet-phone, send him the package, and ask him if he'll make this his master
branch." You can also use, on the left, a commit ID or the word HEAD
: git push origin HEAD:master
means "take whatever commit I'm on now, and ask the remote origin
to make that his master
".
When doing a git fetch
the sides get reversed, and normally you also add origin/
(or the name of your remote) in front of the name you want on your side. That is, you get his master
, but call it origin/master
in your repository. So you git fetch origin master:origin/master
, and so on.4 If you did git fetch origin master:master
you would (potentially) wipe out work you did on your own master.5
There's one other odd thing with fetch
vs pull
. I said this is the "second simplest" form of a refspec. The simplest is just an unadorned name like master
. The meaning of this depends on which you're doing: for fetch
, it means "bring over his master
, but don't necessarily give it any name in my local repository, just save the hash ID." For push
, it means "give him my master
and ask him to call it master
".
Again, in old versions of git, if you asked git fetch
to bring over their master (and maybe others), without giving fetch
a local name to use for it, it would only save the ID (and their name for the branch) in Git's FETCH_HEAD
file. In newer (1.8.4 and later) versions of Git, git uses the fetch =
configuration entry to figure out what remote-tracking branch(es) to update.
The ugly: git pull origin master branch
(don't do it)
If you tell git fetch
to bring over several branches, that works fine (with Git 1.8.4 or later anyway). But if you tell git pull
to take several branches, it behaves badly.
The fetch
step works fine. Things go wrong at the merge
step.
The pull
code asks git merge
to merge multiple branches into your current branch. Git calls this an "octopus merge". Unless you're into advanced branching, you almost certainly don't want that. So don't do it.
Bottom line
I advise doing one git fetch
, which will by default bring over all, then doing individual git merge
or git rebase
ops. You'll be able to see what you're doing.
1Or git rebase
, if so configured or directed. Rebasing is usually better than merging, though it always depends on details. My advice here is to use git fetch
first, then do your own git rebase
or git merge
as a separate step, at least while you're new to Git. I think it's actually less confusing this way, though admittedly you have to type in two commands instead of just one.
2Technically, it's whatever is in the fetch =
lines in the configuration for that remote. The normal line for remote origin
reads fetch = +refs/heads/*:refs/remotes/origin/*
, which is how git knows to rename origin's branches to your origin/whatever
branches.
3Technically, Git just uses a raw hash ID, saved in a file named FETCH_HEAD
. The term remote branch here in quotes is the standard Git term: the branch name as seen on the repository that is feeding commits to your Git through your git fetch
command.
4I'm leaving out one more thing, which is the leading +
sign: when fetching "their master", you usually want to forget any previous idea you had about "their master", so the fetch =
line has that leading plus sign. This turns on the "force" flag, i.e., update even if it's not a fast-forward operation. The fetch =
line also spells everything out in full to avoid problems if you accidentally name a local branch origin/something
, and uses the *
character to match multiple branch names.
5If you do clobber your own work, you can almost always get it back. Git really tries to hang on to everything for at least 30 days. We'll leave "how to get it back" to other SO entries though.
You can use either git pull --all
to pull all the tracked remote branches or git fetch --all
to fetch them and decide later how to proceed. Be aware that pull usually automatically merges any change and it is seldom what you want.
No. git-pull
will only ever incorporate changes to your local branch. If you want the updates for each other branch, you'll have to check them out and pull
down their updates individually.