Chapter 27: Git Push Branch to GitHub
Git push [branch] to GitHub
This is the command that takes the work you did on your laptop (in a branch) and makes it visible and shareable on GitHub so your teammates, your future self, CI/CD pipelines, and the rest of the world (if public) can see it.
Many beginners are afraid of git push because they hear horror stories about force-pushing or overwriting someone’s work — but when you understand it properly, it becomes one of the safest and most predictable steps.
I’m going to explain it very slowly and thoroughly, like I’m sitting right next to you watching the terminal and GitHub page at the same time — with real commands, exact outputs you’ll see, common pitfalls, and a complete realistic example.
1. What does “git push branch to GitHub” actually do?
git push = “send my local commits to the remote (GitHub) and update the branch pointer there”
More precisely, when you run:
|
0 1 2 3 4 5 6 |
git push origin feature/add-dark-mode |
Git does these things:
- Looks at your local branch feature/add-dark-mode
- Finds all commits that exist locally but not yet on origin/feature/add-dark-mode
- Uploads those new commit objects + trees + blobs to GitHub
- Moves the remote branch pointer feature/add-dark-mode to point to your latest local commit
- If the branch didn’t exist on GitHub yet → creates it
Analogy:
- Your laptop = private sketchbook where you drew new pages
- GitHub = shared exhibition wall
- git push = “hang my new pages on the wall so everyone can see them”
2. Important Safety Rules Before You Push Anything
Rule #1 — Never push directly to main/master unless you are 100% sure nobody else is working on it (solo projects only). → Always work on a feature/bugfix branch → push that → create Pull Request → merge via review.
Rule #2 — Always pull first before pushing to shared branches (avoids “non-fast-forward” errors).
Rule #3 — Use -u (set upstream) the first time you push a new branch.
3. Realistic Example – Step by Step (copy-paste ready)
Situation You want to add a dark-mode toggle to your todo app.
Step 1 – Make sure main is up-to-date
|
0 1 2 3 4 5 6 7 |
git switch main git pull origin main |
Step 2 – Create & switch to new branch
|
0 1 2 3 4 5 6 |
git switch -c feature/add-dark-mode-toggle |
Step 3 – Do real work & commit (multiple commits are fine!)
Edit index.html and add some CSS/JS (simplified example):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<button id="themeToggle">Toggle Dark Mode</button> <style> :root { --bg: white; --text: black; } body.dark { --bg: #121212; --text: white; } body { background: var(--bg); color: var(--text); } </style> <script> document.getElementById('themeToggle').addEventListener('click', () => { document.body.classList.toggle('dark'); localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light'); }); // load saved theme if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark'); </script> |
Then:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
git add index.html git commit -m "feat(ui): add basic dark mode toggle with localStorage" # second commit – small fix echo "Improved button styling" >> index.html git add index.html git commit -m "style: improve dark mode button appearance" |
Step 4 – Push the branch to GitHub for the first time
|
0 1 2 3 4 5 6 |
git push -u origin feature/add-dark-mode-toggle |
Typical output:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 8 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (6/6), 1.89 KiB | 1.89 MiB/s, done. Total 6 (delta 1), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (1/1), done. To github.com:Webliance/todo-app.git * [new branch] feature/add-dark-mode-toggle -> feature/add-dark-mode-toggle Branch 'feature/add-dark-mode-toggle' set up to track remote branch 'feature/add-dark-mode-toggle' from 'origin'. |
→ Success! The branch now exists on GitHub.
Go to github.com → your repo → Branches tab → you see feature/add-dark-mode-toggle
Click it → you see your updated index.html with dark mode code.
Step 5 – Later the same day – more work & push again
You add one more commit:
|
0 1 2 3 4 5 6 7 8 9 |
# add system preference detection git commit -m "feat: detect system dark mode preference" git push # no -u needed anymore because of previous -u |
Output much shorter:
|
0 1 2 3 4 5 6 7 8 9 |
Enumerating objects: 4, done. ... To github.com:Webliance/todo-app.git 456def7..89abcde feature/add-dark-mode-toggle -> feature/add-dark-mode-toggle |
→ GitHub now has the new commit too.
4. Most Common git push Patterns (2026)
| Situation | Command you type | What happens |
|---|---|---|
| First push of new branch | git push -u origin feat/add-login | Creates branch on GitHub + sets tracking |
| Normal push on existing branch | git push or git push origin feat/add-login | Sends new commits |
| Push all branches | git push –all | Rarely used — sends every local branch |
| Push tags | git push origin v1.0.0 or git push –tags | Sends release tags |
| Force update (dangerous) | git push –force-with-lease | Overwrites remote if nobody else pushed meanwhile |
5. Common Push Errors & Fixes (very frequent in 2026)
| Error message | Meaning & Fix |
|---|---|
| “Everything up-to-date” | No new local commits → make a commit first |
| “src refspec feat/xxx does not match any” | Branch doesn’t exist locally → check git branch or typo |
| “Updates were rejected … non-fast-forward” | Someone pushed to remote before you → git pull –rebase then push again |
| “Permission denied (publickey)” | SSH not set up → run ssh -T git@github.com or use HTTPS + PAT |
| Asks password every time | Using HTTPS without credential helper → switch to SSH |
6. Safe Daily Push Workflow (what most developers do)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# Start day git switch main git pull origin main # New work git switch -c feat/DEV-456-user-profile # Work → commit several times # Ready to share / get review git push -u origin feat/DEV-456-user-profile # → go to GitHub → create Pull Request |
After PR merged:
|
0 1 2 3 4 5 6 7 8 |
git switch main git pull git branch -d feat/DEV-456-user-profile |
Got the feeling now?
git push branch to GitHub = “upload my branch’s new commits so my team / the internet can see and review them”
Next?
- Want to see what happens when you get a “non-fast-forward” rejection and how to fix it?
- How to create a Pull Request right after pushing?
- Or force-with-lease demo (when it’s safe to use)?
Just tell me — we’ll keep going step by step. You’re doing really well! 🚀
