Git Developer Guide
fatal: The current branch has no upstream branch
What Git is refusing to do
You made a branch, committed to it, and ran a bare git push. Git doesn't know where that branch should go, so it stops and tells you the command it would like you to run:
$ git switch -c feature/retry
Switched to a new branch 'feature/retry'
$ git commit -am "Add retry"
[feature/retry 6adcd22] Add retry
1 file changed, 1 insertion(+)
$ git push
fatal: The current branch feature/retry has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin feature/retry
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.
Nothing was sent. Your commits are only on this Mac. The outputs on this page come from a throwaway repository on Git 2.54 with default settings, with the remote's address shown as github.com:you/app.git.
What an upstream is
An upstream (also called a tracking branch) is a per-branch setting that pairs a local branch with a branch on a remote, for example feature/retry with origin/feature/retry. Bare git push and git pull use it to work out where to go, and git status uses it to count how far ahead or behind you are. A branch you create with git switch -c starts with none. git branch -vv shows which branches have one:
$ git branch -vv
* feature/retry 6adcd22 Add retry
main e0b7c55 [origin/main] init
main tracks origin/main. feature/retry has no brackets, so it has no upstream. The same gap explains two related messages you may meet first:
$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
...
$ git rev-parse --abbrev-ref @{u}
fatal: no upstream configured for branch 'feature/retry'
Note what git status says on this branch: On branch feature/retry and nothing to commit, working tree clean. It prints no ahead count because there is nothing to count against. A clean status here doesn't mean your work is pushed.
Fix 1: push with -u
Run the command Git suggested. -u is the short form of --set-upstream: it pushes the branch and records the pairing, so every later git push and git pull on this branch works bare.
$ git push -u origin feature/retry
To github.com:you/app.git
* [new branch] feature/retry -> feature/retry
branch 'feature/retry' set up to track 'origin/feature/retry'.
$ git status
On branch feature/retry
Your branch is up to date with 'origin/feature/retry'.
You only need -u on the first push of each branch. git push -u origin HEAD does the same without typing the branch name.
Fix 2: make it automatic with push.autoSetupRemote
Since Git 2.37, one setting makes a bare git push on a new branch create the remote branch of the same name and track it:
$ git config --global push.autoSetupRemote true
$ git switch -c feature/logging
Switched to a new branch 'feature/logging'
# ...commit as usual, then:
$ git push
To github.com:you/app.git
* [new branch] feature/logging -> feature/logging
branch 'feature/logging' set up to track 'origin/feature/logging'.
This only applies when the branch has no upstream yet, so it never redirects a branch that already tracks something. Check your version with git --version; Apple's Git on current macOS is well past 2.37.
Fix 3: the branch already exists on the remote
If you pushed the branch from another machine and then created it here by hand with git switch -c, it has no upstream even though origin/feature/retry exists. Don't push; connect the two:
$ git fetch
$ git branch --set-upstream-to=origin/feature/retry
branch 'feature/retry' set up to track 'origin/feature/retry'.
$ git status
On branch feature/retry
Your branch is behind 'origin/feature/retry' by 1 commit, and can be fast-forwarded.
Next time, skip -c. In a fresh clone, git switch feature/retry finds the remote branch of that name, creates the local one, and sets up tracking for you:
$ git switch feature/retry
Switched to a new branch 'feature/retry'
branch 'feature/retry' set up to track 'origin/feature/retry'.
A push without -u leaves the gap open
git push origin HEAD or git push origin feature/metrics uploads the branch, but it doesn't record an upstream:
$ git push origin HEAD
To github.com:you/app.git
* [new branch] HEAD -> feature/metrics
$ git branch -vv | grep metrics
* feature/metrics ea05b0d m
The commits are safe on the remote, but the next bare git push fails with the same error, and git status still can't tell you when you're ahead again. Run git branch --set-upstream-to=origin/feature/metrics once, or use -u next time.
Two lookalike errors
A branch created from a remote branch tracks that branch, so a feature branch cut from origin/main has origin/main as its upstream. With the default push.default=simple, Git refuses to push it there under a different name:
$ git switch -c feature/cache origin/main
Switched to a new branch 'feature/cache'
branch 'feature/cache' set up to track 'origin/main'.
$ git push
fatal: The upstream branch of your current branch does not match
the name of your current branch. To push to the upstream branch
on the remote, use
git push origin HEAD:main
To push to the branch of the same name on the remote, use
git push origin HEAD
You almost certainly want the second command, as git push -u origin HEAD, so the branch tracks its own remote branch from then on. Branch from local main instead (git switch -c feature/cache main) and it starts with no upstream, like any new branch.
If the repository has no remote at all, the message is different, and the fix is to add one first:
$ git push
fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using
git remote add <name> <url>
How GitMon shows it
Because git status stays quiet about a branch with no upstream, these are easy to forget, especially in a repository you haven't opened for a week. GitMon reads each repository's config and refs and puts an orange Never pushed badge on any repo whose checked-out branch has no upstream. Opening the repo explains it: This branch has never been pushed, because there is nothing to compare against. GitMon doesn't invent an unpushed count for these branches, so they don't appear under the Unpushed filter, which only lists branches that are ahead of a real upstream. Look for the badge in the full list. GitMon never pushes for you; use the commands above.