When I run a
git remote show origin
local out of date
local out of date
up to date
git pull --all
The full answer is a bit complex, in part because
git remote does something no other Git command can do. If you're not using a local branch name, though, you can simply delete it as a distraction. The trick is knowing when it is safe to delete, although "when I'm not already using it and won't be using it" is always a good enough time.
git branch -d branchname to delete-with-checking, and
git branch -D branchname to delete forcefully, i.e., without checking. The "checking" that Git does is different from the checking that
git remote does, so do not be too surprised if they do not agree.
Since (and including) Git version 2.3, you can spell this
git branch -d -f or
git branch --delete --force, the way nearly all other Git commands do it. In older versions of Git you must use the uppercase
-D to forcefully delete a branch name.
It might also be a good idea to stop using
git remote show origin at all.
The Git terminology surrounding this sucks, to put it bluntly. You will see the same words used in different combinations to mean different—sometimes very different, although usually at least a little bit related—things. Git has:
Remotes. A remote is just a one-word name like
origin. A remote name supplies, at a minimum, a URL, so
origin is short for
https://... or whatever. A remote name also provides a prefix for "remote-tracking branches", which we have not defined just yet.
Note that the existence of a remote name implies that there is some other Git, usually on another machine entirely, found via the URL. That other Git repository has all of its own settings, quite independent from yours! This will matter when we talk about remote-tracking branches.
Branches. The word branch is ambiguous in Git (see What exactly do we mean by "branch"? for details), but here it means branch name. These may also be called local branches to distinguish them from the other kind. A branch name is just a short—well, usually short—name like
tasks/I_cant_do_that_dave. These names can have slashes, and the somewhat complicated rules about using slashes in them can mostly be ignored.
A branch name points to one specific commit, which Git calls the tip commit of that branch. Each commit in any Git repository "points back" to earlier commits, too. More precisely, a commit points to its parent commit, or for merges, to its (multiple) parents. This forms a backwards chain, so that by starting from the tip of the branch, Git can find all the rest of the commits that are on that branch.
(As an important side effect, this means many commits are on more than one branch. That does not matter here, but it is one of the keys to understanding Git's branches.)
Beware of names that start with
origin/ or any other remote-name, though, because those usually refer to...
Remote-tracking branches. These show up as names like
origin/master. The function of a remote-tracking branch is to let your Git remember, for you, what your Git saw the last time it talked to that other Git, over on the remote. The points of contact here are
git fetch, which brings stuff from the remote Git to your Git, and
git push, which sends things from your Git to the remote Git along with a request that the remote Git accept them. The details matter somewhat but we'll leave that for later. Just note that
git remote not only can, but usually does, contact the other Git—but then it immediately forgets everything it learned, unlike
Git always keeps remote-tracking branches completely separate from local branch names, so that you can have a local branch named
origin/master at the same time that you have a remote-tracking branch named
origin/master.1 But don't do that: it's too confusing.
So far so good, except for the rather verbose name remote-tracking branch. Some people try to shorten it to "remote branch", but this is a bad idea, because ... well, there's that other Git, the one over on
origin. It's the remote Git (not a great name but what else will we call it?). It is a Git repository, so it has branches. What are we going to call them? The obvious answer is "remote branches", or maybe "branches on the remote". (Git does not really have a proper name for these.)
The purpose of your remote-tracking branches is to keep track of these "on-the-remote branches". Your remote-tracking branches are, however, still yours: they live in your repository, and you can update them yourself if you really insist (but you should just let your Git do it automatically). This is also where
git fetch --prune remotename and
git remote prune remotename and
git remote update --prune remotename come in. The prune options—which should all be the same, but have had slightly different bugs in different Git versions—are instructions to your Git: "When you fetch from that other Git, find out what branches it has, and for any of my remote-tracking branches that no longer match a branch-on-the-remote, delete it automatically."
git fetch updates all your remote-tracking branches for you,
git push does not. Instead, if you are pushing your
origin and asking their Git to update their master, your Git will then take the opportunity to update your
origin/master. Your Git does not, during this push transaction, bother to find and save information on any of their other branches. (There's no important idea behind this, it's just Git's historical behavior, with no strong reason to change it either.)
1Git has specific (and somewhat complicated) rules to pick which one you mean, in case of ambiguity. If you get into this situation, you can use the "full names" for each kind of branch to tell them apart: a local branch's full name always starts with
refs/heads/, while a remote-tracking branch's full name always starts with
refs/remotes/ followed by the name of the remote.
origin/master is short for
refs/remotes/origin/master, i.e., a remote-tracking branch.
An accidental local branch with the same name is really
If both exist, which one does
origin/master actually use? The answer for most Git commands is in the
gitrevisions documentation, but
git checkout behaves differently. Just delete the bad local-branch-name. It's way too confusing.
A branch name is your own name, like
master. This points to a tip commit.
A remote is just a name like
A remote-tracking branch is your name, like
origin/master, for your Git's memory of a name like
master as last seen on the remote. Running
git fetch updates these, and adding
--prune cleans up leftovers of these. A successful
git push updates your remote-tracking branch that corresponds to each successfully-pushed branch.
Now it gets bad. :-)
In Git, you can set any branch—i.e., any ordinary local branch name—to "track" one, and only one, other branch. If local branch L is tracking remote-tracking branch R, we also say, at least in newer Git documentation, that R is L's upstream. For generality, though, and/or just to be more confusing and Gitty, Git lets you track another local branch instead. So L might track U, which is also local, and then U is L's upstream.
The only really critical thing is to realize that each of your local names, like
develop, has either no upstream, or one upstream. Most often, local branches have an upstream that is a remote-tracking branch, with the remote-tracking branch having much the same name as the local branch, but with the remote's name added. Hence
origin/master as its upstream.
Again, "has as its upstream" is the newfangled longer—but (we hope) less confusing—way to say "tracks". The problem with the phrase "master tracks origin/master" is that origin/master is already a remote-tracking branch. Remote-tracking branches don't have upstreams, so now we would have to claim that origin/master doesn't "track" anything, even though it's a "remote-tracking branch"! (Yuck! See why I say the terminology is terrible? Maybe it would help if
origin/master were called a "memory name" or something, but it's not.)
The full answer is a bit long and complicated, but the short version is: this is how Git can say:
Your branch is behind 'origin/master' by 286 commits, ...
and the like, and also how you can run
git rebase, and/or
git push without spelling out where to fetch from, what to merge or rebase-upon, and where to push. That's the main reason to set an upstream: it automates a bunch of stuff for you and makes
git status (and
git branch -v, in modern Gits) much more informative.
Several things set upstreams automatically. The key one is that if you have a remote-tracking branch like
origin/develop, and you don't already have a local branch named
develop, you can just run:
git checkout develop
and your Git will discover that there is an
origin/develop and create a new local name
develop for you, with it set to "track"—i.e., have as its upstream—
Totally-new branches, that you have never pushed anywhere, generally won't have an upstream. The "why not" is simple enough: the correct upstream for
newbranch would be
origin/newbranch. But if you just created
newbranch yourself, there is no
newbranch on the Git at
origin, so there can't be an
origin/newbranch in your own Git repository either. There's no remote-tracking branch to set as the upstream yet! This is where
git push -u comes in, as it means "push, then automatically set as upstream if the push works, since that also creates the remote-tracking branch if needed."
git fetch, your Git calls up the remote's Git, probably over the Internet-phone. Your Git gets a list of their branches and such, and then brings things over as needed—and then it renames their branches, making them into your remote-tracking branches. Since your remote-tracking branches have, as a dedicated function, "remember what you saw on the remote", this is always a good thing to do, and modern Gits just always do it.2
git push, your Git calls up the remote's Git, sends them stuff, and asks them (politely, unless you use
--force: then it asks a bit rudely) to set their branch to refer to the same commit as your branch. You can control the precise form of asking with a refspec, which I won't cover in detail here, but normally their branch name is the same as your branch name. That is, you
git push origin master:master to ask them to set their master to match your master exactly.
There is no automatic renaming here. This is why, for your push to succeed, your branch must normally first be caught up with their branch. Generally, you do this by merging or rebasing. That's all your responsibility: the remote Git won't do any merging. It just either accepts your request, or rejects it. The default rule, if you do not use
--force or equivalent, is to accept your push update if and only if their old tip commit is an ancestor of the new tip you are asking them to set.
Moving a branch name from an old tip to a new tip, such that the new tip commit "contains" the old tip commit, is called a fast-forward. This will be a key phrase later. The test: "is changing from hash X to hash Y a fast-forward?" is the same test as: "is X an ancestor of Y?"
2Since Git version 1.8.4, anyway; and this also glosses over any configured
fetch refspecs. Older versions of Git are ... less helpful.
If your (local) branch L has (your) remote-tracking branch R set as its upstream, you get a bunch of nice automation. You do have to run
git fetch to get R updated: your Git calls up the remote's Git and updates all your remote-tracking branches, and now your Git can compare your L to your R, which is now in sync with their branch (probably named L on their end, but that's in their repository, so it's their responsibility, not yours).
Likewise, when your L has (your) R as its upstream, you can run
git push and your Git figures out what to ask their Git to do. For historical reasons, this is highly configurable, and versions of Git before Git 2.0 do something different by default, but since 2.0, the default action is simple (and is even called
simple): your Git pushes your L to their branch that is also called L. Their branch is probably named L, but let's just call it B, to tell them apart. Your push will generally succeed only if your update to their B is a fast-forward.
git remoteis very different
git remote show origin blows much of the above right out of the water.
So why did we discuss it all? Well, mainly because it's the much more normal way to work with Git. All the documentation out there mostly talks about using it, and the words in that documentation are this confusing mishmash of: "branch" "tracks" / "has as upstream" "remote-tracking branch" (on the "remote", where it's named "branch"). It's important to realize that all these words have specific technical definitions ... and that many of them can just get blown away when you use
git remote. It's also useful because "local out of date", the message you are asking about, has a very specific meaning that ties in with
git push, and we needed a lot of clarity about what
git push does, vs what
git fetch does, which means we needed a lot about remotes too.
git remote show remotename normally does—you can tell it not to—is to call up the remote, just like
git fetch or
git push would. This means it gets an instantaneous, right-now picture, just like
git fetch or
git push would. It then tells you what
git fetch right now, or
git push right now, would do or try to do.
If their Git—the Git on the remote—has a branch named B, your Git would likely fetch it into your
origin/B. So your
git remote show origin says:
Remote branches: master tracked
which essentially means "I would fetch
master and call it
origin/master". (I would argue that this is poorly phrased; but it's like this for historical reasons.)
Meanwhile, if you have a local branch named L, that local branch may be set to "track" (i.e., may have as an upstream) one of the branches your
git fetch would bring over from the remote and rename. For instance, your Git would bring over their
master and call it
origin/master, and your
master might then be behind their master, or ahead of their master, or anyway need merging or rebasing. You would then merge or rebase using your
origin/master, which they call
master. So your
git remote show origin says:
Local branches configured for 'git pull': master merges with remote master
(There are some historical mistakes preserved here as well, which is why the phrasing is the way it is. This also refers to
git pull, which I argue no beginner should use.)
master may not match their
master, so that if you ran
git push, your Git would ask their Git to change their
master to match yours. Your
git remote show origin tells you this by saying:
Local ref configured for 'git push': master pushes to master (local out of date)
Local ref configured for 'git push': master pushes to master (fast-forwardable)
This last message is not as useful as it might seem, since by the time you actually run
git push, their Git may have changed. Still, let's look at precisely what it means.
As we noted briefly above, when talking about
git push, you can push your local branch—which we're calling L here—to a different name in their Git repository; so let's continue to call theirs B here. In any case, as we also noted, when you
git push, you will send them commits if needed, then ask them to set their branch—their B—to point to one specific commit: the tip commit of your L.
Because your Git starts by asking their Git about all its branches, your Git can tell which commit hash-ID their B names. Any commits you will send their Git, ending with the tip of your L, will be all-new to them. But your Git can also tell whether their tip commit—their B—is "new to you", because you either have that commit now, or you don't.
If you do already have their B, your Git can tell whether that commit is an ancestor of your (tip-commit-of) L. If you don't have it, then by definition, it's not an ancestor of L,3 and the push will be rejected. You will need to fetch, then merge or rebase. Even if you do have it, it's possible that B is not an ancestor of L—and your push will be rejected, and you must merge or rebase. So that's what "local out of date" means: you may need to fetch—you might as well just do it since it's always safe—and then you definitely need to merge or rebase, to be able to push politely.
If you don't intend to push this particular branch, this information is useless. Even if you do intend to push, the information becomes stale, potentially very quickly: as soon as someone else pushes, what your
git remote show origin showed is out of date.
In any case, though, that's what "fast-forwardable" means: you can try your push, and if it fails, you will need to fetch, then merge or rebase. "Local out of date" means you will need to fetch, then merge or rebase, and then try to push. Why not just fetch, then merge or rebase if needed, then try to push? What did you gain by running
git remote show origin?
3The proof for this falls apart in the presence of a shallow repository. With shallow repositories,
git remote show origin may simply lie to you.
I don't care about these branches, all I want is to not have local out of date versions, either by getting them up to date or removing my local copy (while retaining the tracking of origin/branchName).
The phrase "the tracking of
origin/branchName" is kind of a stumbling block here for me. All the
origin/branchNames will get updated on
git fetch whether or not you have a local branch. The local branch will "track" (have as an upstream)
origin/branchName if you create it with the automatic-upstream method, which is the easy way. So I think the answer here is "just delete the local branches".