From 32929d592e0407aa1b3cc52c71b8ed45a74c63bf Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Wed, 6 May 2026 00:32:55 +0300 Subject: [PATCH] fix: make branch updates use latest remote refs Fetch remote targets before merge or rebase Prefer remote branch targets over stale local branches Fix Update copy and branch search input --- packages/ui/src/components/views/GitView.tsx | 82 ++++++++++++------- .../views/git/BranchIntegrationSection.tsx | 26 +++++- packages/ui/src/lib/i18n/messages/en.ts | 22 ++--- packages/ui/src/lib/i18n/messages/es.ts | 10 +-- packages/ui/src/lib/i18n/messages/ko.ts | 2 +- packages/ui/src/lib/i18n/messages/pt-BR.ts | 10 +-- packages/ui/src/lib/i18n/messages/uk.ts | 22 ++--- 7 files changed, 108 insertions(+), 66 deletions(-) diff --git a/packages/ui/src/components/views/GitView.tsx b/packages/ui/src/components/views/GitView.tsx index d7901618..2df1368e 100644 --- a/packages/ui/src/components/views/GitView.tsx +++ b/packages/ui/src/components/views/GitView.tsx @@ -1396,6 +1396,12 @@ export const GitView: React.FC = () => { return 'main'; }, [effectiveRemotes, localBranches, rootBranchHint, worktreeMetadata?.createdFromBranch]); + const updateTargetBranch = React.useMemo(() => { + const remoteNames = effectiveRemotes.map((remote) => remote.name); + const remoteCandidates = remoteNames.map((remote) => `${remote}/${baseBranch}`); + return remoteCandidates.find((candidate) => remoteBranches.includes(candidate)) ?? baseBranch; + }, [baseBranch, effectiveRemotes, remoteBranches]); + const availableIdentities = React.useMemo(() => { const unique = new Map(); if (globalIdentity) { @@ -1762,6 +1768,29 @@ export const GitView: React.FC = () => { setBranchOperation(null); }, []); + const resolveIntegrationTarget = React.useCallback((branch: string) => { + const trimmed = branch.trim(); + const knownRemoteNames = new Set(effectiveRemotes.map((remote) => remote.name)); + const slashIndex = trimmed.indexOf('/'); + + if (slashIndex > 0) { + const remote = trimmed.slice(0, slashIndex); + const remoteBranch = trimmed.slice(slashIndex + 1); + if (knownRemoteNames.has(remote) && remoteBranch) { + return { branch: trimmed, remote, remoteBranch }; + } + } + + for (const remote of effectiveRemotes) { + const remoteCandidate = `${remote.name}/${trimmed}`; + if (remoteBranches.includes(remoteCandidate)) { + return { branch: remoteCandidate, remote: remote.name, remoteBranch: trimmed }; + } + } + + return { branch: trimmed, remote: null, remoteBranch: null }; + }, [effectiveRemotes, remoteBranches]); + const handleMerge = React.useCallback( async (branch: string) => { if (!currentDirectory) return; @@ -1770,21 +1799,17 @@ export const GitView: React.FC = () => { const currentBranch = status?.current; - const knownRemoteNames = new Set(effectiveRemotes.map((r) => r.name)); + const target = resolveIntegrationTarget(branch); try { - // If it's a remote-tracking branch (prefix matches a known remote), fetch latest first - const slashIndex = branch.indexOf('/'); - if (slashIndex > 0 && knownRemoteNames.has(branch.substring(0, slashIndex))) { - const remote = branch.substring(0, slashIndex); - const remoteBranch = branch.substring(slashIndex + 1); - addOperationLog(`Fetching ${remote}/${remoteBranch}...`, 'running'); - await git.gitFetch(currentDirectory, { remote, branch: remoteBranch }); - updateLastLog('done', `Fetched ${remote}/${remoteBranch}`); + if (target.remote && target.remoteBranch) { + addOperationLog(`Fetching ${target.remote}/${target.remoteBranch}...`, 'running'); + await git.gitFetch(currentDirectory, { remote: target.remote, branch: target.remoteBranch }); + updateLastLog('done', `Fetched ${target.remote}/${target.remoteBranch}`); } - addOperationLog(`Merging ${branch} into ${currentBranch}...`, 'running'); - const result = await git.merge(currentDirectory, { branch }); + addOperationLog(`Merging ${target.branch} into ${currentBranch}...`, 'running'); + const result = await git.merge(currentDirectory, { branch: target.branch }); if (result.conflict) { updateLastLog('error', `Merge conflicts detected`); @@ -1793,7 +1818,7 @@ export const GitView: React.FC = () => { setConflictDialogOpen(true); persistConflictState(currentDirectory, result.conflictFiles ?? [], 'merge'); } else { - updateLastLog('done', `Merged ${branch} into ${currentBranch}`); + updateLastLog('done', `Merged ${target.branch} into ${currentBranch}`); clearConflictState(); addOperationLog('Refreshing repository status...', 'running'); await refreshStatusAndBranches(); @@ -1804,16 +1829,16 @@ export const GitView: React.FC = () => { if (isUncommittedChangesError(err)) { updateLastLog('error', 'Uncommitted changes detected'); setStashDialogOperation('merge'); - setStashDialogBranch(branch); + setStashDialogBranch(target.branch); setStashDialogOpen(true); } else { - const message = err instanceof Error ? err.message : `Failed to merge ${branch}`; + const message = err instanceof Error ? err.message : `Failed to merge ${target.branch}`; updateLastLog('error', message); } } // Note: branchOperation is cleared when dialog closes via handleOperationComplete }, - [currentDirectory, git, status, effectiveRemotes, refreshStatusAndBranches, refreshLog, isUncommittedChangesError, persistConflictState, clearConflictState, addOperationLog, updateLastLog, resetOperationLogs] + [currentDirectory, git, status, resolveIntegrationTarget, refreshStatusAndBranches, refreshLog, isUncommittedChangesError, persistConflictState, clearConflictState, addOperationLog, updateLastLog, resetOperationLogs] ); const handleRebase = React.useCallback( @@ -1824,21 +1849,17 @@ export const GitView: React.FC = () => { const currentBranch = status?.current; - const knownRemoteNames = new Set(effectiveRemotes.map((r) => r.name)); + const target = resolveIntegrationTarget(branch); try { - // If it's a remote-tracking branch (prefix matches a known remote), fetch latest first - const slashIndex = branch.indexOf('/'); - if (slashIndex > 0 && knownRemoteNames.has(branch.substring(0, slashIndex))) { - const remote = branch.substring(0, slashIndex); - const remoteBranch = branch.substring(slashIndex + 1); - addOperationLog(`Fetching ${remote}/${remoteBranch}...`, 'running'); - await git.gitFetch(currentDirectory, { remote, branch: remoteBranch }); - updateLastLog('done', `Fetched ${remote}/${remoteBranch}`); + if (target.remote && target.remoteBranch) { + addOperationLog(`Fetching ${target.remote}/${target.remoteBranch}...`, 'running'); + await git.gitFetch(currentDirectory, { remote: target.remote, branch: target.remoteBranch }); + updateLastLog('done', `Fetched ${target.remote}/${target.remoteBranch}`); } - addOperationLog(`Rebasing ${currentBranch} onto ${branch}...`, 'running'); - const result = await git.rebase(currentDirectory, { onto: branch }); + addOperationLog(`Rebasing ${currentBranch} onto ${target.branch}...`, 'running'); + const result = await git.rebase(currentDirectory, { onto: target.branch }); if (result.conflict) { updateLastLog('error', `Rebase conflicts detected`); @@ -1847,7 +1868,7 @@ export const GitView: React.FC = () => { setConflictDialogOpen(true); persistConflictState(currentDirectory, result.conflictFiles ?? [], 'rebase'); } else { - updateLastLog('done', `Rebased ${currentBranch} onto ${branch}`); + updateLastLog('done', `Rebased ${currentBranch} onto ${target.branch}`); clearConflictState(); addOperationLog('Refreshing repository status...', 'running'); await refreshStatusAndBranches(); @@ -1858,16 +1879,16 @@ export const GitView: React.FC = () => { if (isUncommittedChangesError(err)) { updateLastLog('error', 'Uncommitted changes detected'); setStashDialogOperation('rebase'); - setStashDialogBranch(branch); + setStashDialogBranch(target.branch); setStashDialogOpen(true); } else { - const message = err instanceof Error ? err.message : `Failed to rebase onto ${branch}`; + const message = err instanceof Error ? err.message : `Failed to rebase onto ${target.branch}`; updateLastLog('error', message); } } // Note: branchOperation is cleared when dialog closes via handleOperationComplete }, - [currentDirectory, git, status, effectiveRemotes, refreshStatusAndBranches, refreshLog, isUncommittedChangesError, persistConflictState, clearConflictState, addOperationLog, updateLastLog, resetOperationLogs] + [currentDirectory, git, status, resolveIntegrationTarget, refreshStatusAndBranches, refreshLog, isUncommittedChangesError, persistConflictState, clearConflictState, addOperationLog, updateLastLog, resetOperationLogs] ); const handleAbortConflict = React.useCallback(async () => { @@ -2249,6 +2270,7 @@ export const GitView: React.FC = () => { currentBranch={status?.current} localBranches={localBranches} remoteBranches={remoteBranches} + defaultTargetBranch={updateTargetBranch} onMerge={handleMerge} onRebase={handleRebase} disabled={isBusy} diff --git a/packages/ui/src/components/views/git/BranchIntegrationSection.tsx b/packages/ui/src/components/views/git/BranchIntegrationSection.tsx index 4c825d44..7f9943b1 100644 --- a/packages/ui/src/components/views/git/BranchIntegrationSection.tsx +++ b/packages/ui/src/components/views/git/BranchIntegrationSection.tsx @@ -53,6 +53,7 @@ interface BranchIntegrationSectionProps { operationLogs?: OperationLogEntry[]; onOperationComplete?: () => void; mode?: 'dialog' | 'inline'; + defaultTargetBranch?: string; } export const BranchIntegrationSection: React.FC = ({ @@ -66,6 +67,7 @@ export const BranchIntegrationSection: React.FC = operationLogs = [], onOperationComplete, mode = 'dialog', + defaultTargetBranch, }) => { const { t } = useI18n(); const [dialogOpen, setDialogOpen] = React.useState(false); @@ -94,10 +96,15 @@ export const BranchIntegrationSection: React.FC = // Filter branches based on search const filteredLocal = React.useMemo(() => { const term = branchSearch.toLowerCase(); - const filtered = localBranches.filter((b) => b !== currentBranch); + const remoteBranchNames = new Set( + remoteBranches + .map((branch) => branch.slice(branch.indexOf('/') + 1)) + .filter(Boolean) + ); + const filtered = localBranches.filter((branch) => branch !== currentBranch && !remoteBranchNames.has(branch)); if (!term) return filtered; return filtered.filter((b) => b.toLowerCase().includes(term)); - }, [branchSearch, localBranches, currentBranch]); + }, [branchSearch, localBranches, currentBranch, remoteBranches]); const filteredRemote = React.useMemo(() => { const term = branchSearch.toLowerCase(); @@ -105,9 +112,16 @@ export const BranchIntegrationSection: React.FC = return remoteBranches.filter((b) => b.toLowerCase().includes(term)); }, [branchSearch, remoteBranches]); + const resolveDefaultBranch = React.useCallback(() => { + if (!defaultTargetBranch) return null; + if (remoteBranches.includes(defaultTargetBranch)) return defaultTargetBranch; + if (localBranches.includes(defaultTargetBranch)) return defaultTargetBranch; + return null; + }, [defaultTargetBranch, localBranches, remoteBranches]); + const handleOpenDialog = () => { setDialogOpen(true); - setSelectedBranch(null); + setSelectedBranch(resolveDefaultBranch()); setOperation('merge'); setBranchSearch(''); }; @@ -158,6 +172,11 @@ export const BranchIntegrationSection: React.FC = } }, [branchDropdownOpen]); + React.useEffect(() => { + if (mode !== 'inline' || selectedBranch) return; + setSelectedBranch(resolveDefaultBranch()); + }, [mode, resolveDefaultBranch, selectedBranch]); + const renderOperating = () => (
= placeholder={t('gitView.branch.searchPlaceholder')} value={branchSearch} onValueChange={setBranchSearch} + onKeyDown={(event) => event.stopPropagation()} /> {t('gitView.branch.empty')} diff --git a/packages/ui/src/lib/i18n/messages/en.ts b/packages/ui/src/lib/i18n/messages/en.ts index 01620f58..b6fdbe9a 100644 --- a/packages/ui/src/lib/i18n/messages/en.ts +++ b/packages/ui/src/lib/i18n/messages/en.ts @@ -364,19 +364,19 @@ export const dict = { 'sessions.sidebar.sessionDialogs.actions.deleteLocalBranch': 'Delete local branch', 'sessions.sidebar.sessionDialogs.actions.deleting': 'Deleting…', 'sessions.sidebar.sessionDialogs.actions.deleteWorktree': 'Delete worktree', - 'gitView.branch.branchToMergeInto': 'Branch To Merge Into', - 'gitView.branch.branchToRebaseOnto': 'Branch To Rebase Onto', + 'gitView.branch.branchToMergeInto': 'Branch to merge into {branch}', + 'gitView.branch.branchToRebaseOnto': 'Branch to rebase onto', 'gitView.branch.create': 'Create new branch...', 'gitView.branch.currentBadge': 'Current', 'gitView.branch.currentBranchFallback': 'current branch', 'gitView.branch.currentBranchTooltip': 'Current branch', 'gitView.branch.detachedHead': 'Detached HEAD', - 'gitView.branch.dialogDescriptionPrefix': 'Dialog Description Prefix', + 'gitView.branch.dialogDescriptionPrefix': 'Choose how to bring another branch into', 'gitView.branch.empty': 'No branches found.', 'gitView.branch.localBranches': 'Local branches', - 'gitView.branch.mergeDescription': 'Merge Description', + 'gitView.branch.mergeDescription': 'Create a merge commit and preserve branch history.', 'gitView.branch.mergeRebase': 'Merge/Rebase', - 'gitView.branch.mergeRebaseTooltip': 'Merge Rebase tooltip', + 'gitView.branch.mergeRebaseTooltip': 'Update this branch from another branch.', 'gitView.branch.mergingInProgress': 'Merging In Progress', 'gitView.branch.namePlaceholder': 'Branch name', 'gitView.branch.newBranchPlaceholder': 'New branch name', @@ -387,17 +387,17 @@ export const dict = { 'gitView.branch.operationFailed': 'Operation Failed', 'gitView.branch.pushToPrefix': 'Push To Prefix', 'gitView.branch.pushToSuffix': 'Push To Suffix', - 'gitView.branch.rebaseDescription': 'Rebase Description', + 'gitView.branch.rebaseDescription': 'Replay your commits on top of the selected branch.', 'gitView.branch.rebasingInProgress': 'Rebasing In Progress', 'gitView.branch.remoteBranches': 'Remote branches', 'gitView.branch.renameTitle': 'Rename branch', 'gitView.branch.searchPlaceholder': 'Search branches...', 'gitView.branch.selectBranch': 'Select Branch', - 'gitView.branch.summaryMergeInfix': 'Summary Merge Infix', - 'gitView.branch.summaryMergePrefix': 'Summary Merge Prefix', - 'gitView.branch.summaryRebaseInfix': 'Summary Rebase Infix', - 'gitView.branch.summaryRebasePrefix': 'Summary Rebase Prefix', - 'gitView.branch.updateDescriptionPrefix': 'Update Description Prefix', + 'gitView.branch.summaryMergeInfix': 'into', + 'gitView.branch.summaryMergePrefix': 'This will merge', + 'gitView.branch.summaryRebaseInfix': 'onto', + 'gitView.branch.summaryRebasePrefix': 'This will rebase', + 'gitView.branch.updateDescriptionPrefix': 'Bring the latest changes into', 'gitView.branch.updateTitle': 'Update branch', 'gitView.changes.changedFilesAria': 'Changed files', 'gitView.changes.clearSelectionAria': 'Clear file selection', diff --git a/packages/ui/src/lib/i18n/messages/es.ts b/packages/ui/src/lib/i18n/messages/es.ts index 818d619c..c9b83b91 100644 --- a/packages/ui/src/lib/i18n/messages/es.ts +++ b/packages/ui/src/lib/i18n/messages/es.ts @@ -372,12 +372,12 @@ export const dict: Record = { "gitView.branch.currentBranchFallback": "rama actual", "gitView.branch.currentBranchTooltip": "Rama actual", "gitView.branch.detachedHead": "HEAD desvinculado", - "gitView.branch.dialogDescriptionPrefix": "Confirma la operación sobre", + "gitView.branch.dialogDescriptionPrefix": "Elige cómo traer otra rama a", "gitView.branch.empty": "No se encontraron ramas.", "gitView.branch.localBranches": "Ramas locales", - "gitView.branch.mergeDescription": "Hacer merge de la rama seleccionada", + "gitView.branch.mergeDescription": "Crea un commit de merge y conserva el historial.", "gitView.branch.mergeRebase": "Merge/Rebase", - "gitView.branch.mergeRebaseTooltip": "Merge o rebase con otra rama", + "gitView.branch.mergeRebaseTooltip": "Actualiza esta rama desde otra rama.", "gitView.branch.mergingInProgress": "Merge en curso", "gitView.branch.namePlaceholder": "Nombre de la rama", "gitView.branch.newBranchPlaceholder": "Nombre de la nueva rama", @@ -388,7 +388,7 @@ export const dict: Record = { "gitView.branch.operationFailed": "No se pudo completar la operación", "gitView.branch.pushToPrefix": "Enviar", "gitView.branch.pushToSuffix": "a:", - "gitView.branch.rebaseDescription": "Hacer rebase de la rama seleccionada", + "gitView.branch.rebaseDescription": "Reaplica tus commits encima de la rama seleccionada.", "gitView.branch.rebasingInProgress": "Rebase en progreso", "gitView.branch.remoteBranches": "Ramas remotas", "gitView.branch.renameTitle": "Cambiar nombre de rama", @@ -398,7 +398,7 @@ export const dict: Record = { "gitView.branch.summaryMergePrefix": "Se hará merge de", "gitView.branch.summaryRebaseInfix": "sobre", "gitView.branch.summaryRebasePrefix": "Se hará rebase de", - "gitView.branch.updateDescriptionPrefix": "Confirma la operación sobre", + "gitView.branch.updateDescriptionPrefix": "Trae los últimos cambios a", "gitView.branch.updateTitle": "Actualizar rama", "gitView.changes.changedFilesAria": "Archivos modificados", "gitView.changes.clearSelectionAria": "Limpiar selección de archivos", diff --git a/packages/ui/src/lib/i18n/messages/ko.ts b/packages/ui/src/lib/i18n/messages/ko.ts index 6ab668f0..8a4c3ff5 100644 --- a/packages/ui/src/lib/i18n/messages/ko.ts +++ b/packages/ui/src/lib/i18n/messages/ko.ts @@ -398,7 +398,7 @@ export const dict: Record = { 'gitView.branch.summaryMergePrefix': '현재 브랜치에', 'gitView.branch.summaryRebaseInfix': '위로 리베이스', 'gitView.branch.summaryRebasePrefix': '현재 브랜치를', - 'gitView.branch.updateDescriptionPrefix': '브랜치 설명 접두사 업데이트', + 'gitView.branch.updateDescriptionPrefix': '최신 변경 사항을 가져올 대상:', 'gitView.branch.updateTitle': '브랜치 업데이트', 'gitView.changes.changedFilesAria': '변경된 파일', 'gitView.changes.clearSelectionAria': '파일 선택 해제', diff --git a/packages/ui/src/lib/i18n/messages/pt-BR.ts b/packages/ui/src/lib/i18n/messages/pt-BR.ts index 9262cfc5..0495ec4e 100644 --- a/packages/ui/src/lib/i18n/messages/pt-BR.ts +++ b/packages/ui/src/lib/i18n/messages/pt-BR.ts @@ -372,12 +372,12 @@ export const dict: Record = { "gitView.branch.currentBranchFallback": "branch atual", "gitView.branch.currentBranchTooltip": "Branch atual", "gitView.branch.detachedHead": "HEAD desvinculado", - "gitView.branch.dialogDescriptionPrefix": "Confirmà operación sobre", + "gitView.branch.dialogDescriptionPrefix": "Escolha como trazer outra branch para", "gitView.branch.empty": "Nenhuma branch encontrada.", "gitView.branch.localBranches": "Branches locais", - "gitView.branch.mergeDescription": "Fazer merge da branch selecionada", + "gitView.branch.mergeDescription": "Cria um commit de merge e preserva o histórico.", "gitView.branch.mergeRebase": "Merge/Rebase", - "gitView.branch.mergeRebaseTooltip": "Merge ou rebase com outra branch", + "gitView.branch.mergeRebaseTooltip": "Atualiza esta branch a partir de outra branch.", "gitView.branch.mergingInProgress": "Merge em curso", "gitView.branch.namePlaceholder": "Nome da branch", "gitView.branch.newBranchPlaceholder": "Nome da nova branch", @@ -388,7 +388,7 @@ export const dict: Record = { "gitView.branch.operationFailed": "Não foi possível completar a operación", "gitView.branch.pushToPrefix": "Enviar", "gitView.branch.pushToSuffix": "a:", - "gitView.branch.rebaseDescription": "Hacer rebase da branch selecionada", + "gitView.branch.rebaseDescription": "Reaplica seus commits sobre a branch selecionada.", "gitView.branch.rebasingInProgress": "Rebase em andamento", "gitView.branch.remoteBranches": "Branches remotas", "gitView.branch.renameTitle": "Renomear de branch", @@ -398,7 +398,7 @@ export const dict: Record = { "gitView.branch.summaryMergePrefix": "Se hará merge de", "gitView.branch.summaryRebaseInfix": "sobre", "gitView.branch.summaryRebasePrefix": "Se hará rebase de", - "gitView.branch.updateDescriptionPrefix": "Confirmà operación sobre", + "gitView.branch.updateDescriptionPrefix": "Traz as alterações mais recentes para", "gitView.branch.updateTitle": "Atualizar branch", "gitView.changes.changedFilesAria": "Arquivos modificados", "gitView.changes.clearSelectionAria": "Limpar selección de arquivos", diff --git a/packages/ui/src/lib/i18n/messages/uk.ts b/packages/ui/src/lib/i18n/messages/uk.ts index 38bc0c69..fab826a2 100644 --- a/packages/ui/src/lib/i18n/messages/uk.ts +++ b/packages/ui/src/lib/i18n/messages/uk.ts @@ -365,19 +365,19 @@ export const dict: Record = { "sessions.sidebar.sessionDialogs.actions.deleteLocalBranch": "Видалити локальну гілку", "sessions.sidebar.sessionDialogs.actions.deleting": "Видалення…", "sessions.sidebar.sessionDialogs.actions.deleteWorktree": "Видалити worktree", - "gitView.branch.branchToMergeInto": "Гілка для злиття", - "gitView.branch.branchToRebaseOnto": "Гілка для перебазування", + "gitView.branch.branchToMergeInto": "Гілка, яку злити в {branch}", + "gitView.branch.branchToRebaseOnto": "Гілка, на яку перебазуватися", "gitView.branch.create": "Створити нову гілку...", "gitView.branch.currentBadge": "поточний", "gitView.branch.currentBranchFallback": "поточна гілка", "gitView.branch.currentBranchTooltip": "Поточна гілка", "gitView.branch.detachedHead": "Відокремлено HEAD", - "gitView.branch.dialogDescriptionPrefix": "Виконайте операцію з гілкою.", + "gitView.branch.dialogDescriptionPrefix": "Виберіть, як підтягнути іншу гілку в", "gitView.branch.empty": "Гілок не знайдено.", "gitView.branch.localBranches": "Локальні гілки", - "gitView.branch.mergeDescription": "Злити поточну гілку в цільову.", + "gitView.branch.mergeDescription": "Створити merge commit і зберегти історію гілок.", "gitView.branch.mergeRebase": "Злити/перебазувати", - "gitView.branch.mergeRebaseTooltip": "Відкрити дії злиття або перебазування", + "gitView.branch.mergeRebaseTooltip": "Оновити цю гілку з іншої гілки.", "gitView.branch.mergingInProgress": "Виконується злиття", "gitView.branch.namePlaceholder": "Назва гілки", "gitView.branch.newBranchPlaceholder": "Нова назва гілки", @@ -388,17 +388,17 @@ export const dict: Record = { "gitView.branch.operationFailed": "Операцію не виконано", "gitView.branch.pushToPrefix": "Надіслати до", "gitView.branch.pushToSuffix": "після завершення", - "gitView.branch.rebaseDescription": "Перебазувати поточну гілку на цільову.", + "gitView.branch.rebaseDescription": "Переграти ваші коміти поверх вибраної гілки.", "gitView.branch.rebasingInProgress": "Виконується перебазування", "gitView.branch.remoteBranches": "Віддалені гілки", "gitView.branch.renameTitle": "Перейменувати гілку", "gitView.branch.searchPlaceholder": "Пошук гілок...", "gitView.branch.selectBranch": "Вибрати гілку", - "gitView.branch.summaryMergeInfix": "буде злито в", - "gitView.branch.summaryMergePrefix": "Поточна гілка", - "gitView.branch.summaryRebaseInfix": "буде перебазовано на", - "gitView.branch.summaryRebasePrefix": "Поточна гілка", - "gitView.branch.updateDescriptionPrefix": "Оновити поточну гілку з віддаленої.", + "gitView.branch.summaryMergeInfix": "в", + "gitView.branch.summaryMergePrefix": "Буде злито", + "gitView.branch.summaryRebaseInfix": "на", + "gitView.branch.summaryRebasePrefix": "Буде перебазовано", + "gitView.branch.updateDescriptionPrefix": "Підтягнути останні зміни в", "gitView.branch.updateTitle": "Оновлення гілки", "gitView.changes.changedFilesAria": "Змінені файли", "gitView.changes.clearSelectionAria": "Очистити вибір файлу",