From 50c5b12d53ed428c8360582b80e012625e4ef4f0 Mon Sep 17 00:00:00 2001 From: xintaofei Date: Thu, 23 Apr 2026 14:02:46 +0800 Subject: [PATCH] refactor(branch-dropdown): drop worktree parent-branch merge shortcut Remove the parent-branch button shown beside the branch selector along with its supporting API, command, service, model, and i18n strings. Add migration m20260423 to drop the now-unused folder.parent_branch column. --- src-tauri/src/commands/folders.rs | 35 +------------------ src-tauri/src/db/entities/folder.rs | 1 - ...260423_000001_drop_folder_parent_branch.rs | 35 +++++++++++++++++++ src-tauri/src/db/migration/mod.rs | 2 ++ src-tauri/src/db/service/folder_service.rs | 18 ---------- src-tauri/src/lib.rs | 1 - src-tauri/src/models/folder.rs | 1 - src-tauri/src/web/handlers/folders.rs | 17 --------- src-tauri/src/web/router.rs | 4 --- src/components/layout/branch-dropdown.tsx | 21 ----------- src/i18n/messages/ar.json | 1 - src/i18n/messages/de.json | 1 - src/i18n/messages/en.json | 1 - src/i18n/messages/es.json | 1 - src/i18n/messages/fr.json | 1 - src/i18n/messages/ja.json | 1 - src/i18n/messages/ko.json | 1 - src/i18n/messages/pt.json | 1 - src/i18n/messages/zh-CN.json | 1 - src/i18n/messages/zh-TW.json | 1 - src/lib/api.ts | 10 ------ src/lib/tauri.ts | 10 ------ src/lib/types.ts | 1 - 23 files changed, 38 insertions(+), 128 deletions(-) create mode 100644 src-tauri/src/db/migration/m20260423_000001_drop_folder_parent_branch.rs diff --git a/src-tauri/src/commands/folders.rs b/src-tauri/src/commands/folders.rs index 179f074..2b1c8a5 100644 --- a/src-tauri/src/commands/folders.rs +++ b/src-tauri/src/commands/folders.rs @@ -19,6 +19,7 @@ use tauri::Manager; use crate::app_error::AppCommandError; #[cfg(feature = "tauri-runtime")] use crate::db::error::DbError; +#[cfg(feature = "tauri-runtime")] use crate::db::service::folder_service; use crate::db::AppDatabase; use crate::models::GitCredentials; @@ -479,40 +480,6 @@ pub async fn add_folder_to_history( folder_service::add_folder(&db.conn, &path).await } -pub(crate) async fn set_folder_parent_branch_core( - conn: &sea_orm::DatabaseConnection, - path: &str, - parent_branch: Option, -) -> Result<(), AppCommandError> { - use crate::db::entities::folder; - use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; - let row = folder::Entity::find() - .filter(folder::Column::Path.eq(path)) - .filter(folder::Column::DeletedAt.is_null()) - .one(conn) - .await - .map_err(|e| { - AppCommandError::database_error("Failed to query folder").with_detail(e.to_string()) - })?; - - if let Some(folder_model) = row { - folder_service::set_folder_parent_branch(conn, folder_model.id, parent_branch) - .await - .map_err(AppCommandError::from)?; - } - Ok(()) -} - -#[cfg(feature = "tauri-runtime")] -#[cfg_attr(feature = "tauri-runtime", tauri::command)] -pub async fn set_folder_parent_branch( - db: tauri::State<'_, AppDatabase>, - path: String, - parent_branch: Option, -) -> Result<(), AppCommandError> { - set_folder_parent_branch_core(&db.conn, &path, parent_branch).await -} - #[cfg(feature = "tauri-runtime")] #[cfg_attr(feature = "tauri-runtime", tauri::command)] pub async fn remove_folder_from_history( diff --git a/src-tauri/src/db/entities/folder.rs b/src-tauri/src/db/entities/folder.rs index f4fd9a9..bc798c6 100644 --- a/src-tauri/src/db/entities/folder.rs +++ b/src-tauri/src/db/entities/folder.rs @@ -15,7 +15,6 @@ pub struct Model { pub updated_at: DateTimeUtc, pub deleted_at: Option, pub is_open: bool, - pub parent_branch: Option, pub sort_order: i32, } diff --git a/src-tauri/src/db/migration/m20260423_000001_drop_folder_parent_branch.rs b/src-tauri/src/db/migration/m20260423_000001_drop_folder_parent_branch.rs new file mode 100644 index 0000000..4ff73c5 --- /dev/null +++ b/src-tauri/src/db/migration/m20260423_000001_drop_folder_parent_branch.rs @@ -0,0 +1,35 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Folder::Table) + .drop_column(Folder::ParentBranch) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Folder::Table) + .add_column(ColumnDef::new(Folder::ParentBranch).string().null()) + .to_owned(), + ) + .await + } +} + +#[derive(DeriveIden)] +enum Folder { + Table, + ParentBranch, +} diff --git a/src-tauri/src/db/migration/mod.rs b/src-tauri/src/db/migration/mod.rs index 316d0fb..74aece2 100644 --- a/src-tauri/src/db/migration/mod.rs +++ b/src-tauri/src/db/migration/mod.rs @@ -11,6 +11,7 @@ mod m20260404_000001_model_provider; mod m20260406_000001_agent_setting_model_provider; mod m20260420_000001_opened_tabs; mod m20260422_000001_folder_sort_order; +mod m20260423_000001_drop_folder_parent_branch; pub struct Migrator; #[async_trait::async_trait] @@ -28,6 +29,7 @@ impl MigratorTrait for Migrator { Box::new(m20260406_000001_agent_setting_model_provider::Migration), Box::new(m20260420_000001_opened_tabs::Migration), Box::new(m20260422_000001_folder_sort_order::Migration), + Box::new(m20260423_000001_drop_folder_parent_branch::Migration), ] } } diff --git a/src-tauri/src/db/service/folder_service.rs b/src-tauri/src/db/service/folder_service.rs index 6023b40..4b2efcb 100644 --- a/src-tauri/src/db/service/folder_service.rs +++ b/src-tauri/src/db/service/folder_service.rs @@ -31,7 +31,6 @@ fn to_detail(m: folder::Model) -> FolderDetail { name: m.name, path: m.path, git_branch: m.git_branch, - parent_branch: m.parent_branch, default_agent_type, last_opened_at: m.last_opened_at, sort_order: m.sort_order, @@ -85,7 +84,6 @@ pub async fn add_folder( name: Set(name), path: Set(path.to_string()), git_branch: Set(None), - parent_branch: Set(None), default_agent_type: Set(None), last_opened_at: Set(now), created_at: Set(now), @@ -127,22 +125,6 @@ pub async fn remove_folder(conn: &DatabaseConnection, path: &str) -> Result<(), Ok(()) } -pub async fn set_folder_parent_branch( - conn: &DatabaseConnection, - folder_id: i32, - parent_branch: Option, -) -> Result<(), DbError> { - let row = folder::Entity::find_by_id(folder_id).one(conn).await?; - - if let Some(row) = row { - let mut active = row.into_active_model(); - active.parent_branch = Set(parent_branch); - active.updated_at = Set(Utc::now()); - active.update(conn).await?; - } - Ok(()) -} - pub async fn set_folder_open( conn: &DatabaseConnection, folder_id: i32, diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 729fe21..c2ae83d 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -225,7 +225,6 @@ mod tauri_app { folders::remove_folder_from_workspace, folders::reorder_folders, folders::add_folder_to_history, - folders::set_folder_parent_branch, folders::remove_folder_from_history, folders::create_folder_directory, folders::clone_repository, diff --git a/src-tauri/src/models/folder.rs b/src-tauri/src/models/folder.rs index ff03cd7..5910beb 100644 --- a/src-tauri/src/models/folder.rs +++ b/src-tauri/src/models/folder.rs @@ -17,7 +17,6 @@ pub struct FolderDetail { pub name: String, pub path: String, pub git_branch: Option, - pub parent_branch: Option, pub default_agent_type: Option, pub last_opened_at: DateTime, pub sort_order: i32, diff --git a/src-tauri/src/web/handlers/folders.rs b/src-tauri/src/web/handlers/folders.rs index 6bae498..f8c4195 100644 --- a/src-tauri/src/web/handlers/folders.rs +++ b/src-tauri/src/web/handlers/folders.rs @@ -287,13 +287,6 @@ pub async fn open_push_window( })) } -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SetFolderParentBranchParams { - pub path: String, - pub parent_branch: Option, -} - pub async fn add_folder_to_history( Extension(state): Extension>, Json(params): Json, @@ -305,16 +298,6 @@ pub async fn add_folder_to_history( Ok(Json(result)) } -pub async fn set_folder_parent_branch( - Extension(state): Extension>, - Json(params): Json, -) -> Result, AppCommandError> { - let db = &state.db; - folder_commands::set_folder_parent_branch_core(&db.conn, ¶ms.path, params.parent_branch) - .await?; - Ok(Json(())) -} - pub async fn remove_folder_from_history( Extension(state): Extension>, Json(params): Json, diff --git a/src-tauri/src/web/router.rs b/src-tauri/src/web/router.rs index ca2b9d8..1cda392 100644 --- a/src-tauri/src/web/router.rs +++ b/src-tauri/src/web/router.rs @@ -114,10 +114,6 @@ pub fn build_router(state: Arc, token: String, static_dir: std::path:: "/add_folder_to_history", post(handlers::folders::add_folder_to_history), ) - .route( - "/set_folder_parent_branch", - post(handlers::folders::set_folder_parent_branch), - ) .route( "/remove_folder_from_history", post(handlers::folders::remove_folder_from_history), diff --git a/src/components/layout/branch-dropdown.tsx b/src/components/layout/branch-dropdown.tsx index 032f4c6..c62ebab 100644 --- a/src/components/layout/branch-dropdown.tsx +++ b/src/components/layout/branch-dropdown.tsx @@ -5,7 +5,6 @@ import { ArchiveRestore, Archive, ArrowDownToLine, - ArrowLeftRight, ChevronDown, ChevronRight, FolderGit2, @@ -77,7 +76,6 @@ import { openCommitWindow, openPushWindow, openStashWindow, - setFolderParentBranch, } from "@/lib/api" import { openFileDialog, subscribe } from "@/lib/platform" import { RemoteManageDialog } from "@/components/layout/remote-manage-dialog" @@ -130,7 +128,6 @@ export function BranchDropdown() { const branch = activeFolder ? (branches.get(activeFolder.id) ?? activeFolder.git_branch ?? null) : null - const parentBranch = activeFolder?.parent_branch ?? null const [branchList, setBranchList] = useState({ local: [], @@ -349,15 +346,9 @@ export function BranchDropdown() { await runGitTask(t("tasks.newWorktree", { name }), async () => { await gitWorktreeAdd(folderPath, name, wtPath) await openFolder(wtPath) - await setFolderParentBranch(wtPath, branch) }) } - function handleMergeParent() { - if (!parentBranch) return - setConfirmAction({ type: "merge", branchName: parentBranch }) - } - async function handleConfirm() { if (!confirmAction) return const { type, branchName } = confirmAction @@ -818,18 +809,6 @@ export function BranchDropdown() { - {parentBranch && ( - - )} - { diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json index b30e7c4..9c0017c 100644 --- a/src/i18n/messages/ar.json +++ b/src/i18n/messages/ar.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "لا توجد فروع محلية", "remoteBranches": "الفروع البعيدة ({count, plural, one {#} other {#}})", "noRemoteBranches": "لا توجد فروع بعيدة", - "parentBranchHint": "تم إنشاء الفرع الحالي من {parentBranch}. انقر لدمج {parentBranch} في الفرع الحالي.", "dialogs": { "newBranchTitle": "فرع جديد", "newBranchDescription": "إنشاء فرع جديد من الفرع الحالي {branch}", diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index 4903356..636302d 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "Keine lokalen Branches", "remoteBranches": "Remote-Branches ({count, plural, one {#} other {#}})", "noRemoteBranches": "Keine Remote-Branches", - "parentBranchHint": "Der aktuelle Branch wurde von {parentBranch} erstellt. Klicken, um {parentBranch} in den aktuellen Branch zu mergen.", "dialogs": { "newBranchTitle": "Neuer Branch", "newBranchDescription": "Neuen Branch vom aktuellen Branch {branch} erstellen", diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index cfca612..6929fd3 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "No local branches", "remoteBranches": "Remote branches ({count, plural, one {#} other {#}})", "noRemoteBranches": "No remote branches", - "parentBranchHint": "Current branch was created from {parentBranch}. Click to merge {parentBranch} into current branch.", "dialogs": { "newBranchTitle": "New branch", "newBranchDescription": "Create a new branch from current branch {branch}", diff --git a/src/i18n/messages/es.json b/src/i18n/messages/es.json index ad3f10c..71add80 100644 --- a/src/i18n/messages/es.json +++ b/src/i18n/messages/es.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "Sin ramas locales", "remoteBranches": "Ramas remotas ({count, plural, one {#} other {#}})", "noRemoteBranches": "Sin ramas remotas", - "parentBranchHint": "La rama actual fue creada desde {parentBranch}. Haz clic para fusionar {parentBranch} en la rama actual.", "dialogs": { "newBranchTitle": "Nueva rama", "newBranchDescription": "Crear una nueva rama desde la rama actual {branch}", diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index 699f8a0..6242cc1 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "Aucune branche locale", "remoteBranches": "Branches distantes ({count, plural, one {#} other {#}})", "noRemoteBranches": "Aucune branche distante", - "parentBranchHint": "La branche actuelle a été créée depuis {parentBranch}. Cliquez pour fusionner {parentBranch} dans la branche actuelle.", "dialogs": { "newBranchTitle": "Nouvelle branche", "newBranchDescription": "Créer une nouvelle branche depuis la branche actuelle {branch}", diff --git a/src/i18n/messages/ja.json b/src/i18n/messages/ja.json index d44b59a..1f287a1 100644 --- a/src/i18n/messages/ja.json +++ b/src/i18n/messages/ja.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "ローカルブランチはありません", "remoteBranches": "リモートブランチ ({count, plural, one {#} other {#}})", "noRemoteBranches": "リモートブランチはありません", - "parentBranchHint": "現在のブランチは {parentBranch} から作成されました。クリックして {parentBranch} を現在のブランチにマージします。", "dialogs": { "newBranchTitle": "新規ブランチ", "newBranchDescription": "現在のブランチ {branch} から新しいブランチを作成", diff --git a/src/i18n/messages/ko.json b/src/i18n/messages/ko.json index c22a1ac..61a9902 100644 --- a/src/i18n/messages/ko.json +++ b/src/i18n/messages/ko.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "로컬 브랜치가 없습니다", "remoteBranches": "원격 브랜치 ({count, plural, one {#} other {#}})", "noRemoteBranches": "원격 브랜치가 없습니다", - "parentBranchHint": "현재 브랜치는 {parentBranch}에서 생성되었습니다. 클릭하여 {parentBranch}를 현재 브랜치에 병합하세요.", "dialogs": { "newBranchTitle": "새 브랜치", "newBranchDescription": "현재 브랜치 {branch}에서 새 브랜치를 만듭니다", diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json index ef35602..d58db4a 100644 --- a/src/i18n/messages/pt.json +++ b/src/i18n/messages/pt.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "Sem branches locais", "remoteBranches": "Branches remotas ({count, plural, one {#} other {#}})", "noRemoteBranches": "Sem branches remotas", - "parentBranchHint": "A branch atual foi criada a partir de {parentBranch}. Clique para mesclar {parentBranch} na branch atual.", "dialogs": { "newBranchTitle": "Nova branch", "newBranchDescription": "Criar uma nova branch a partir da branch atual {branch}", diff --git a/src/i18n/messages/zh-CN.json b/src/i18n/messages/zh-CN.json index 9c19e9a..3f34fac 100644 --- a/src/i18n/messages/zh-CN.json +++ b/src/i18n/messages/zh-CN.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "无本地分支", "remoteBranches": "远程分支 ({count})", "noRemoteBranches": "无远程分支", - "parentBranchHint": "当前分支从 {parentBranch} 创建,点击合并 {parentBranch} 到当前分支", "dialogs": { "newBranchTitle": "新建分支", "newBranchDescription": "从当前分支 {branch} 创建新分支", diff --git a/src/i18n/messages/zh-TW.json b/src/i18n/messages/zh-TW.json index fc4880c..a7cec71 100644 --- a/src/i18n/messages/zh-TW.json +++ b/src/i18n/messages/zh-TW.json @@ -1082,7 +1082,6 @@ "noLocalBranches": "無本地分支", "remoteBranches": "遠端分支 ({count})", "noRemoteBranches": "無遠端分支", - "parentBranchHint": "目前分支從 {parentBranch} 建立,點擊合併 {parentBranch} 到目前分支", "dialogs": { "newBranchTitle": "新增分支", "newBranchDescription": "從目前分支 {branch} 建立新分支", diff --git a/src/lib/api.ts b/src/lib/api.ts index e6d5c42..f982e27 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -656,16 +656,6 @@ export async function getFolderConversation( return getTransport().call("get_folder_conversation", { conversationId }) } -export async function setFolderParentBranch( - path: string, - parentBranch: string | null -): Promise { - return getTransport().call("set_folder_parent_branch", { - path, - parentBranch, - }) -} - export async function removeFolderFromHistory(path: string): Promise { return getTransport().call("remove_folder_from_history", { path }) } diff --git a/src/lib/tauri.ts b/src/lib/tauri.ts index 9697e1f..c53be36 100644 --- a/src/lib/tauri.ts +++ b/src/lib/tauri.ts @@ -524,16 +524,6 @@ export async function getFolderConversation( return invoke("get_folder_conversation", { conversationId }) } -export async function setFolderParentBranch( - path: string, - parentBranch: string | null -): Promise { - return invoke("set_folder_parent_branch", { - path, - parentBranch, - }) -} - export async function removeFolderFromHistory(path: string): Promise { return invoke("remove_folder_from_history", { path }) } diff --git a/src/lib/types.ts b/src/lib/types.ts index afdebfd..749f67a 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -160,7 +160,6 @@ export interface FolderDetail { name: string path: string git_branch: string | null - parent_branch: string | null default_agent_type: AgentType | null last_opened_at: string sort_order: number