fatal: The current branch feature/login-form has no upstream branch. — a plain git push does not know where a new local branch should go, because nothing links it to a branch on the remote yet. Push it once with git push --set-upstream origin feature/login-form (or the short -u), and every later plain git push works.

If you create branches all day, set push.autoSetupRemote to true and Git sets the upstream by itself on the first push. Both fixes were confirmed below.

The error

$ git push
fatal: The current branch feature/login-form has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin feature/login-form

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

Exit code 128. The branch had one commit and had never been pushed.

Why it happens

An upstream is a setting on a local branch, two lines in .git/config that pair it with a branch on a remote. git push -u origin main wrote them for main; git switch -c created the new branch without any:

$ git config --get-regexp "^branch\."
branch.main.remote origin
branch.main.merge refs/heads/main

With no arguments, git push follows push.default, which is simple unless you changed it: push the current branch to its upstream of the same name. The new branch has no upstream to follow, so Git stops and prints the command that would create one. Nothing reaches the remote; git ls-remote --heads origin still listed only main, and git branch -vv showed the new branch without the [origin/...] part that main had.

The fix

$ git push --set-upstream origin feature/login-form
branch 'feature/login-form' set up to track 'origin/feature/login-form'.
To ../remote.git
 * [new branch]      feature/login-form -> feature/login-form

$ git status -sb
## feature/login-form...origin/feature/login-form

$ git commit -am "Add remember-me checkbox"
[feature/login-form 1ae180b] Add remember-me checkbox
 1 file changed, 1 insertion(+)
$ git push
To ../remote.git
   f08a2c9..1ae180b  feature/login-form -> feature/login-form

The first push creates the branch on the remote and records the pairing, which git status -sb now shows after the three dots. From then on a plain git push needs no arguments. -u is the same option in short form.

The automatic version, tried on the next new branch:

$ git config --local push.autoSetupRemote true
$ git push
branch 'feature/password-reset' set up to track 'origin/feature/password-reset'.
To ../remote.git
 * [new branch]      feature/password-reset -> feature/password-reset

The test set it with --local so it stayed inside the scratch repository. The everyday form, for every repository on your machine, is git config --global push.autoSetupRemote true. Git's manual says the setting takes effect when push.default is simple, upstream or current, which covers the default.

How it was reproduced

Git for Windows 2.45.2 (git version 2.45.2.windows.1), run from Git Bash. A bare repository made with git init --bare stood in for GitHub, so the To line shows ../remote.git where you would see your remote's URL. A working repository pushed main with -u, then git switch -c feature/login-form, one commit and a plain git push failed as above. A repeat run with a branch named feature/cart checked .git/config and the remote's branch list before and after the fix. The machine's personal global config was replaced by an empty file (GIT_CONFIG_GLOBAL) so no personal setting could hide the error. Output was captured to a file, so Git's progress lines do not appear.

Frequently asked

What does 'has no upstream branch' mean in Git?
Your local branch is not linked to any branch on a remote. A plain git push needs that link to know where to send the commits, so it stops and prints the git push --set-upstream command that creates the link.
What is the difference between git push -u and git push --set-upstream?
None. -u is the short form of --set-upstream. Both push the branch and record origin/branch-name as its upstream, so later plain git push and git pull commands know where to go.
How do I make git push set the upstream automatically?
Set push.autoSetupRemote to true. For all your repositories that is git config --global push.autoSetupRemote true. The first plain git push of a new branch then creates it on origin and sets the upstream for you.

More decoded errors in the Fixes category. Part 6 of the Git series, GitHub: Your Code in the Cloud, explains remotes, push and pull, and what -u does on your first push.