You've cloned a repo. You've made a commit locally. The commit
lives in your .git/ folder on your machine, and nowhere else. To
share it, you need to send it back to the remote. That's what
git push does.
What push does
git push origin main
Reads as: "send commits from my local main to the remote called
origin, and update origin's main branch to match mine."
Under the hood Git figures out which commits the remote is missing
(it has your local view of the remote via origin/main, so it can
compare), and sends only those. Efficient. If the remote already
has everything you have, push does nothing.
After a successful push:
To /home/student/origin.git
c1..c2 main -> main
Your local origin/main remote-tracking branch also advances to
the new commit, so your local view of the remote stays accurate.
What happens when push is refused
If the remote has commits you don't, Git refuses to push:
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the remote contains work
hint: that you do not have locally.
This is Git protecting the remote from having its history erased. The remote branch has moved forward (someone else pushed), and your local branch has moved forward too. Just pushing yours would overwrite theirs.
The fix is to bring the remote's commits into your local branch
first. That's git pull (next lesson). Then push again.
-u and why it matters (mostly for later)
The first time you push a new local branch, Git wants you to tell
it where to send the branch AND whether to remember that mapping
for next time. The -u flag (short for --set-upstream) does
both:
git push -u origin feature
After this, git push and git pull (with no arguments) know
which remote branch to talk to. Without the mapping, Git makes
you specify origin and branch every single time.
For this lesson you don't need -u because main was set up as a
tracking branch when you cloned. You can push it with just
git push or git push origin main. The -u matters more in the
new-branch lesson later in this module.
Never force-push a shared branch
Sometimes you'll be tempted to use git push --force or git push -f to override a rejection. Don't, on any branch that's shared.
It literally erases whatever was on the remote and replaces it
with your local version. Anyone who had those erased commits now
has ghost commits, and untangling that costs real time.
If you must force-push (for example after a rebase on your own branch that no one else has pulled), use the safer variant:
git push --force-with-lease origin feature
--force-with-lease refuses the push if the remote has moved
since you last fetched, which catches the case where someone else
pushed while you were rewriting history. It's the closest thing
Git has to a "yes, I really mean it, but only if I still know
what I'm doing" flag.