I did this:
git branch --track stats_page
to create a separate branch to try something out. But now everytime I push or pull I see:
$ git pull
From .
* branch master -> FETCH_HEAD
and
$ git push
Total 0 (delta 0), reused 0 (delta 0)
To .
ff0caf5..e360168 stats_page -> master
I'm far from a git master so I might be miss understanding what's happening - but is my stats_page branch tracking to master?
I may have created the branch wrong - if so - can I fix it so that from now on it pushes and pulls to the remote stats_page branch? How?
Quick answer: The easiest way to fix this is in Make an existing Git branch track a remote branch?
What's really going on here
I've always found descriptions of git's "tracking branches" confusing myself. They sound, to me at least, like they do a lot more than they really do.
The trick, I think, is to realize that git doesn't ever actually "track" a remote repository at all. (It does fetch from a remote repo.) Instead, a "tracking branch" tracks a branch in your own repo. To "track a remote branch", you create a branch whose name says that it was originally copied from some other repo. (Under the covers, this means any branch stored under refs/remotes/
, more or less.) The most common "other repo" is the one named origin
, which is the one that an initial git clone
sets up for you. As it says in the git-clone manual page:
This default configuration is achieved by creating references to the remote branch heads under refs/remotes/origin
and by initializing remote.origin.url
and remote.origin.fetch
configuration variables.
When you use git branch --track
to create a branch, it makes the new branch "track" the "start point" that you give it. (And, "track" mainly means "associate for various push/pull/fetch actions, and tell me more when I run git status
.) So, assuming the repo you cloned-from already has a stats_page
branch, you probably meant to do this:
git branch --track stats_page origin/stats_page
which tells git "make new branch named stats_page
that tracks what I have in refs/remotes/origin/stats_page
" (you normally leave off the refs/heads
and refs/remotes
parts, and git figures them out). You don't even need the --track
here, as the origin/
part on the right turns that on for you.
Once you do all that, in git's terminology, you have a "local" branch (refs/heads/stats_page
) that tracks a "remote" branch (refs/remotes/origin/stats_page
). To actually update the "remote" branch you use git fetch
, or more explicitly, git fetch origin
, which goes out to the URL associated with origin
and collects any new stuff and then adds it to your repo. Hence, despite calling this "remote", it's still remarkably local: it's right there on your own local disk.
(I have taken to calling git "the Borg of SCMs": "We are the git-Borg. We will add your commit distinctiveness to our own." Most of what you do just adds new stuff to your own repo-Borg-collective.)
Once you've used git fetch
to update your local copy of the "remote" branch (origin/stats_page
), you can do a git merge
to get it merged in (to stats_page
, the name without the origin/
part). And, a git pull
just runs those two in one easy step—which hides the fact that it's the fetch
that actually gets new stuff from the "remote"
Now, the problem you have is that when you ran:
git branch --track stats_page
you were on your master
branch, so you created a new "local" branch named stats_page
that tracks your master
, instead of tracking origin/stats_page
. Hence, git pull
and git push
just pull and push on your local branch named master
. (Note: If you actually run git fetch
, that still fetches into remotes/origin/*
, so it still updates origin/stats_page
, even though the one "local" branch is mistakenly tracking another "local" branch.)
One last note: usually when you make a "local" branch that tracks a remote branch of the same name, you also want to do a git checkout
immediately. You can just git checkout -b stats_page origin/stats_page
to get all three steps done at once. (If your version of git is old, it may not automatically track when you name origin/stats_page
on the right; but if so you probably should just update your version of git.)
Footnote: Some people recommend against using
git pull
at all, and I sort of agree with them.
git pull
really mixes two very different operations. In particular
git pull remote_A remote_B
seems to surprise people when it does an octopus merge. Using
git fetch
never seems to surprise people; and once they get used to, and familiar with, an explicit
git merge
, the logic behind fast-forward merges makes a lot more sense. Still,
git pull
with no arguments is so convenient....
open .git/config in a text editor, and look for something like:
push = stats_page:master
You'll probably find something like that in the section for your remote (not your branch).
You can delete it. By default push and pull operations push/pull all matching names. The push option makes it so you can have a local branch push to a remote branch with a different name.
Look at the section for your branch too, you may need to adjust the "merge" option there.