fastForwardBranch used git merge --ff-only which fails when the clone has uncommitted files. This caused the ff to be silently skipped, the merge to proceed on stale main, and the push to fail (non-fast-forward). Switched to update-ref which only moves the branch pointer without touching the working tree.