Lesson 13 · Everyday work
Push commits and publish a branch
Publish the intended branch to the local bare origin without overwriting Leo's newer main. Bring the behind-only main forward explicitly, then publish the feature with its own upstream.
- Level: Beginner
- 6 min read
- 4 min video
- Updated
- Before this lesson: Fetch a teammate's change without replacing your page
Progress saved in this browser.
Playing loads the video from YouTube (privacy-enhanced mode).
What you will learn
- Inspect source and destination before push.
- Fast-forward a behind-only branch without a merge commit.
- Publish one named feature and verify its upstream.
- Distinguish refusal from lost work.
Before you start
Start where lesson 11 ended: main/H6 checked out, origin/main/server H7 with Leo's footer, clean, main six versus fetched seven commits and0/1. Feature F1 exists only locally without upstream.
The video was recorded with Git 2.52.0 and GitTree 2.0 on Ubuntu 24.04: the fast-forward, the pushes and the upstream were done in the app; the before and after checks and the refused push ran in the terminal. Nothing was run on macOS or Windows, and Ubuntu is the only Linux system recorded. GitTree's source Git floor is 2.39.0.
GitTree asks you to sign in; the Free plan then covers every step here. No provider account, Pro/trial, API credential or internet service is needed. A local bare origin is not GitLab or CI. All identities use example.com; never run this lesson inside a source checkout.
Make mutations through either GitTree or the native path at identical inputs, not both consecutively. Read-only verification can follow either. Any preparation described as terminal work is labeled native preparation, never an invented app feature.
Concept and state effects
Push proposes updates to selected remote refs. It is not a backup of every file, untracked buffer or branch. A destination can reject an update even when a network connection works.
The incoming H7 descends from main/H6. A fast-forward can move main to that descendant without inventing a merge commit. This narrowly stated ancestry operation is introduced here; divergent integration belongs to later lessons of the course.
Publishing feature/pricing-cards sends F1 to a new server branch. In GitTree that push does not choose the upstream: you set it afterwards from the same branch row. It neither switches the current branch nor merges its workflow cards into main. A successful no-op main push is not a new server commit.
The explicit fast-forward changes main/HEAD, index and work to H7. Push changes only the selected server ref and local tracking/config after success; it does not save unstaged text. Remote main must retain Leo's commit.
Prepare the exact project state
Use the original after lesson 11, background fetch off for a stable preview. No new file payload or notebook is added. The intentional behind-main rejection is a separate native take, not an instruction to click app force-push.
In GitTree
Palette: Command+Shift+P (Ctrl+Shift+P on Ubuntu); type the exact named command and select it. Named-ref actions use that row's context menu, not an argument-free palette shortcut.
- On main, inspect actual source/destination and0/1 counts; do not push the older main first in the canonical take.
- In the side panel's Remote group, right-click origin/main → Merge origin/main into main. In Record it as choose Fast-forward only, then Merge. Expect main at H7 with Leo's footer, one parent, and a straight line in the graph.
- Run the ancestry/clean readbacks below; if main diverged, Cancel rather than choosing a rewrite mode.
- Click the toolbar Push on main. The notice reads “Everything was already up to date.”: this is not a new commit.
- Under Local, open the feature folder and right-click pricing-cards → Push feature/pricing-cards. With one remote there is no dialog: the notice reads “Pushed feature/pricing-cards to origin/feature/pricing-cards.”
- The push did not set an upstream (the branch had none). Right-click the same row → Upstream → Set Upstream…, in What should feature/pricing-cards track? choose origin/feature/pricing-cards, then Track. Verify server feature F1 and the upstream.
- Select main and feature graph labels without checkout; confirm they remain different tips and no merge appeared.
- Leave main checked out, clean, both named server branches verified. Do not select Force Push… or publish every ref.
For every ordinary commit: Summary is the stated subject; Description empty; Amend Previous Commit, Skip Hooks, Add Signed-off-by, Different Author, Push After Commit and Allow Empty Commit off; no co-authors. Stage only the named files, then Commit Changes to N Files once (File for one), or Command+Enter as an alternative. Wait for the real result. A lesson that explicitly amends changes only that stated option.
In the terminal
From the original demo, native alternative:
git rev-list --left-right --count main...origin/main
git merge --ff-only --quiet origin/main
git push --quiet origin main
git push --quiet --set-upstream origin feature/pricing-cards
git rev-list --left-right --count main...origin/main
git rev-parse --abbrev-ref 'feature/pricing-cards@{upstream}'
git symbolic-ref --short HEAD
git status --shortFirst count0/1; fast-forward and quiet pushes exit 0. The final readbacks print, in order:
0 0
origin/feature/pricing-cards
mainStatus is silent. Independently compare server/local main and feature actual SHAs with git ls-remote --heads origin; variable IDs must match their intended local tips. Separate pre-fast-forward negative take: git push --quiet origin main exited1 with the actual diagnostic excerpt:
! [rejected] main -> main (non-fast-forward)The full diagnostic names the measured local file URL and Git hints. No remote ref changed on that refusal; do not fabricate the URL or repair by force.
Result
Where you end: main fast-forwarded to H7 and still checked out/clean; server main remains H7. Feature F1 is now published as origin/feature/pricing-cards and tracks it; main and feature were not merged.
Common mistakes
- Publishing the current main when you meant the named feature.
- Treating a behind-only refusal as permission to overwrite Leo.
- Assuming the push set the feature's upstream, or that setting it merged anything: the app needs the separate Set Upstream… step.
If something goes wrong
After refusal, fetch and inspect ancestry/destination before retrying. For this exact behind-only input use the explicit fast-forward. A remote push has no generic app Undo; coordinate any later remote correction.
Check your understanding
Answer each question, then read why. Questions marked “Required” count toward completing the lesson.
0 of 6 correct
Answer the required questions correctly to complete the lesson.
Checked in this browser.
Practice
Prove main/server H7 equality, feature/server F1 equality, feature upstream, unchanged main checkout and clean status. In a separate old-main copy predict and observe refusal without losing H7.
Your own confirmation: the site cannot see your computer.
To complete the lesson, answer the required questions correctly and confirm the practical exercise.
Recap
- Inspect the exact destination.
- Integrate a behind-only descendant explicitly.
- Publish one branch without merging it.
Related
Glossary terms introduced
Push — دفع; publish branch — نشر فرع; upstream — الفرع المتتبَّع; fast-forward — تقديم سريع.
Video transcript
The narration of the video, cue by cue.
Show the transcript
- Start from the exact checkpoint.
- Name the branch, index and working version.
- Prepare only the isolated course copy.
- Inspect the exact source and destination.
- Fast-forward only when the ancestry allows it.
- Stop if the actual branches have diverged.
- Main already matches the destination now.
- Publish the named feature, not every branch.
- Verify the feature's own upstream.
- Publication does not merge the feature.
- Leave the original main clean.
- What does publishing F1 do?
- It sends that named ref, not all working files.
- Which facts hold after canonical success?
- Its push was already aligned.
- Fast-forward main/H6 to descendant H7: new merge commit?
- The ref moves to an existing descendant.
- Change input: push old H6 over server H7 before alignment.
- The native take exited1, preserving H7.
- Push says already up to date. Is F1 published?
- Main's result says nothing about another ref.
- Which final evidence is needed?
- Compare actual SHAs for each branch.
- Verify the actual result, not just a message.
- Predict the changed input before acting.
- Preserve useful work before recovery.
- Prove the checkpoint before continuing.
- Keep the verified result for the next step.