From a8fb7533aab724c97f31db2719245db53108093c Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Sun, 31 May 2026 21:26:29 -0700 Subject: [PATCH] Make rebase abort buttons non-destructive - Keep merge abort actions styled as destructive - Make rebase abort match the quieter conflict review treatment --- .../right-sidebar/CommitArea.test.tsx | 37 +++++++++++++++++++ .../right-sidebar/SourceControl.tsx | 12 +++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/components/right-sidebar/CommitArea.test.tsx b/src/renderer/src/components/right-sidebar/CommitArea.test.tsx index 273926ce0bd..2598ab5208a 100644 --- a/src/renderer/src/components/right-sidebar/CommitArea.test.tsx +++ b/src/renderer/src/components/right-sidebar/CommitArea.test.tsx @@ -65,6 +65,15 @@ function firstButton(markup: string): string { return match[0] } +function buttonContaining(markup: string, label: string): string { + const buttons = markup.match(//g) ?? [] + const button = buttons.find((candidate) => candidate.includes(label)) + if (!button) { + throw new Error(`button not found: ${label}`) + } + return button +} + function textarea(markup: string): string { const match = markup.match(//) if (!match) { @@ -374,6 +383,22 @@ describe('ConflictSummaryCard', () => { expect(cherryPickMarkup).not.toContain('Abort rebase') }) + it('renders rebase abort with the quiet review-conflicts button treatment', () => { + const markup = renderToStaticMarkup( + + ) + + expect(buttonContaining(markup, 'Review conflicts')).toContain('data-variant="ghost"') + expect(buttonContaining(markup, 'Abort rebase')).toContain('data-variant="ghost"') + }) + it('renders the Sparkles icon on the idle Resolve with AI button', () => { const markup = renderToStaticMarkup( { expect(cherryPickMarkup).not.toContain('Abort merge') expect(cherryPickMarkup).not.toContain('Abort rebase') }) + + it('keeps rebase abort non-destructive while preserving merge abort styling', () => { + const mergeMarkup = renderToStaticMarkup( + + ) + const rebaseMarkup = renderToStaticMarkup( + + ) + + expect(buttonContaining(mergeMarkup, 'Abort merge')).toContain('data-variant="destructive"') + expect(buttonContaining(rebaseMarkup, 'Abort rebase')).toContain('data-variant="ghost"') + }) }) diff --git a/src/renderer/src/components/right-sidebar/SourceControl.tsx b/src/renderer/src/components/right-sidebar/SourceControl.tsx index 9ea85f66bda..5e5451cdd42 100644 --- a/src/renderer/src/components/right-sidebar/SourceControl.tsx +++ b/src/renderer/src/components/right-sidebar/SourceControl.tsx @@ -6341,6 +6341,14 @@ function DiffCommentsInlineList({ ) } +function conflictAbortButtonVariant( + conflictOperation: GitConflictOperation +): 'ghost' | 'destructive' { + // Why: aborting a rebase is the escape hatch for this state, so it should + // match the quiet conflict-review action instead of reading as a red danger path. + return conflictOperation === 'rebase' ? 'ghost' : 'destructive' +} + export function ConflictSummaryCard({ conflictOperation, unresolvedCount, @@ -6410,7 +6418,7 @@ export function ConflictSummaryCard({ {(conflictOperation === 'merge' || conflictOperation === 'rebase') && onAbortOperation ? (