Does a git pull update all tracked branches? (2023)

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 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.


Top Articles
Latest Posts
Article information

Author: Trent Wehner

Last Updated: 19/01/2024

Views: 5995

Rating: 4.6 / 5 (56 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Trent Wehner

Birthday: 1993-03-14

Address: 872 Kevin Squares, New Codyville, AK 01785-0416

Phone: +18698800304764

Job: Senior Farming Developer

Hobby: Paintball, Calligraphy, Hunting, Flying disc, Lapidary, Rafting, Inline skating

Introduction: My name is Trent Wehner, I am a talented, brainy, zealous, light, funny, gleaming, attractive person who loves writing and wants to share my knowledge and understanding with you.