Skip to main content

Rebase and Resolve Conflicts

What to do when the remote has moved: recovering from divergence, pulling and rebasing, force-with-lease, resolving conflicts and continuing or aborting, detached HEAD, and the errors that come with all of it.

Reviewed

Recovering from divergence

When a push is rejected because the remote moved on, the banner reads "Remote has N new commits. Pull and rebase, or force push to overwrite." Two recovery paths follow.

Pull and rebase

The primary option opens a confirmation: "Pull and rebase 'BRANCH'? Replays N local commits on top of M incoming commits from the remote. Rebasing rewrites local commit history and cannot be undone." The counts come from the worktree's ahead and behind state. Confirm and the rebase runs against the branch's upstream. If it hits conflicts mid-replay, the working tree drops into the conflict view below.

Force push

The secondary option appears only when Daintree captured a lease for the remote branch at the moment of rejection. Without that lease, --force-with-lease would silently degrade to a plain --force if a background fetch advanced the tracking ref between the rejection and your click, so the button is suppressed rather than offered unsafely.

It opens a dialog titled "Force push to REMOTE/BRANCH?" listing the Remote commits to discard with hash, message, and author, plus a tail count when the range runs longer than the list. Both the rows and the total come from the same range against the resolved destination, so the preview cannot describe a different repository from the one being written.

Force push uses --force-with-lease: it only overwrites the remote if it still matches what Daintree saw when the push was rejected, so it will not clobber a teammate's newer work. It will still discard every remote commit in the list. Pull and rebase is the safer default.

Resolving conflicts

Review Hub resolves conflicts in place. When a worktree is mid-conflict (from a merge, rebase, cherry-pick, or revert), the file list is replaced by a three-region conflict panel.

Operation chrome

An amber banner names the operation: "Resolve Merge Conflicts", "Resolve Rebase Conflicts", and so on. For a rebase it also shows a Step N of M badge and a running conflict count. An Abort button backs the whole operation out; its confirmation spells out exactly what gets discarded and restored for that operation type.

Rebase sequence rail

During a rebase, a vertical rail lists the full commit sequence so you can see where you are. Done commits get a check and dim out, the current commit is bold with an accent chevron, pending commits show a dashed circle, and dropped commits are struck through. Fixup and squash commits sit indented under their parent.

The worklist

Each conflicted file shows a warning icon, its path, a label like "both modified", and a badge with the number of conflict regions. Per file you can:

  • Take ours / Take theirs: resolve the whole file one way, each behind a confirmation.
  • Open: jump to the file in your external editor at the first conflict marker.
  • Mark resolved: stage the file once you have handled it by hand.

Resolved files collapse into a Resolved (N) disclosure. Continue is enabled only once no conflicts remain.

Note
During a rebase, "ours" and "theirs" are inverted from what you would expect: "ours" is the branch you are rebasing onto, and "theirs" is the commit being replayed. The action tooltips spell this out so you do not pick the wrong side.

Detached HEAD

In a detached HEAD state the composer shows an amber warning and disables the textarea and the commit buttons. Detached HEAD is also a readiness blocker, so the rail says so before you reach for the composer.

Errors and auto-refresh

If git status fails to load, a red banner with a Retry button replaces the file lists. A push that is rate-limited reports a rate-limit message rather than a raw error.

Review Hub watches the worktree and refreshes in the background, so the lists stay current while an agent writes files. Your scroll position is kept, and the surface takes a stale treatment (dimmed, and marked busy for assistive technology) while a refresh is in flight rather than tearing down to a skeleton.