$ Git Game

My push was rejected

Someone's push landed before yours. The fix is two commands; the rest of this page is about choosing them once, and about the one command that isn't the fix.

$ git push
To ../origin.git
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to '../origin.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

The fix

Pull with a rebase, then push again:

$ git pull --rebase
Successfully rebased and updated refs/heads/main.
$ git push
To ../origin.git
   7a20dd4..febe3f7  main -> main

Your commit is replayed on top of theirs and the push goes through. If the two touched the same lines, the pull stops on a conflict first; resolve it and continue. What the rejection itself means, and the second form it takes, (fetch first), is on the non-fast-forward page.

Choose once

A plain git pull on diverged branches asks you to choose between a rebase and a merge, and refuses to guess. Set it once, and the plain pull does what you chose:

$ git config pull.rebase true
$ git pull
Successfully rebased and updated refs/heads/main.
$ git push
To ../origin.git
   7a20dd4..febe3f7  main -> main

pull.rebase true keeps the history one straight line, which most teams prefer on a shared branch. pull.rebase false merges instead, keeping both histories and adding a merge commit (the three ways a pull lands). git config --global makes either the default for every repository on the machine.

When a force is right, and when it never is

git push --force makes the rejection go away by erasing their commit, which is why it is never the fix on a shared branch. It is right on a branch that is yours alone, after a rebase or an amend rewrote its history, and then as --force-with-lease, which refuses if anyone pushed since you last fetched. Both are on the forced update page.

Why the game does this to you

A rejected push in Git Game is a pack whose push ran after someone else's in the day's random order. The pack pulls before each push for exactly this reason: the pull is the fix, written in advance, and the op it costs is the price of being behind. The pull is also where the choice is made, keep theirs, keep mine or keep both, before the day closes and with nobody there to answer a prompt.

Play a day where this happens

One tap starts a game against the bot. It pushes every day, so sooner or later it reaches main first.

play the bot now

Output captured from Git 2.50.1 (Apple Git-155) by scripts/git-output.sh, in a scratch repository with two clones, ana's and bot's, and fixed dates, so the hashes are the same on every run. It is captured again at every Git release.