Git Notes
Learn how to use git push to share your commits with remote repositories. Cover push options, force push, upstream tracking, and push best practices.
Git push is the command that takes your local commits and uploads them to a remote repository. It is the complement to git pull — pull brings others' work to you, push shares your work with others. Until you push, your commits exist only on your machine, invisible to teammates and at risk of being lost if your computer fails.
Understanding push is straightforward for simple cases, but the nuances around force pushing, upstream tracking, and rejected pushes are where most developers get tripped up in team environments.
Basic Push Operations
# Push current branch to its tracked upstream
git push
# Push a specific branch to a specific remote
git push origin main
# Push the current branch (shorthand when upstream is set)
git push origin HEADEnumerating objects: 8, done. Counting objects: 100% (8/8), done. Delta compression using up to 8 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (5/5), 621 bytes | 621.00 KiB/s, done. Total 5 (delta 3), reused 0 (delta 0) remote: Resolving deltas: 100% (3/3), completed with 3 local objects. To github.com:yourname/project.git a1b2c3d..f4e5d6c main -> main
Setting Up Upstream Tracking
The first time you push a new branch, Git does not know where to send it. You need to establish the tracking relationship:
# Create a branch and push it for the first time
git checkout -b feature/notifications
# ... make commits ...
# First push - set upstream tracking
git push -u origin feature/notifications
# or the longer form:
git push --set-upstream origin feature/notificationsTotal 0 (delta 0), reused 0 (delta 0) remote: Create a pull request for 'feature/notifications' on GitHub by visiting: remote: https://github.com/yourname/project/pull/new/feature/notifications To github.com:yourname/project.git * [new branch] feature/notifications -> feature/notifications Branch 'feature/notifications' set up to track remote branch 'feature/notifications' from 'origin'.
After setting upstream once, all future pushes from this branch just need git push with no arguments.
When Push Gets Rejected
The most common frustration. You try to push and Git says no:
git push origin mainTo github.com:yourname/project.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'github.com:yourname/project.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. Integrate the remote changes (e.g., 'git pull ...') hint: before pushing again.
This means someone else pushed commits that you do not have. Git protects the remote from losing their work:
# Solution 1: Pull with rebase (clean history)
git pull --rebase origin main
git push origin main
# Solution 2: Pull with merge (shows merge point)
git pull origin main
# Resolve any conflicts if needed
git push origin mainForce Push: Power and Danger
After rewriting history locally (via amend, rebase, or reset), your local branch diverges from the remote. Normal push fails, and force push is needed:
# DANGEROUS: Overwrites the remote branch completely
git push --force origin feature/my-branch
git push -f origin feature/my-branch
# SAFE(R): Only forces if remote has not changed since your last fetch
git push --force-with-lease origin feature/my-branchThe critical difference: --force blindly overwrites whatever is on the remote. If a teammate pushed between your last fetch and your force push, their work is gone. --force-with-lease checks that the remote is at the commit you expect before overwriting.
# Example: after rebasing your feature branch
git checkout feature/auth
git rebase main
# Now your local branch has different commit hashes
git push --force-with-lease origin feature/authRule: Never force push to shared branches like main or develop. Only force push to your own feature branches, and prefer --force-with-lease.
Pushing Tags
Tags are not pushed automatically — you must push them explicitly:
# Push a single tag
git push origin v1.2.0
# Push all tags at once
git push --tags origin
# Push only annotated tags (not lightweight)
git push origin --follow-tags
# Delete a remote tag
git push origin --delete v0.9.0-betaAdvanced Push Options
# Dry run - see what would be pushed without actually pushing
git push --dry-run origin main
# Push all branches to remote
git push --all origin
# Push and set upstream in one step (Git 2.37+)
git push --set-upstream origin $(git branch --show-current)
# Push to a different remote branch name
git push origin local-branch:remote-branch
# Delete a remote branch via push
git push origin --delete feature/old-branch
git push origin :feature/old-branch # ShorthandPush Hooks and CI Triggers
When you push to platforms like GitHub, it triggers several things automatically:
- CI/CD pipelines run (GitHub Actions, Jenkins, etc.)
- Pull request checks execute
- Deployment workflows may activate
- Notifications go to team members watching the repo
- Status badges update
This is why pushing is more significant than committing. A commit is private; a push is public.
Common Mistakes
Mistake 1: Force pushing to shared branches. This rewrites history that teammates depend on, causing confusion, lost work, and broken local repositories.
Mistake 2: Pushing sensitive data (passwords, API keys, secrets). Once pushed, consider it compromised even if you remove it in the next commit. Use git filter-branch or BFG to purge from history.
Mistake 3: Pushing without pulling first. When your push is rejected, some developers try --force instead of properly integrating remote changes. Always pull first.
Mistake 4: Forgetting to push tags. After tagging a release locally, forgetting to push the tag means no one else sees it. Use git push --follow-tags to push commits and their associated annotated tags together.
Interview Questions
Q1: What happens if you try to push and the remote has newer commits?
Git rejects the push with a "fetch first" error. This prevents overwriting others' work. You must first pull or fetch and merge/rebase to integrate the remote changes, then push again. Never force push to resolve this on shared branches.
Q2: What is the difference between --force and --force-with-lease?
--force blindly overwrites the remote branch regardless of what has changed. --force-with-lease verifies that the remote branch is at the expected commit before force pushing. If someone else has pushed since your last fetch, it fails and prevents data loss.
Q3: What does git push -u origin branch do?
The -u (or --set-upstream) flag creates a tracking relationship between your local branch and the remote branch. After this, Git knows where to push and pull from, allowing you to use git push and git pull without specifying the remote and branch each time.
Q4: How do you push tags to a remote?
Tags are not included in regular pushes. Use git push origin <tagname> for a single tag, git push --tags for all tags, or git push --follow-tags to push annotated tags alongside commits. Delete remote tags with git push origin --delete <tagname>.
Q5: Should you ever force push to main?
Almost never. Force pushing to main rewrites public history, breaks teammates' local copies, and can trigger CI/CD pipeline confusion. The only acceptable case is after a security incident requiring history rewriting, and it requires team coordination. Use git revert for normal undo operations on main.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Git Push - Upload Local Commits to Remote Repository.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Git & GitHub topic.
Search Terms
git-github, git & github, git, github, working, with, repositories, push
Related Git & GitHub Topics