Claude / Operating Manual · Topics

← All Operating Manual pages

Git in parallel

Working a shared repo with someone else. Branches, pull requests, merge versus rebase, and the handful of operations that can actually lose work.

updated 2026-07-28

Claude Code commits, branches, rebases and pushes on your behalf, which is fine on a repo only you touch and becomes consequential the moment a second person is in it. This page is the model underneath those operations: what a branch actually is, why a pull request is not a git feature at all, and which four commands are the only ones that can genuinely destroy someone's work.

A branch is a pointer, nothing more

Git does not store folders. It stores commits, immutable snapshots that each point at their parent, forming a chain. A branch is a sticky note with a name on it, pointing at one commit. That is the entire data structure.

When you commit, the sticky note you are standing on slides forward to the new commit. So "being on a branch" just means which sticky note moves when I commit.

This is why everything below is cheap. Creating a branch writes a 40 character file, it does not copy any code. Deleting a branch throws away the note, never the commits.

Where your code actually lives

Four places, two of them invisible, which is what makes this confusing.

WhereWhat it isMoves onward with
Working treeThe actual files on disk you are editinggit add
Staging areaWhat you have marked for the next commitgit commit
Local repositoryYour .git, holding every commit and branch, on your machinegit push
RemoteThe forge copy your collaborator also talks togit fetch

Your local repository is a complete independent copy of the entire history. You and your collaborator each have one. Neither is "the real one", GitHub is simply the copy you have both agreed to sync through.

The one that bites: git commit shares nothing. Nobody can see your commit until you push, and you cannot see theirs until you fetch. Worse, origin/main in your repo is not GitHub's main. It is your cached memory of where it was the last time you fetched, it goes stale silently, and nothing warns you.

Why parallel work needs branches

If two people commit straight onto main, they are both moving the same sticky note and every push becomes a collision. Branches give each person their own note to move.

                    ┌── your branch ──●  ●  ●
                    │
main ──●────●────●──┤
                    │
                    └── theirs ───────●  ●

You each commit freely, neither blocks the other, and you merge back when ready.

What a pull request actually is

A pull request is not a git feature. Git has no idea PRs exist. It is a forge feature (GitHub, GitLab) and it means: here is a branch, please move main forward to include it.

What you buy by asking rather than just doing:

  • A review surface. Someone sees the diff and comments on specific lines.
  • Somewhere for CI to run before the code reaches main, rather than after.
  • A durable record of the why. The description outlives the commits. In six months, "why does this check exist?" has an answer with a URL.
  • A clean rollback point. A merged PR is one revert, not seven.

The cost is latency, you wait for a human. On a solo repo that is pure overhead and committing straight to main is correct. The moment a second person is in the repo, that calculus flips.

Worth checking before you assume you are alone in a repo:

git log --format=%an | sort -u          # who has committed here
gh pr list --state all --limit 10       # is there a PR convention
git branch -r                           # whose branches are in flight

Merge versus rebase

Both answer the same question: main moved while I was working. Say your branch started at B and someone landed C in the meantime.

main       ──A──B──C
                 └──X──Y──Z        your work

Merge ties the two together with a new commit that has two parents. Nothing is rewritten. True history, but the graph braids.

main  ──A──B──C─────────M
              └──X──Y──Z┘

Rebase replays your commits on top of the new tip, as though you had started from C. Linear and much easier to read.

main  ──A──B──C──X'──Y'──Z'

Note X'. It is a new commit with a new SHA. Same changes, different identity. Which gives the rule that matters:

Rebase your own unshared branch freely. Never rebase anything someone else has pulled. If they pulled X Y Z and you rewrote them into X' Y' Z', their repo still holds the originals and git now sees two unrelated histories.

There is a payoff beyond tidiness. Rebasing onto the current main means your tests finally run against your collaborator's latest code instead of a stale tree. A suite that passes on your branch and passes on main has still never proved the two work together until you do this.

Fast forward versus force push

Fast forward means the branch only slides forward along an existing chain. Nothing is rewritten and nothing can be lost. This is the ordinary case and git's default.

Force push points a branch at a commit that is not a descendant of where it was. Commits become orphaned, and anyone who pulled them now has a diverging history.

git push --force-with-lease    # "only if the remote is still where I last saw it"
git push --force               # "I do not care what is there"

Always the first. --force-with-lease aborts if the remote moved since your last fetch, which is exactly the case where a bare --force silently deletes a colleague's afternoon. It is not a formality: a mistyped SHA in the lease will refuse the push rather than guess.

The daily loop

Pull main, branch, commit, fetch, rebase, push, open the PR, then delete the branch once it lands. The fetch before the rebase is the step people skip, and it is the one that makes the rebase meaningful.

git checkout main && git pull      # start from current reality, always
git checkout -b feat/thing         # your own sticky note

# ... work, commit as often as you like ...

git fetch origin                   # refresh your cached view of the remote
git rebase origin/main             # replay onto their latest, re-run the tests
git push -u origin feat/thing      # publish the branch
gh pr create                       # ask for the merge

# ... review, CI, merge on the forge ...

git checkout main && git pull      # pick up your own merged work
git branch -d feat/thing           # bin the note, the commits live on in main

Lowercase -d refuses to delete an unmerged branch, which makes it a safety net worth preferring. -D overrides that check.

When you break it

Commits are almost never truly gone. Git keeps a log of every position each branch has held, for around 90 days, and it is local, so it records things that were never pushed.

git reflog                         # every commit HEAD has pointed at, newest first
git reflog show origin/main        # where one specific branch has been

git branch rescue <sha>            # name it first, look before leaping
git reset --hard <sha>             # then put the branch back where it was

Before any risky move, make a branch at the current commit. It costs nothing and means the work exists under a name you can find, rather than only as a SHA you would have to dig out of the reflog under pressure.

Rules of thumb

  • git fetch before you reason about main. Your origin/main is a cache.
  • One branch per piece of work. They are free.
  • Rebase onto origin/main before opening the PR, so CI tests the real combination.
  • Write the PR description for whoever reads it in six months.
  • Create the branch before rewinding anything, so the work is never only in one place.
  • Do not push straight to main on a repo someone else works in, even when nothing stops you.
  • Do not rebase a branch anyone else has pulled.
  • Never bare --force. --force-with-lease does the same job with a seatbelt.
  • Do not delete or prune someone else's branches, even merged ones. Ask.

Branch protection is the setting that turns the sixth rule from a convention into a mechanism, and it is worth enabling wherever the plan allows it. Until then the convention is the only guardrail, which means it holds exactly as well as the people and agents working in the repo remember it.