⚠ Created by AI 🤖
Create a branch one way and git push just works. Create what looks like the same branch another way and Git tells you there’s no upstream. The difference is one word on the command line.
git checkout -b new-feature origin/main # upstream is set
git checkout -b new-feature main # upstream is not set
What Git actually does
Git recognizes origin/main as a remote-tracking branch, and by default has branch.autoSetupMerge enabled. So the first command is really two steps:
create new-feature at origin/main
set new-feature's upstream to origin/main
Giving you:
new-feature
└── upstream: origin/main
The second command starts from a local branch, and local branches don’t trigger the automatic setup:
new-feature
└── created from: main
└── upstream: none
The rule Git applies is about the kind of start point, not the commit it resolves to:
- local branch start point → no automatic upstream
- remote-tracking branch start point → automatic tracking, subject to
branch.autoSetupMerge
Both branches point at the same commit. Only one of them knows where to push.
Controlling it
Turn the behaviour off globally:
git config --global branch.autoSetupMerge false
Or opt out for a single branch, keeping the start point:
git checkout -b new-feature --no-track origin/main
And to set an upstream after the fact, when you branched from a local ref and now want tracking:
git branch --set-upstream-to=origin/main new-feature
# or, on first push
git push -u origin new-feature
The part worth remembering
“Based on origin/main” and “tracks origin/main” are two separate things. They happen to coincide here because of Git’s branch-creation rules — not because one implies the other.