Gitastic
Path › Part 3: Working with others › Lesson 9 of 16
09

Pull & push

Sharing work in both directions — and what "rejected" really means.

1 Learn the idea

Two commands move work between you and origin: git push sends your commits up, git pull brings theirs down.

What pull actually does

  1. git fetch: download new commits and update origin/main.
  2. git merge origin/main: integrate them into your current branch (a fast-forward if you had nothing new, otherwise a merge commit).
  3. With git pull --rebase step 2 becomes a rebase: your local commits are replayed on top of theirs, keeping history in a straight line.

2 Watch it happen

Push, get rejected, pull, push again

Press Play or use → to step through. Watch the graph as each command runs.

origin (GitHub — shared with your team)
220addd Initial commit220adddInitial commitBranch "main" — a movable pointer (current branch: moves when you commit)main
your laptop ~/project · on main
220addd Initial commit220adddInitial commitHEAD = where you are. It points at the current branch.HEAD →Branch "main" — a movable pointer (current branch: moves when you commit)mainRemote-tracking branch: where origin's main was last time you fetchedorigin/main
terminal · simulated, no real repository is touched
Read this demo as text
  1. $ edit about.md "About us"
    $ git add about.md
    $ git commit -m "Add about page"

    You commit locally. main is now 1 ahead of origin/main.

  2. $ git push

    git push copies the commit to origin and moves origin's main (and your origin/main bookmark) forward. Everybody can see it now.

  3. $ teammate push -m "Update README" -f README.md -c "# The Shop"

    Meanwhile, Sam pushes a commit of their own to origin.

  4. $ edit contact.md "mail@shop.test"
    $ git add contact.md
    $ git commit -m "Add contact page"

    You commit something too, without knowing about Sam's work.

  5. $ git push

    Rejected! origin has a commit you do not have. Pushing would throw Sam's work away, so git refuses. Nothing is broken — you just need to integrate first.

  6. $ git pull

    git pull = fetch + merge. Histories diverged, so git creates a merge commit tying Sam's commit and yours together.

  7. $ git push

    Now your main contains everything origin has, so the push is a simple move forward. Accepted.

  8. $ teammate push -m "Add prices" -f prices.md -c "5 EUR"
    $ edit faq.md "Q&A"
    $ git add faq.md
    $ git commit -m "Add FAQ"

    Same situation again: Sam pushed, you committed. This time we will avoid the merge commit.

  9. $ git pull --rebase

    pull --rebase fetches, then replays your FAQ commit on top of Sam's. Straight-line history, no merge bubble. (The old FAQ commit is left behind, faded.)

  10. $ git push

    Push works again. Many teams set git config pull.rebase true to make this the default.

git pull (merge)
  • Keeps exact history
  • Adds a merge commit when diverged
  • Never rewrites your commits
git pull --rebase
  • Linear history
  • Replays your local commits (new hashes)
  • Fine for commits you have not pushed yet
git pullfetch + merge the upstream into your branch
git pull --rebasefetch + replay your commits on top
git push -u origin <branch>First push of a branch; remembers the upstream
git push --force-with-leaseOverwrite remote only if nobody else pushed

3 Check your understanding

Question 1

Your push is rejected with "fetch first". What is the usual fix?

Question 2

git pull is a shortcut for…

Question 3

You created branch search and run git push. Git says it has no upstream branch. What now?

Question 4

Look at the graph: main and origin/main have diverged. You run git pull --rebase. What happens to your local commit?

origin (GitHub — shared with your team)
220addd Initial commit220adddInitial commitf4055ad Their fixf4055adTheir fixBranch "main" — a movable pointer (current branch: moves when you commit)main
your laptop ~/project · on main
220addd Initial commit220adddInitial commitf4055ad Their fixf4055adTheir fixa26df6e My featurea26df6eMy featureRemote-tracking branch: where origin's main was last time you fetchedorigin/mainHEAD = where you are. It points at the current branch.HEAD →Branch "main" — a movable pointer (current branch: moves when you commit)main

4 Practice for real

Your mission

Publish everything, cleanly

You are on branch search. 1) Publish it so it tracks origin/search. 2) Your local main has a commit "Add footer", but Sam already pushed "Add banner". Get your footer onto origin's main without a merge commit.

origin (GitHub — shared with your team)
220addd Initial commit220adddInitial commit3e5e46c Add banner3e5e46cAdd bannerBranch "main" — a movable pointer (current branch: moves when you commit)main
your laptop ~/project · on search
220addd Initial commit click to insert the hash into the terminal220adddInitial commit2ad2197 Add footer click to insert the hash into the terminal2ad2197Add footerad37cfc Add search box click to insert the hash into the terminalad37cfcAdd search boxRemote-tracking branch: where origin's main was last time you fetchedorigin/mainBranch "main" — a movable pointermainHEAD = where you are. It points at the current branch.HEAD →Branch "search" — a movable pointer (current branch: moves when you commit)search
terminal · simulated, no real repository is touched
Type commands below. `help` lists everything. Tab completes, ↑ recalls. Click a commit to paste its hash.
~/project (search) $