By admin , 28 April 2026

Introduction

git push uploads local commits to a remote and updates that remote's branches and tags. It is how your work becomes visible to collaborators.

Basic push

git push                          # current branch to its upstream
git push origin main              # explicit
git push -u origin feature/login  # set upstream and push

The -u (or --set-upstream) flag links the local branch to the remote one so future git push and git pull need no arguments.

Pushing tags

Tags are not pushed by default:

git push origin v1.2.3
git push origin --tags          # all tags
git push --follow-tags          # tags reachable from pushed commits

--follow-tags is the safest default for release workflows.

Deleting remote branches

git push origin --delete feature/login
# equivalently
git push origin :feature/login

Force pushing safely

Rewriting history (rebase, amend, squash) requires a force push. Always prefer --force-with-lease, which refuses to clobber refs that moved on the server:

git push --force-with-lease
git push --force-with-lease=feature/login:abcd1234

Never --force blindly to a shared branch like main.

Configuring push defaults

git config --global push.default simple    # default since 2.0
git config --global push.autoSetupRemote true   # 2.37+: auto -u

With push.autoSetupRemote set, plain git push on a new branch creates the remote branch and links them automatically.

What happens during push

  1. Local Git negotiates with the remote to find common commits.
  2. It packs and uploads only the missing objects.
  3. The remote runs pre-receive and update hooks.
  4. If accepted, refs are updated atomically.
  5. The post-receive hook runs (CI, mirroring, etc.).

Atomic and signed pushes

--atomic turns multi-ref pushes into a single transaction; either every ref updates or none do, which prevents partial deployments. --signed sends a GPG-signed push certificate that some hosts log for audit:

git push --atomic origin main release/1.2
git push --signed origin main

For automated systems, the --receive-pack option lets you specify an alternate receive-pack on the server, occasionally needed for hosts with non-standard binaries. Always use git push --dry-run when scripting destructive pushes for the first time.

Common mistakes

Pushing to main when you meant a feature branch, because you forgot which branch you were on. Run git status first. Using git push --force against main and rewriting other people's commits; recover with the reflog of the remote (if you have shell access) or by re-pushing from a teammate's clone. Pushing without configured credentials and getting hung on a password prompt; configure a credential helper or SSH key. Finally, large pushes can fail at the last moment if a hook rejects them; if so, the rejection message names the offending commit. Read it carefully rather than re-running blindly.