Git Push

Git push uploads your local commits to a remote repository, sharing your work with everyone else connected to that remote.

Sending Commits Upstream

Committing changes only updates your local repository; nobody else can see those commits until you push them somewhere they can access. git push takes the commits on your current branch that do not yet exist on the remote and uploads them, then moves the remote's branch pointer forward to match. It is the mechanism by which distributed, offline-friendly Git becomes a genuinely collaborative tool.

Push operates on a simple contract: the remote branch you are pushing to must be an ancestor-compatible continuation of your local branch. In plain terms, the remote must not have commits that you do not yet have locally. If it does, Git refuses the push to protect against accidentally erasing a teammate's work, and asks you to pull first.

Basic Syntax

Pushing a branch explicitly

$ git push origin main
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 8 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 612 bytes | 612.00 KiB/s, done.
Total 5 (delta 3), reused 0 (delta 0)
To github.com:acme/project.git
   d9012ab..a3f1c9d  main -> main

The command reads as 'push my main branch to the remote named origin.' Git reports each object it uploads and finally prints a summary line showing the old commit hash, the new commit hash, and which branch was updated on the remote.

Setting the Upstream with -u

Typing the remote name and branch name every single time gets tedious fast, especially for a branch you push to repeatedly. The -u flag, short for --set-upstream, tells Git to remember the pairing between your local branch and that specific remote branch. After running it once, plain git push and git pull with no arguments know exactly where to send or fetch commits.

Pushing a new branch and linking it upstream

$ git checkout -b feature/search-filters
Switched to a new branch 'feature/search-filters'

$ git push -u origin feature/search-filters
...
To github.com:acme/project.git
 * [new branch]      feature/search-filters -> feature/search-filters
Branch 'feature/search-filters' set up to track remote branch 'feature/search-filters' from 'origin'.

$ git push
Everything up-to-date
Note: Once a branch has an upstream configured, git status will also tell you whether your branch is ahead of, behind, or diverged from the remote branch, which is one of the more subtle but genuinely useful pieces of feedback Git provides.

Common Push Options

  • git push - pushes the current branch to its configured upstream
  • git push origin main - pushes explicitly to a named remote and branch
  • git push -u origin <branch> - pushes and remembers the upstream for future pushes
  • git push --tags - uploads tags that are not automatically included in a normal push
  • git push --force-with-lease - overwrites remote history safely after a rebase, checking nobody else pushed in the meantime

Push Options Compared

CommandEffectWhen to use it
git pushPush to already-configured upstreamEveryday pushes on an existing tracked branch
git push -u origin branchPush and set upstream trackingFirst push of a brand-new local branch
git push --forceOverwrite remote history unconditionallyRarely; risks deleting teammates' commits
git push --force-with-leaseOverwrite only if remote matches your last known stateAfter a local rebase, safer alternative to --force
Note: Avoid plain --force on shared branches like main. If a teammate pushed commits after your last fetch, --force silently discards them on the remote with no easy way to recover. --force-with-lease is almost always the safer choice.

When Push Is Rejected

The most common push error is a rejection because the remote branch has moved ahead of your local branch, usually because a teammate pushed first. Git will print a message telling you the push was rejected and suggest fetching before pushing again. The fix is almost always to pull, resolve any conflicts, and push again.

A rejected push and the fix

$ git push origin main
To github.com:acme/project.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:acme/project.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally.

$ git pull origin main
$ git push origin main