Sharing work: push and pull

Git · Essentials · 9 min

These two commands are the everyday loop of collaborating through a shared repository.

`git push` uploads your local commits to a remote branch. The first time you push a new branch, set its upstream so later pushes and pulls need no arguments:

git push -u origin feature-login

A push is only accepted if it fast-forwards the remote branch: the remote's current tip must be an ancestor of what you push. If someone else pushed first, Git rejects yours with "Updates were rejected because the remote contains work that you do not have locally". The fix is to bring their work in first, then push again.

`git pull` does that: it fetches new commits from the upstream and integrates them into your current branch. When both sides have new commits, it must either merge (creating a merge commit) or rebase (replaying your commits on top of theirs). Recent Git refuses to guess and asks you to choose, so set pull.rebase once in your config. Many teams prefer pull.rebase true for a linear history on personal branches.

The everyday loop on a shared branch:

  • git pull to start from the latest state.
  • Edit, git add, git commit.
  • git pull again if time has passed, resolve any conflicts.
  • git push.

Never reach for git push --force to get past a rejection; it overwrites your teammates' commits. If you truly need to replace a branch you own (after rebasing it, say), use git push --force-with-lease, which refuses if the remote moved since you last fetched.

Example

git push -u origin main          # first push: set upstream
# ... later
git commit -am "Update docs"
git push
# ! [rejected] main -> main (fetch first)

git pull --rebase                # bring in their commits, replay mine on top
git push                         # now a fast-forward: accepted

git config --global pull.rebase true   # make --rebase the default

Remember

  • push -u once per new branch; afterwards plain git push
  • Pushes must fast-forward the remote; rejections mean pull first
  • pull = fetch + merge or rebase; set pull.rebase to choose
  • Prefer --force-with-lease over --force, and never on shared branches

Watch out for

  • Answering a rejected push with git push --force and silently deleting a colleague's commits.

Check yourself

  1. Your push is rejected because the remote has commits you don't have. What is the right next step?
  2. What does --force-with-lease add over --force?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: git-scm.com/docs/git-push