From 31a4fd5b4b3c72cc461a456c73cac250028e0ff1 Mon Sep 17 00:00:00 2001 From: xintaofei Date: Sun, 15 Mar 2026 18:44:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=88=86=E6=94=AF=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=A6=82=E6=9E=9C=E6=8F=90=E7=A4=BA=E5=88=86=E6=94=AF?= =?UTF-8?q?=E6=9C=AA=E5=90=88=E5=B9=B6=E5=AE=8C=E6=88=90=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=BC=BA=E5=88=B6=E5=88=A0=E9=99=A4=EF=BC=8C=E8=80=8C?= =?UTF-8?q?=E4=B8=8D=E6=98=AF=E6=B0=B8=E8=BF=9C=E6=97=A0=E6=B3=95=E5=88=A0?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/layout/branch-dropdown.tsx | 32 ++++++++++++++++++++--- src/i18n/messages/ar.json | 4 ++- src/i18n/messages/de.json | 4 ++- src/i18n/messages/en.json | 4 ++- src/i18n/messages/es.json | 4 ++- src/i18n/messages/fr.json | 4 ++- src/i18n/messages/ja.json | 4 ++- src/i18n/messages/ko.json | 4 ++- src/i18n/messages/pt.json | 4 ++- src/i18n/messages/zh-CN.json | 4 ++- src/i18n/messages/zh-TW.json | 4 ++- 11 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/components/layout/branch-dropdown.tsx b/src/components/layout/branch-dropdown.tsx index cc90d8a..f33a567 100644 --- a/src/components/layout/branch-dropdown.tsx +++ b/src/components/layout/branch-dropdown.tsx @@ -100,7 +100,7 @@ interface BranchDropdownProps { } type ConfirmAction = { - type: "merge" | "rebase" | "delete" + type: "merge" | "rebase" | "delete" | "forceDelete" branchName: string } @@ -189,7 +189,8 @@ export function BranchDropdown({ async function runGitTask( label: string, action: () => Promise, - getSuccessDescription?: (result: T) => string | false | undefined + getSuccessDescription?: (result: T) => string | false | undefined, + onError?: (errorMsg: string) => boolean ) { const taskId = `git-${++taskSeq.current}-${Date.now()}` setLoading(true) @@ -212,8 +213,11 @@ export function BranchDropdown({ } } catch (err) { removeTask(taskId) - const errorTitle = t("toasts.taskFailed", { label }) const errorMsg = toErrorMessage(err) + if (onError?.(errorMsg)) { + return + } + const errorTitle = t("toasts.taskFailed", { label }) pushAlert("error", errorTitle, errorMsg) toast.error(errorTitle, { description: errorMsg }) } finally { @@ -472,8 +476,22 @@ export function BranchDropdown({ ) break case "delete": + await runGitTask( + t("tasks.deleteBranch", { branchName }), + () => gitDeleteBranch(folderPath, branchName), + undefined, + (errorMsg) => { + if (/not fully merged/i.test(errorMsg)) { + setConfirmAction({ type: "forceDelete", branchName }) + return true + } + return false + } + ) + break + case "forceDelete": await runGitTask(t("tasks.deleteBranch", { branchName }), () => - gitDeleteBranch(folderPath, branchName) + gitDeleteBranch(folderPath, branchName, true) ) break } @@ -488,6 +506,8 @@ export function BranchDropdown({ return t("confirm.rebaseTitle") case "delete": return t("confirm.deleteTitle") + case "forceDelete": + return t("confirm.forceDeleteTitle") } } @@ -508,6 +528,10 @@ export function BranchDropdown({ return t("confirm.deleteDescription", { branchName: confirmAction.branchName, }) + case "forceDelete": + return t("confirm.forceDeleteDescription", { + branchName: confirmAction.branchName, + }) } } diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json index 86c9e29..dccbe5b 100644 --- a/src/i18n/messages/ar.json +++ b/src/i18n/messages/ar.json @@ -810,7 +810,9 @@ "deleteTitle": "حذف الفرع", "mergeDescription": "دمج {branchName} في الفرع الحالي {currentBranch}؟", "rebaseDescription": "إجراء rebase للفرع الحالي {currentBranch} على {branchName}؟", - "deleteDescription": "حذف الفرع {branchName}؟ لا يمكن التراجع عن هذا الإجراء." + "deleteDescription": "حذف الفرع {branchName}؟ لا يمكن التراجع عن هذا الإجراء.", + "forceDeleteTitle": "حذف الفرع بالقوة", + "forceDeleteDescription": "الفرع {branchName} لم يتم دمجه بالكامل. هل أنت متأكد من أنك تريد حذفه بالقوة؟ لا يمكن التراجع عن هذا الإجراء." }, "current": "الحالي", "switchToBranch": "التبديل إلى هذا الفرع", diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index 4ffd105..4b59df5 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -810,7 +810,9 @@ "deleteTitle": "Branch löschen", "mergeDescription": "{branchName} in den aktuellen Branch {currentBranch} mergen?", "rebaseDescription": "Aktuellen Branch {currentBranch} auf {branchName} rebasen?", - "deleteDescription": "Branch {branchName} löschen? Diese Aktion kann nicht rückgängig gemacht werden." + "deleteDescription": "Branch {branchName} löschen? Diese Aktion kann nicht rückgängig gemacht werden.", + "forceDeleteTitle": "Branch erzwungen löschen", + "forceDeleteDescription": "Der Branch {branchName} ist nicht vollständig gemergt. Möchten Sie ihn wirklich erzwungen löschen? Diese Aktion kann nicht rückgängig gemacht werden." }, "current": "Aktuell", "switchToBranch": "Zu diesem Branch wechseln", diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index e3a27b0..df464fd 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -810,7 +810,9 @@ "deleteTitle": "Delete branch", "mergeDescription": "Merge {branchName} into current branch {currentBranch}?", "rebaseDescription": "Rebase current branch {currentBranch} onto {branchName}?", - "deleteDescription": "Delete branch {branchName}? This action cannot be undone." + "deleteDescription": "Delete branch {branchName}? This action cannot be undone.", + "forceDeleteTitle": "Force Delete Branch", + "forceDeleteDescription": "Branch {branchName} is not fully merged. Are you sure you want to force delete it? This action cannot be undone." }, "current": "Current", "switchToBranch": "Switch to this branch", diff --git a/src/i18n/messages/es.json b/src/i18n/messages/es.json index 66d2074..d5bc74f 100644 --- a/src/i18n/messages/es.json +++ b/src/i18n/messages/es.json @@ -810,7 +810,9 @@ "deleteTitle": "Eliminar rama", "mergeDescription": "¿Fusionar {branchName} en la rama actual {currentBranch}?", "rebaseDescription": "¿Hacer rebase de la rama actual {currentBranch} sobre {branchName}?", - "deleteDescription": "¿Eliminar la rama {branchName}? Esta acción no se puede deshacer." + "deleteDescription": "¿Eliminar la rama {branchName}? Esta acción no se puede deshacer.", + "forceDeleteTitle": "Forzar eliminación de rama", + "forceDeleteDescription": "La rama {branchName} no está completamente fusionada. ¿Estás seguro de que quieres forzar su eliminación? Esta acción no se puede deshacer." }, "current": "Actual", "switchToBranch": "Cambiar a esta rama", diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index a59c106..49638b5 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -810,7 +810,9 @@ "deleteTitle": "Supprimer la branche", "mergeDescription": "Fusionner {branchName} dans la branche actuelle {currentBranch} ?", "rebaseDescription": "Rebaser la branche actuelle {currentBranch} sur {branchName} ?", - "deleteDescription": "Supprimer la branche {branchName} ? Cette action est irréversible." + "deleteDescription": "Supprimer la branche {branchName} ? Cette action est irréversible.", + "forceDeleteTitle": "Forcer la suppression de la branche", + "forceDeleteDescription": "La branche {branchName} n'est pas entièrement fusionnée. Êtes-vous sûr de vouloir la supprimer de force ? Cette action est irréversible." }, "current": "Actuelle", "switchToBranch": "Basculer vers cette branche", diff --git a/src/i18n/messages/ja.json b/src/i18n/messages/ja.json index b586fc8..e4f9541 100644 --- a/src/i18n/messages/ja.json +++ b/src/i18n/messages/ja.json @@ -810,7 +810,9 @@ "deleteTitle": "ブランチを削除", "mergeDescription": "{branchName} を現在のブランチ {currentBranch} にマージしますか?", "rebaseDescription": "現在のブランチ {currentBranch} を {branchName} にリベースしますか?", - "deleteDescription": "ブランチ {branchName} を削除しますか?この操作は元に戻せません。" + "deleteDescription": "ブランチ {branchName} を削除しますか?この操作は元に戻せません。", + "forceDeleteTitle": "ブランチを強制削除", + "forceDeleteDescription": "ブランチ {branchName} はまだ完全にマージされていません。強制削除してもよろしいですか?この操作は元に戻せません。" }, "current": "現在", "switchToBranch": "このブランチに切り替え", diff --git a/src/i18n/messages/ko.json b/src/i18n/messages/ko.json index 61dc73f..c1274e0 100644 --- a/src/i18n/messages/ko.json +++ b/src/i18n/messages/ko.json @@ -810,7 +810,9 @@ "deleteTitle": "브랜치 삭제", "mergeDescription": "{branchName}을(를) 현재 브랜치 {currentBranch}에 병합할까요?", "rebaseDescription": "현재 브랜치 {currentBranch}를 {branchName} 위로 리베이스할까요?", - "deleteDescription": "브랜치 {branchName}을(를) 삭제할까요? 이 작업은 되돌릴 수 없습니다." + "deleteDescription": "브랜치 {branchName}을(를) 삭제할까요? 이 작업은 되돌릴 수 없습니다.", + "forceDeleteTitle": "브랜치 강제 삭제", + "forceDeleteDescription": "브랜치 {branchName}가 완전히 병합되지 않았습니다. 강제 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다." }, "current": "현재", "switchToBranch": "이 브랜치로 전환", diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json index deaae83..bf1c72f 100644 --- a/src/i18n/messages/pt.json +++ b/src/i18n/messages/pt.json @@ -810,7 +810,9 @@ "deleteTitle": "Excluir branch", "mergeDescription": "Mesclar {branchName} na branch atual {currentBranch}?", "rebaseDescription": "Fazer rebase da branch atual {currentBranch} sobre {branchName}?", - "deleteDescription": "Excluir a branch {branchName}? Esta ação não pode ser desfeita." + "deleteDescription": "Excluir a branch {branchName}? Esta ação não pode ser desfeita.", + "forceDeleteTitle": "Forçar exclusão do branch", + "forceDeleteDescription": "O branch {branchName} não está totalmente mesclado. Tem certeza de que deseja forçar a exclusão? Esta ação não pode ser desfeita." }, "current": "Atual", "switchToBranch": "Mudar para esta branch", diff --git a/src/i18n/messages/zh-CN.json b/src/i18n/messages/zh-CN.json index 9e46c54..d2b5951 100644 --- a/src/i18n/messages/zh-CN.json +++ b/src/i18n/messages/zh-CN.json @@ -810,7 +810,9 @@ "deleteTitle": "删除分支", "mergeDescription": "确定将 {branchName} 合并到当前分支 {currentBranch} 吗?", "rebaseDescription": "确定将当前分支 {currentBranch} 变基到 {branchName} 吗?", - "deleteDescription": "确定删除分支 {branchName} 吗?此操作不可恢复。" + "deleteDescription": "确定删除分支 {branchName} 吗?此操作不可恢复。", + "forceDeleteTitle": "强制删除分支", + "forceDeleteDescription": "分支 {branchName} 尚未完全合并,确定要强制删除吗?此操作不可恢复。" }, "current": "当前", "switchToBranch": "切换到此分支", diff --git a/src/i18n/messages/zh-TW.json b/src/i18n/messages/zh-TW.json index 14dd0bf..86f2b62 100644 --- a/src/i18n/messages/zh-TW.json +++ b/src/i18n/messages/zh-TW.json @@ -810,7 +810,9 @@ "deleteTitle": "刪除分支", "mergeDescription": "確定將 {branchName} 合併到目前分支 {currentBranch} 嗎?", "rebaseDescription": "確定將目前分支 {currentBranch} 變基到 {branchName} 嗎?", - "deleteDescription": "確定刪除分支 {branchName} 嗎?此操作無法復原。" + "deleteDescription": "確定刪除分支 {branchName} 嗎?此操作無法復原。", + "forceDeleteTitle": "強制刪除分支", + "forceDeleteDescription": "分支 {branchName} 尚未完全合併,確定要強制刪除嗎?此操作不可恢復。" }, "current": "目前", "switchToBranch": "切換到此分支",