Theory
Theory: A Remote is Another Repository Plus a Nickname
origin is not special to Git. It is a default name for a URL. Fetch copies objects and updates remote-tracking refs. Push asks the other repository to move a name it owns.
Invariants
git fetchdoes not move yourmain. It updatesrefs/remotes/origin/main.git pull= fetch + merge or rebase of@{u}intoHEAD.- Non-fast-forward push is rejected because it would drop commits the remote still names.
--force-with-leasesucceeds only if the remote ref still matches what you last fetched.- Several remotes means several photographs of the same DAG, not several Git identities.
laptop origin (bare or forge)
refs/heads/main refs/heads/main
refs/remotes/origin/main ◄── (fetch updates this)
│ push ──────────────────► (moves theirs if fast-forward)
Why PRs are not Git objects
A pull request is a forge row: “please integrate this ref into that ref,” plus comments and checks. The Git underneath is still fetch + merge/rebase/squash on the server.
What can break
git pullon a dirty tree.- Force-push of
main. - Two remotes with the same objects but different
main(divergent policy).
How to read this chapter
Fetch/pull/push, extra remotes, force-with-lease, PRs, two-clone lab; then upstream, refspecs, bundle, prune, fork vs clone.