TL;DR
You probably want to set the upstream of your branch. There are lots of ways to do this, but the most direct, at this stage, is to use:
git branch --set-upstream-to=origin/new-branch new-branch
after which all the shortcut stuff you're using will work.
Long: what all this shortcut stuff is
To really understand this, you need to know:
- what a Git branch name really is and does (which is not much, but what it does matters a lot to humans);
- what a remote-tracking name is;
- what the upstream of a branch is; and
- how
git pull
works.
Branch names and remote-tracking names
First, regarding branches, there are several things to keep in mind here:
Git isn't really about branches at all. It's really about commits. Commits aren't really named by branch. They're really named by hash ID. Every Git everywhere agrees that any one particular commit has that hash ID, and no other commit ever gets to use that hash ID. But hash IDs look random, and are impossible for humans to remember, so...
Branch names mainly serve to find commits. That means that we humans depend pretty heavily on the names. Each branch name holds exactly one hash ID. By definition, that hash ID is the hash ID of the last commit in the branch.
Your own Git has its own branch names, which are independent of anyone else's branch names. But because these names are useful to us, your Git will also create remote-tracking names like origin/master
, to remember what your Git saw in the other Git (over on origin
), in their master
. Your Git will update these remote-tracking names whenever your Git gets a chance.
For instance, consider running git fetch origin
. This makes your Git call up their Git, using the short name origin
to look up the URL (their Git's "phone number"). Their Git will list out some or all of their branch names, along with the commit hash IDs that go with those names. Your Git will get these commits, if you don't have them yet, and any other commits that go with those commits, if you don't have them yet. So now you have all of their commits—or all of the ones you need for the specific branch(es) you're fetching, if you limited your git fetch
—and your Git knows which commit their Git's branch name identifies. Hence, your Git now updates your remote-tracking names—your origin/master
and so forth—so that you can remember their commits.
Remember, too, that every commit, named by its unique hash ID, also have inside themselves some hash IDs. Most commits hold one hash ID: that's this commit's parent commit. These parent IDs form commits into backwards-pointing chains. That's why it's OK to just remember the last hash ID. Given a branch name like master
, Git finds the last commit in the chain, i.e., the tip of the branch. That commit remembers the next earlier commit. The next earlier commit remembers another even-earlier commit—the grandparent of the tip commit—and the grandparent remembers another even-earlier commit, and so on.
git pull
All git pull
does is run two Git commands for you:
First, it runs git fetch
. This is what actually obtains new commits. The fetch step will also update your remote-tracking names as appropriate.
The new commits you've picked up, if any, have not affected any of your branch names at all.
Then, it runs a second Git command. This second command will, or at least can, have some effect on some branch name.
Which branch does this second command affect? In theory, that could depend on the second command. Which second command does git pull
run? That's under your control.
You can choose to have git pull
run git rebase
. If you don't do that, though, git pull
will run git merge
. (There are some rare exceptions where git pull
uses yet another option, but you won't hit those unless you're creating a new repository from scratch.)
Before you see what git fetch
fetches, you must decide in advance whether the new commits should be merged, with git merge
, or rebased-onto, with git rebase
. Somehow, magically, you make this decision, and then you run git pull --rebase
or just git pull
, and Git runs the two commands.
The second command affects your current branch, because both rebase and merge affect your current branch. This is true no matter what options and arguments you give to git pull
.
So your current branch matters. And, every branch in Git can have one upstream setting. If you run:
git pull origin new-branch
then git pull
ignores the upstream setting (if any). The name origin
tells it where to fetch
, and the name new-branch
tells it how to run git merge
or git rebase
later, after the fetch finishes.
But if you run:
git pull
with no extra arguments, git pull
uses the upstream setting. This leads us to...
What an upstream is and does
Each branch name can have just one upstream setting. Or, you can unset the upstream, and thus have no upstream. If you unset the upstream—or have a branch in which it has never been set—running git pull
with no arguments just complains at you. So one thing setting the upstream does is enable you to run git pull
with no arguments.
The upstream of a branch is just another name. Usually, it's a remote-tracking name like origin/master
or origin/new-branch
. This comes in two parts: the origin
part—what git pull
will give to git fetch
—and the name of the branch as seen in the other Git. Their master
becomes your origin/master
, so the remote-tracking name origin/master
means, in effect, their master.
You can set the upstream of a branch to a branch in your own Git. (Git stores this internally by setting the "remote" to .
, but git branch --set-upstream-to
doesn't need the .
: you just do a git branch --set-upstream-to=develop feature
and now the upstream of feature
is develop
.) There are some small uses for this but for the most part, upstream settings should refer to some other Git.
Besides setting things up so that you can run git pull
with no arguments—and also split this into git fetch && git merge
or git fetch && git rebase
, also with no extra arguments, if you want to split up the git pull
like I often do—the upstream lets you:
- lets you see how far ahead and/or behind you are when you run
git status
; and
- affects
git push
, depending on your setting of push.default
.
Some branch-creation commands automatically set an upstream for the new branch, and some don't. For more details and links and so on, see Why do I have to "git push --set-upstream origin <branch>"? and Why do I need to do `--set-upstream` all the time?.