You've seen push work on main, which already had a
counterpart on the remote (origin/main) from when you cloned.
This lesson covers the case where you make a brand new branch
locally and want to publish it. The mechanics are almost the same,
with one small twist that trips up almost everyone the first time.
Making a new local branch is unremarkable
Nothing about branches on the remote side changes what you do locally:
git switch -c feature
Now you have a feature branch locally. As far as the remote
knows, this branch doesn't exist. It has no counterpart yet, so
you can't push to it with just git push, because Git doesn't
know where to send it.
The first push needs -u
The push command for a brand new branch:
git push -u origin feature
Two things happen:
origin/featureis created on the remote, pointing at whatever commit your localfeaturewas at.- The
-uflag (short for--set-upstream) tells your localfeaturebranch to rememberorigin/featureas its upstream.
That upstream link is a small piece of configuration that says
"when I run git push or git pull on this branch with no
arguments, go here." Without it, you'd have to type the remote
and branch every time.
What happens if you forget -u
If you run git push on a new branch without setting upstream,
Git will complain:
fatal: The current branch feature has no upstream branch.
To push the current branch and set the remote as upstream, use:
git push --set-upstream origin feature
Git literally hands you the command to run. Copy, paste, done.
The -u flag is short for exactly this.
You can also set the upstream after the fact:
git branch --set-upstream-to=origin/feature
Effect is the same.
Confirming the tracking
Once upstream is set, git branch -vv shows the tracking
relationship for every branch:
main c1 [origin/main] Initial
* feature c2 [origin/feature] Start feature
The [origin/feature] in brackets is the tracking info. It's
saying "this local branch is linked to that remote branch."
Why upstream tracking matters
Beyond saving keystrokes on push and pull, tracking is what
tells Git how "ahead" or "behind" your local branch is compared
to the remote:
Your branch is ahead of 'origin/feature' by 2 commits.
Your branch is behind 'origin/feature' by 1 commit.
Those messages come from Git comparing your local branch pointer to the tracking pointer. Without an upstream, Git has nothing to compare against.
Every collaborative Git workflow depends on this comparison. Set
-u on the first push and forget about it forever after.