fix(ui): display actual base branch name instead of hardcoded main (#969)

* fix(ui): display actual base branch name instead of hardcoded "main"

The merge conflict UI was showing "Main branch has X new commits"
regardless of the actual base branch. Now it correctly displays
the dynamic branch name (e.g., "develop branch has 40 new commits")
using the baseBranch value from gitConflicts.

* docs: update README download links to v2.7.3 (#976)

- Update all stable download links from 2.7.2 to 2.7.3
- Add Flatpak download link (new in 2.7.3)

* fix(i18n): add translation keys for branch divergence messages

- Add merge section to taskReview.json with pluralized translations
- Update WorkspaceStatus.tsx to use i18n for branch behind message
- Update MergePreviewSummary.tsx to use i18n for branch divergence text
- Add French translations for all new keys

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(i18n): add missing translation keys for branch behind details

- Add branchHasNewCommitsSinceBuild for build started message
- Add filesNeedAIMergeDueToRenames for path-mapped files
- Add fileRenamesDetected for rename detection message
- Add filesRenamedOrMoved for generic rename/move message
- Update WorkspaceStatus.tsx to use all new i18n keys

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(i18n): correct pluralization for rename count in AI merge message

The filesNeedAIMergeDueToRenames translation has two values that need
independent pluralization (fileCount and renameCount). Since i18next
only supports one count parameter, added separate translation keys
for singular/plural renames and select the correct key based on
renameCount value.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(i18n): use translation keys for merge button labels with dynamic branch

Replace hardcoded 'Stage to Main' and 'Merge to Main' button labels with
i18n translation keys that interpolate the actual target branch name.
Also adds translations for loading states (Resolving, Staging, Merging).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Andy
2026-01-13 10:14:49 +01:00
committed by AndyMik90
parent 553d1e8d7a
commit 5d07d5f196
4 changed files with 75 additions and 11 deletions
@@ -1,4 +1,5 @@
import { CheckCircle, AlertTriangle } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { Button } from '../../ui/button';
import { cn } from '../../../lib/utils';
import type { MergeConflict, MergeStats, GitConflictInfo } from '../../../../shared/types';
@@ -20,6 +21,7 @@ export function MergePreviewSummary({
mergePreview,
onShowConflictDialog
}: MergePreviewSummaryProps) {
const { t } = useTranslation(['taskReview']);
const hasGitConflicts = mergePreview.gitConflicts?.hasConflicts;
const hasAIConflicts = mergePreview.conflicts.length > 0;
const hasHighSeverity = mergePreview.conflicts.some(
@@ -72,8 +74,8 @@ export function MergePreviewSummary({
<div className="mb-3 p-2 bg-warning/10 rounded text-xs border border-warning/30">
<p className="font-medium text-warning mb-1">Branch has diverged - AI will resolve</p>
<p className="text-muted-foreground mb-2">
The main branch has {mergePreview.gitConflicts.commitsBehind} new commit{mergePreview.gitConflicts.commitsBehind !== 1 ? 's' : ''} since this worktree was created.
{mergePreview.gitConflicts.conflictingFiles.length} file{mergePreview.gitConflicts.conflictingFiles.length !== 1 ? 's' : ''} will need intelligent merging:
{t('taskReview:merge.branchHasNewCommitsSinceWorktree', { branch: mergePreview.gitConflicts.baseBranch, count: mergePreview.gitConflicts.commitsBehind })}
{' '}{t('taskReview:merge.filesNeedIntelligentMerging', { count: mergePreview.gitConflicts.conflictingFiles.length })}
</p>
<ul className="list-disc list-inside text-muted-foreground">
{mergePreview.gitConflicts.conflictingFiles.map((file, idx) => (
@@ -346,10 +346,10 @@ export function WorkspaceStatus({
{/* Git Conflicts Details */}
{hasGitConflicts && mergePreview?.gitConflicts && (
<div className="text-xs text-muted-foreground pl-6">
Main branch has {mergePreview.gitConflicts.commitsBehind} new commit{mergePreview.gitConflicts.commitsBehind !== 1 ? 's' : ''}.
{t('taskReview:merge.branchHasNewCommits', { branch: mergePreview.gitConflicts.baseBranch, count: mergePreview.gitConflicts.commitsBehind })}
{mergePreview.gitConflicts.conflictingFiles.length > 0 && (
<span className="text-warning">
{' '}{mergePreview.gitConflicts.conflictingFiles.length} file{mergePreview.gitConflicts.conflictingFiles.length !== 1 ? 's' : ''} need merging.
{' '}{t('taskReview:merge.filesNeedMerging', { count: mergePreview.gitConflicts.conflictingFiles.length })}
</span>
)}
</div>
@@ -358,15 +358,15 @@ export function WorkspaceStatus({
{/* Branch Behind Details (no explicit conflicts but needs AI merge due to path mappings) */}
{!hasGitConflicts && isBranchBehind && mergePreview?.gitConflicts && (
<div className="text-xs text-muted-foreground pl-6">
Target branch has {commitsBehind} new commit{commitsBehind !== 1 ? 's' : ''} since this build started.
{t('taskReview:merge.branchHasNewCommitsSinceBuild', { branch: mergePreview.gitConflicts.baseBranch, count: commitsBehind })}
{hasPathMappedMerges ? (
<span className="text-warning">
{' '}{pathMappedAIMergeCount} file{pathMappedAIMergeCount !== 1 ? 's' : ''} need AI merge due to {totalRenames} file rename{totalRenames !== 1 ? 's' : ''}.
{' '}{t(totalRenames === 1 ? 'taskReview:merge.filesNeedAIMergeDueToRenames' : 'taskReview:merge.filesNeedAIMergeDueToRenamesPlural', { renameCount: totalRenames, count: pathMappedAIMergeCount })}
</span>
) : totalRenames > 0 ? (
<span className="text-warning"> {totalRenames} file rename{totalRenames !== 1 ? 's' : ''} detected - AI will handle the merge.</span>
<span className="text-warning"> {t('taskReview:merge.fileRenamesDetected', { count: totalRenames })}</span>
) : (
<span className="text-warning"> Files may have been renamed or moved - AI will handle the merge.</span>
<span className="text-warning"> {t('taskReview:merge.filesRenamedOrMoved')}</span>
)}
</div>
)}
@@ -427,14 +427,20 @@ export function WorkspaceStatus({
{isMerging ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
{hasGitConflicts || isBranchBehind || hasPathMappedMerges ? 'Resolving...' : stageOnly ? 'Staging...' : 'Merging...'}
{hasGitConflicts || isBranchBehind || hasPathMappedMerges
? t('taskReview:merge.buttons.resolving')
: stageOnly
? t('taskReview:merge.buttons.staging')
: t('taskReview:merge.buttons.merging')}
</>
) : (
<>
<GitMerge className="mr-2 h-4 w-4" />
{hasGitConflicts || isBranchBehind || hasPathMappedMerges
? (stageOnly ? 'Stage with AI Merge' : 'Merge with AI')
: (stageOnly ? 'Stage to Main' : 'Merge to Main')}
? (stageOnly ? t('taskReview:merge.buttons.stageWithAIMerge') : t('taskReview:merge.buttons.mergeWithAI'))
: (stageOnly
? t('taskReview:merge.buttons.stageTo', { branch: worktreeStatus.currentProjectBranch || worktreeStatus.baseBranch || 'main' })
: t('taskReview:merge.buttons.mergeTo', { branch: worktreeStatus.currentProjectBranch || worktreeStatus.baseBranch || 'main' }))}
</>
)}
</Button>
@@ -4,6 +4,34 @@
"openInbuilt": "Open in Inbuilt Terminal",
"openExternal": "Open in External Terminal"
},
"merge": {
"branchHasNewCommits": "{{branch}} branch has {{count}} new commit.",
"branchHasNewCommits_other": "{{branch}} branch has {{count}} new commits.",
"branchHasNewCommitsSinceWorktree": "The {{branch}} branch has {{count}} new commit since this worktree was created.",
"branchHasNewCommitsSinceWorktree_other": "The {{branch}} branch has {{count}} new commits since this worktree was created.",
"filesNeedMerging": "{{count}} file needs merging.",
"filesNeedMerging_other": "{{count}} files need merging.",
"filesNeedIntelligentMerging": "{{count}} file will need intelligent merging:",
"filesNeedIntelligentMerging_other": "{{count}} files will need intelligent merging:",
"branchHasNewCommitsSinceBuild": "{{branch}} branch has {{count}} new commit since this build started.",
"branchHasNewCommitsSinceBuild_other": "{{branch}} branch has {{count}} new commits since this build started.",
"filesNeedAIMergeDueToRenames": "{{count}} file needs AI merge due to {{renameCount}} file rename.",
"filesNeedAIMergeDueToRenames_other": "{{count}} files need AI merge due to {{renameCount}} file renames.",
"filesNeedAIMergeDueToRenamesPlural": "{{count}} file needs AI merge due to {{renameCount}} file renames.",
"filesNeedAIMergeDueToRenamesPlural_other": "{{count}} files need AI merge due to {{renameCount}} file renames.",
"fileRenamesDetected": "{{count}} file rename detected - AI will handle the merge.",
"fileRenamesDetected_other": "{{count}} file renames detected - AI will handle the merge.",
"filesRenamedOrMoved": "Files may have been renamed or moved - AI will handle the merge.",
"buttons": {
"stageWithAIMerge": "Stage with AI Merge",
"mergeWithAI": "Merge with AI",
"stageTo": "Stage to {{branch}}",
"mergeTo": "Merge to {{branch}}",
"resolving": "Resolving...",
"staging": "Staging...",
"merging": "Merging..."
}
},
"pr": {
"title": "Create Pull Request",
"description": "Push branch and create a pull request for \"{{taskTitle}}\"",
@@ -4,6 +4,34 @@
"openInbuilt": "Ouvrir dans le terminal intégré",
"openExternal": "Ouvrir dans le terminal externe"
},
"merge": {
"branchHasNewCommits": "La branche {{branch}} a {{count}} nouveau commit.",
"branchHasNewCommits_other": "La branche {{branch}} a {{count}} nouveaux commits.",
"branchHasNewCommitsSinceWorktree": "La branche {{branch}} a {{count}} nouveau commit depuis la création de ce worktree.",
"branchHasNewCommitsSinceWorktree_other": "La branche {{branch}} a {{count}} nouveaux commits depuis la création de ce worktree.",
"filesNeedMerging": "{{count}} fichier nécessite une fusion.",
"filesNeedMerging_other": "{{count}} fichiers nécessitent une fusion.",
"filesNeedIntelligentMerging": "{{count}} fichier nécessitera une fusion intelligente :",
"filesNeedIntelligentMerging_other": "{{count}} fichiers nécessiteront une fusion intelligente :",
"branchHasNewCommitsSinceBuild": "La branche {{branch}} a {{count}} nouveau commit depuis le début de ce build.",
"branchHasNewCommitsSinceBuild_other": "La branche {{branch}} a {{count}} nouveaux commits depuis le début de ce build.",
"filesNeedAIMergeDueToRenames": "{{count}} fichier nécessite une fusion IA en raison de {{renameCount}} renommage de fichier.",
"filesNeedAIMergeDueToRenames_other": "{{count}} fichiers nécessitent une fusion IA en raison de {{renameCount}} renommage de fichier.",
"filesNeedAIMergeDueToRenamesPlural": "{{count}} fichier nécessite une fusion IA en raison de {{renameCount}} renommages de fichiers.",
"filesNeedAIMergeDueToRenamesPlural_other": "{{count}} fichiers nécessitent une fusion IA en raison de {{renameCount}} renommages de fichiers.",
"fileRenamesDetected": "{{count}} renommage de fichier détecté - l'IA gérera la fusion.",
"fileRenamesDetected_other": "{{count}} renommages de fichiers détectés - l'IA gérera la fusion.",
"filesRenamedOrMoved": "Des fichiers ont peut-être été renommés ou déplacés - l'IA gérera la fusion.",
"buttons": {
"stageWithAIMerge": "Préparer avec fusion IA",
"mergeWithAI": "Fusionner avec IA",
"stageTo": "Préparer vers {{branch}}",
"mergeTo": "Fusionner vers {{branch}}",
"resolving": "Résolution...",
"staging": "Préparation...",
"merging": "Fusion..."
}
},
"pr": {
"title": "Créer une Pull Request",
"description": "Pousser la branche et créer une pull request pour \"{{taskTitle}}\"",