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.
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.
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.
git checkout -b BRANCH-NAME.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.