Sharing: remote, push, pull, fetch, clone
Everyone has a full copy of the repo. The remote (GitHub, called origin) is just the copy
everyone agrees to share through. push sends your new commits up. pull brings others' commits
down and merges them into your branch. Git refuses a push if the remote has commits you don't have yet, so you pull first.
The words
| Term | Means |
|---|---|
| remote | Another copy of the repo you exchange commits with. Yours: origin → github.com/guymellsop/WadOfGore (git remote -v) |
origin/main | Your repo's memory of where main was on GitHub the last time you talked to it. It's not live. |
git clone URL | Download a repo for the first time (a full copy, all history) |
git fetch | Download new commits from the remote and update origin/main, but don't touch your files |
git pull | fetch + merge: download, then fold them into your current branch |
git push | Upload your new commits to the remote |
Why a push gets rejected
! [rejected] main -> main (fetch first)
hint: Updates were rejected because the remote contains work that you do not have locally.
A teammate pushed while you were working. Your history and GitHub's have split:
A ── B ── C (GitHub: teammate pushed C)
╲
D (you: committed D on top of B)
If git accepted your push, C would be thrown away. So it refuses. You git pull (bringing C in and merging it
with D), fix any conflicts, and push again.
Habit: pull before you start work, and pull before you push.
--force makes the remote match you by deleting whatever you don't have. That's commit C, your
teammate's work, gone from GitHub. On your own branch it's sometimes legitimate; on main it's how teams lose a day.
If you must, use --force-with-lease, which refuses if someone else pushed in the meantime.
fetch vs pull
fetch is "look, don't touch". It's safe any time, and then git log origin/main shows what your teammates
did before you decide to merge it. pull is "fetch and merge straight away". Most days pull is fine. When you're in the middle of
something delicate, fetch first and look.
Quiz yourself
What is origin?
The default name for the remote you cloned from (here, the GitHub repo).
git pull is two commands in one. Which?
git fetch then git merge (of the fetched branch into yours).
Does git fetch change your files?
No. It downloads commits and updates origin/main, and leaves your branch and files alone.
Your push is rejected with "fetch first". What happened and what do you do?
Someone pushed commits you don't have. Pull (fetch + merge), resolve any conflicts, then push again.
Why is git push --force on main dangerous?
It overwrites the remote with your history, deleting any commits others pushed that you don't have.
Is origin/main always what's on GitHub right now?
No. It's what was there at your last fetch or pull.