Skip to main content

git push โ€” Uploading to a Remote

What It Doesโ€‹

git push uploads your local commits to a remote repository, making them available to other team members. It transfers only the objects (commits, trees, blobs) that the remote does not yet have, making it efficient.

A push is a fast-forward operation by default โ€” the remote will only accept a push if its branch can be fast-forwarded to your commit (i.e., your local branch is ahead of the remote with no divergence). If the remote has commits you don't have, Git will reject the push and ask you to pull first.


Syntaxโ€‹

git push [remote] [branch]

Common Usageโ€‹

Push current branch to originโ€‹

git push origin feature/JIRA-123-add-export

Push and set upstream tracking (first push of a new branch)โ€‹

git push -u origin feature/JIRA-123-add-export
# After this, plain `git push` and `git pull` work without specifying remote/branch

Push to a differently named remote branchโ€‹

git push origin local-branch:remote-branch

Push all local branchesโ€‹

git push --all origin

Push tags to remoteโ€‹

# Push a specific tag
git push origin v1.2.0

# Push all tags
git push --tags

Delete a remote branchโ€‹

git push origin --delete feature/JIRA-123-add-export
# or shorthand:
git push origin :feature/JIRA-123-add-export

Force Pushโ€‹

Force push replaces the remote branch with your local branch, discarding any commits on the remote that are not in your local history. Use with extreme care.

--force (dangerous โ€” avoid on shared branches)โ€‹

git push --force origin feature/my-branch

This can destroy your teammates' commits if they have pushed to the same branch.

--force-with-lease (safer force push)โ€‹

This is the correct force push to use. It refuses to force-push if the remote has commits you have not fetched โ€” protecting against accidentally overwriting someone else's work:

git push --force-with-lease origin feature/my-branch

When is force push acceptable?

  • After rebasing or amending your own feature branch (before others have based work on it)
  • Cleaning up a PR branch before merge
  • Pushing to your own fork

When is force push NEVER acceptable?

  • main / master
  • develop
  • release/**
  • Any branch that is shared with teammates who have already pulled from it

Protect branches from force pushโ€‹

Configure branch protection in GitHub / GitLab / Bitbucket:

# .github/branch-protection.yml (GitHub Actions / API)
# Require PRs, prevent force push, require status checks on main:
branches:
- name: main
protection:
required_pull_request_reviews:
required_approving_review_count: 1
allow_force_pushes: false
allow_deletions: false
required_status_checks:
strict: true

Upstream Trackingโ€‹

When a local branch tracks a remote branch, Git knows how far ahead or behind you are:

# Check tracking relationships
git branch -vv

# Output:
# * feature/JIRA-123 a3f9bc2 [origin/feature/JIRA-123: ahead 2] feat: add export
# main 91bc3f0 [origin/main] chore: bump Spring Boot version

# Set tracking on an existing branch
git branch --set-upstream-to=origin/main main

Push Hooksโ€‹

Git runs hooks before and after push. Useful for pre-push validation:

# .git/hooks/pre-push (must be executable: chmod +x)
#!/bin/bash

echo "Running pre-push checks..."

# Block push if tests fail
./mvnw test -q
if [ $? -ne 0 ]; then
echo "โŒ Tests failed โ€” push blocked"
exit 1
fi

echo "โœ… Pre-push checks passed"
exit 0

Useful Flags Summaryโ€‹

FlagMeaning
-u / --set-upstreamSet tracking and push
--allPush all local branches
--tagsPush all tags
--forceOverwrite remote unconditionally (dangerous)
--force-with-leaseForce push only if remote hasn't changed (safe)
--deleteDelete a remote branch or tag
--dry-runShow what would be pushed without doing it
-v / --verboseShow details of what is being transferred
--no-verifySkip pre-push hooks (use sparingly)

Never Force-Push to Shared Branches

git push --force on main or develop will rewrite the public history and corrupt every teammate's local clone. Use --force-with-lease on feature branches only, and never on protected branches.

Interview Questions (Senior Level)โ€‹

  1. How do you design branch protection around safe push behavior at scale?
  2. Why is --force-with-lease materially safer than --force?
  3. What controls prevent accidental pushes to privileged remotes?
  4. How do you recover quickly from a mistaken force push?

Short answer guide:

  • Use protected branches, required checks, and approval gates.
  • Lease validation prevents overwriting unseen remote commits.
  • Add remote restrictions, hooks, and least-privilege credentials.
  • Recover via reflog/backup refs and coordinated branch restoration.
Interview Focus

Tie push strategy to governance: branch protection, approval policy, and recovery procedures.

Interview Trap

Recommending --force on collaborative branches instead of --force-with-lease on owned feature branches.