Rejected pushes & git pull --rebase

Pull before you push

Lesson 15 of 20 · 10 min · Module 4: Working with GitHub

Working with others means GitHub sometimes has commits you do not have yet. Git protects their work by refusing your push until you bring those commits in.

Start this lesson →

Free. No installation: you write and run the code in your browser, and it is checked automatically.

By the end, you’ll be able to…

  • Explain why a push is rejected
  • Integrate remote commits with pull --rebase or a merge
  • Push again safely

The idea

A push only succeeds if it adds your commits on top of what GitHub already has. If a teammate pushed first, Git rejects your push with fetch first. Integrate their work, then push again. git pull --rebase replays your local commits on top of theirs and keeps the history in a straight line; git pull --no-rebase creates a merge commit instead. When both sides have new commits, plain git pull asks you to choose; git config --global pull.rebase true (or false) sets your default once.

git push
git pull --rebase
git push

01Why GitHub says no

Sam's commit is on GitHub but not on your computer. Your push would replace it, so Git refuses and tells you to integrate the remote work first.

git push
Output
To https://github.com/learner/website.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/learner/website.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

02Rebase or merge

git pull --rebase fetches Sam's commit and replays yours on top of it, so the history stays a straight line. git pull --no-rebase would create a merge commit instead. Both keep everyone's work.

git pull --rebase
git log --oneline -3
Output
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 321 bytes | 321.00 KiB/s, done.
From https://github.com/learner/website
   4abfd2a..858714b  main       -> origin/main
Successfully rebased and updated refs/heads/main.
9cd1755 (HEAD -> main) Add a links page
858714b (origin/main, origin/HEAD) Update the about page
4abfd2a Say what the site is about

03Push again

Now your commit sits on top of everything that is on GitHub, so the push simply adds it.

git push
Output
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 312 bytes | 312.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/learner/website.git
   858714b..9cd1755  main -> main

Your turn

You committed a links page, but Sam pushed to GitHub in the meantime. Try git push and read why it is rejected. Bring in Sam's work with git pull --rebase, which puts your commit on top of his, then push again. Finish with a clean status that is up to date with origin/main.

What the checks look for

  • Your first push is rejected
  • GitHub has Sam's commit and yours
  • Sam's commit is unchanged, with yours after it
  • Your main matches GitHub and is clean
Try it in the editor →

Take this with you

Rejected push? Pull first, with --rebase or --no-rebase, then push again.

Go a little further

In a fresh run, try git pull --no-rebase instead and compare the two histories with git log --oneline --graph.

Learn Git & GitHub for free

20 short lessons with real code and instant checks.

See the whole course →