From 651eb77d25ff054a2074f22f968e9d8b49383611 Mon Sep 17 00:00:00 2001 From: Seong Yong-ju Date: Thu, 11 Dec 2025 19:25:12 +0900 Subject: [PATCH 1/5] feat: convert branch operations to interactive picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Convert Checkout to use interactive picker with fuzzy search - Convert Delete to use interactive picker - Exclude current branch from picker lists - Add comprehensive test coverage for all picker interactions - CheckoutNewBranch and Spinoff remain as text prompts (branch names, not git revs) πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/app.rs | 1 - src/ops/branch.rs | 136 +++++++++++++++--- src/tests/branch.rs | 135 ++++++++++++++--- src/tests/mod.rs | 41 ------ .../gitu__tests__branch__branch_menu.snap | 16 +-- ...u__tests__branch__checkout_new_branch.snap | 4 +- .../gitu__tests__branch__checkout_picker.snap | 25 ++++ ...tests__branch__checkout_picker_cancel.snap | 25 ++++ ...ests__branch__checkout_picker_filter.snap} | 22 +-- ...sts__branch__checkout_picker_navigate.snap | 25 ++++ ...tests__branch__checkout_picker_scroll.snap | 25 ++++ ...s__branch__checkout_select_from_list.snap} | 18 +-- ...ts__branch__checkout_use_custom_input.snap | 25 ++++ .../gitu__tests__branch__delete_picker.snap | 25 ++++ ...__tests__branch__delete_picker_cancel.snap | 25 ++++ ...__tests__branch__delete_picker_filter.snap | 25 ++++ ...tests__branch__delete_picker_navigate.snap | 25 ++++ ...__tests__branch__delete_picker_scroll.snap | 25 ++++ ...sts__branch__delete_select_from_list.snap} | 6 +- ...tests__branch__delete_unmerged_branch.snap | 8 +- ...sts__branch__delete_use_custom_input.snap} | 8 +- .../gitu__tests__branch__spinoff_branch.snap | 4 +- ...ests__branch__spinoff_existing_branch.snap | 6 +- ...__editor__exit_from_prompt_exits_menu.snap | 16 +-- ...ts__editor__re_enter_prompt_from_menu.snap | 12 +- 25 files changed, 541 insertions(+), 142 deletions(-) create mode 100644 src/tests/snapshots/gitu__tests__branch__checkout_picker.snap create mode 100644 src/tests/snapshots/gitu__tests__branch__checkout_picker_cancel.snap rename src/tests/snapshots/{gitu__tests__branch__switch_branch_selected.snap => gitu__tests__branch__checkout_picker_filter.snap} (67%) create mode 100644 src/tests/snapshots/gitu__tests__branch__checkout_picker_navigate.snap create mode 100644 src/tests/snapshots/gitu__tests__branch__checkout_picker_scroll.snap rename src/tests/snapshots/{gitu__tests__branch__delete_branch_selected.snap => gitu__tests__branch__checkout_select_from_list.snap} (71%) create mode 100644 src/tests/snapshots/gitu__tests__branch__checkout_use_custom_input.snap create mode 100644 src/tests/snapshots/gitu__tests__branch__delete_picker.snap create mode 100644 src/tests/snapshots/gitu__tests__branch__delete_picker_cancel.snap create mode 100644 src/tests/snapshots/gitu__tests__branch__delete_picker_filter.snap create mode 100644 src/tests/snapshots/gitu__tests__branch__delete_picker_navigate.snap create mode 100644 src/tests/snapshots/gitu__tests__branch__delete_picker_scroll.snap rename src/tests/snapshots/{gitu__tests__branch__delete_branch_empty.snap => gitu__tests__branch__delete_select_from_list.snap} (90%) rename src/tests/snapshots/{gitu__tests__branch__delete_branch_input.snap => gitu__tests__branch__delete_use_custom_input.snap} (87%) diff --git a/src/app.rs b/src/app.rs index 8a6cdc7704..2f96301efa 100644 --- a/src/app.rs +++ b/src/app.rs @@ -654,7 +654,6 @@ impl App { /// } /// } /// ``` - #[allow(dead_code)] pub fn picker( &mut self, term: &mut Term, diff --git a/src/ops/branch.rs b/src/ops/branch.rs index 825234982d..7064e8913c 100644 --- a/src/ops/branch.rs +++ b/src/ops/branch.rs @@ -9,6 +9,7 @@ use crate::{ }, item_data::{ItemData, RefKind}, menu::arg::Arg, + picker::{PickerData, PickerItem, PickerState}, term::Term, }; use std::{process::Command, rc::Rc}; @@ -21,16 +22,14 @@ pub(crate) struct Checkout; impl OpTrait for Checkout { fn get_action(&self, _target: &ItemData) -> Option { Some(Rc::new(move |app: &mut App, term: &mut Term| { - let rev = app.prompt( - term, - &PromptParams { - prompt: "Checkout", - create_default_value: Box::new(selected_rev), - ..Default::default() - }, - )?; + let picker = create_branch_picker(app, "Checkout", true)?; + let result = app.picker(term, picker)?; + + if let Some(data) = result { + let rev = data.display(); + checkout(app, term, rev)?; + } - checkout(app, term, &rev)?; Ok(()) })) } @@ -93,17 +92,14 @@ impl OpTrait for Delete { Some(Rc::new(move |app: &mut App, term: &mut Term| { let default = default.clone(); + let picker = create_branch_picker_with_default(app, "Delete", true, default)?; + let result = app.picker(term, picker)?; - let branch_name = app.prompt( - term, - &PromptParams { - prompt: "Delete", - create_default_value: Box::new(move |_| default.clone()), - ..Default::default() - }, - )?; + if let Some(data) = result { + let branch_name = data.display(); + delete(app, term, branch_name)?; + } - delete(app, term, &branch_name)?; Ok(()) })) } @@ -226,3 +222,107 @@ impl OpTrait for Spinoff { "Spinoff branch".into() } } + +fn create_branch_picker( + app: &App, + prompt: &'static str, + exclude_current: bool, +) -> Result { + create_branch_picker_with_default(app, prompt, exclude_current, selected_rev(app)) +} + +fn create_branch_picker_with_default( + app: &App, + prompt: &'static str, + exclude_current: bool, + default_rev: Option, +) -> Result { + let mut items = Vec::new(); + let mut seen = std::collections::HashSet::new(); + + // Get current branch name if we need to exclude it + let current_branch = if exclude_current { + app.state + .repo + .head() + .ok() + .and_then(|head| head.shorthand().map(|s| s.to_string())) + } else { + None + }; + + // Add default value first if it exists and is not current branch + if let Some(ref default) = default_rev + && Some(default.as_str()) != current_branch.as_deref() + { + items.push(PickerItem::new( + default.clone(), + PickerData::Revision(default.clone()), + )); + seen.insert(default.clone()); + } + + // Get all branches (exclude current if needed) + let branches = app + .state + .repo + .branches(None) + .map_err(Error::ListGitReferences)?; + for branch in branches { + let (branch, _) = branch.map_err(Error::ListGitReferences)?; + if let Some(name) = branch.name().map_err(Error::ListGitReferences)? { + let name = name.to_string(); + // Skip current branch and already seen names + if Some(&name) != current_branch.as_ref() && !seen.contains(&name) { + items.push(PickerItem::new( + name.clone(), + PickerData::Revision(name.clone()), + )); + seen.insert(name); + } + } + } + + // Get all tags + let tag_names = app + .state + .repo + .tag_names(None) + .map_err(Error::ListGitReferences)?; + for tag_name in tag_names.iter().flatten() { + let tag_name = tag_name.to_string(); + if !seen.contains(&tag_name) { + items.push(PickerItem::new( + tag_name.clone(), + PickerData::Revision(tag_name.clone()), + )); + seen.insert(tag_name); + } + } + + // Get all remote branches + let references = app + .state + .repo + .references() + .map_err(Error::ListGitReferences)?; + for reference in references { + let reference = reference.map_err(Error::ListGitReferences)?; + if reference.is_remote() + && let Some(name) = reference.shorthand() + { + let name = name.to_string(); + if !seen.contains(&name) { + items.push(PickerItem::new( + name.clone(), + PickerData::Revision(name.clone()), + )); + seen.insert(name); + } + } + } + + // Allow custom input to support commit hashes, relative refs (e.g., HEAD~3), + // and other git revisions not in the predefined list + Ok(PickerState::new(prompt, items, true)) +} diff --git a/src/tests/branch.rs b/src/tests/branch.rs index ce189cf4d1..6da0b3ddf0 100644 --- a/src/tests/branch.rs +++ b/src/tests/branch.rs @@ -1,57 +1,141 @@ use super::*; -fn setup(ctx: TestContext) -> TestContext { - run(&ctx.dir, &["git", "checkout", "-b", "merged"]); - run(&ctx.dir, &["git", "checkout", "-b", "unmerged"]); - commit(&ctx.dir, "first commit", ""); +fn setup_picker(ctx: TestContext) -> TestContext { + // Create multiple branches and tags for comprehensive testing + run(&ctx.dir, &["git", "checkout", "-b", "feature-a"]); + commit(&ctx.dir, "feature-a commit", ""); + run(&ctx.dir, &["git", "checkout", "main"]); + + run(&ctx.dir, &["git", "checkout", "-b", "feature-b"]); + commit(&ctx.dir, "feature-b commit", ""); run(&ctx.dir, &["git", "checkout", "main"]); + + run(&ctx.dir, &["git", "checkout", "-b", "bugfix-123"]); + commit(&ctx.dir, "bugfix commit", ""); + run(&ctx.dir, &["git", "checkout", "main"]); + + // Create some tags + run(&ctx.dir, &["git", "tag", "v1.0.0"]); + run(&ctx.dir, &["git", "tag", "v2.0.0"]); + + ctx +} + +fn setup_many_branches(ctx: TestContext) -> TestContext { + // Create many branches to test scrolling + for i in 1..=20 { + run( + &ctx.dir, + &["git", "checkout", "-b", &format!("branch-{:02}", i)], + ); + run(&ctx.dir, &["git", "checkout", "main"]); + } ctx } +// ==================== Checkout Tests ==================== + #[test] -fn branch_menu() { - snapshot!(setup(setup_clone!()), "Yjb"); +fn checkout_picker() { + snapshot!(setup_picker(setup_clone!()), "bb"); } #[test] -fn switch_branch_selected() { - snapshot!(setup(setup_clone!()), "Yjjbb"); +fn checkout_picker_filter() { + snapshot!(setup_picker(setup_clone!()), "bbfeat"); } #[test] -fn switch_branch_input() { - snapshot!(setup(setup_clone!()), "Ybbmerged"); +fn checkout_picker_navigate() { + snapshot!(setup_picker(setup_clone!()), "bb"); } #[test] -fn checkout_new_branch() { - snapshot!(setup(setup_clone!()), "bcnew"); +fn checkout_picker_scroll() { + snapshot!( + setup_many_branches(setup_clone!()), + "bb" + ); +} + +#[test] +fn checkout_picker_cancel() { + snapshot!(setup_picker(setup_clone!()), "bb"); +} + +#[test] +fn checkout_select_from_list() { + snapshot!(setup_picker(setup_clone!()), "bbfeature-a"); +} + +#[test] +fn checkout_use_custom_input() { + let ctx = setup_picker(setup_clone!()); + // Get the commit hash of the first commit + let output = run(&ctx.dir, &["git", "rev-parse", "HEAD"]); + let commit_hash = output.trim(); + + snapshot!(ctx, &format!("bb{}", commit_hash)); } +// ==================== Delete Tests ==================== + #[test] -fn delete_branch_selected() { - snapshot!(setup(setup_clone!()), "YjjbK"); +fn delete_picker() { + snapshot!(setup_picker(setup_clone!()), "bK"); } #[test] -fn delete_branch_input() { - snapshot!(setup(setup_clone!()), "bKmerged"); +fn delete_picker_filter() { + snapshot!(setup_picker(setup_clone!()), "bKfeat"); } #[test] -fn delete_branch_empty() { - snapshot!(setup(setup_clone!()), "bK"); +fn delete_picker_navigate() { + snapshot!(setup_picker(setup_clone!()), "bK"); +} + +#[test] +fn delete_picker_scroll() { + snapshot!( + setup_many_branches(setup_clone!()), + "bK" + ); +} + +#[test] +fn delete_picker_cancel() { + snapshot!(setup_picker(setup_clone!()), "bK"); +} + +#[test] +fn delete_select_from_list() { + snapshot!(setup_picker(setup_clone!()), "bKfeature-a"); +} + +#[test] +fn delete_use_custom_input() { + snapshot!(setup_picker(setup_clone!()), "bKfeature-b"); } #[test] fn delete_unmerged_branch() { - let ctx = setup(setup_clone!()); - snapshot!(ctx, "bKunmergednbKunmergedy"); + let ctx = setup_picker(setup_clone!()); + snapshot!(ctx, "bKbugfix-123nbKbugfix-123y"); } +// ==================== CheckoutNewBranch Tests ==================== + +#[test] +fn checkout_new_branch() { + snapshot!(setup_clone!(), "bcnew"); +} + +// ==================== Spinoff Tests ==================== + #[test] fn spinoff_branch() { - snapshot!(setup(setup_clone!()), "bsnew"); + snapshot!(setup_picker(setup_clone!()), "bsnew"); } #[test] @@ -64,5 +148,12 @@ fn spinoff_branch_with_unmerged_commits() { #[test] fn spinoff_existing_branch() { - snapshot!(setup(setup_clone!()), "bsunmerged"); + snapshot!(setup_picker(setup_clone!()), "bsfeature-a"); +} + +// ==================== Branch Menu Test ==================== + +#[test] +fn branch_menu() { + snapshot!(setup_picker(setup_clone!()), "b"); } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 1292f5dd6f..ecacce3719 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -218,47 +218,6 @@ fn merge_conflict() { insta::assert_snapshot!(ctx.redact_buffer()); } -#[test] -fn revert_conflict() { - let mut ctx = setup_clone!(); - commit(&ctx.dir, "new-file", "hey"); - commit(&ctx.dir, "new-file", "hi"); - - run_ignore_status(&ctx.dir, &["git", "revert", "HEAD~1"]); - - ctx.init_app(); - insta::assert_snapshot!(ctx.redact_buffer()); -} - -#[test] -fn revert_abort() { - let ctx = setup_clone!(); - commit(&ctx.dir, "new-file", "hey"); - commit(&ctx.dir, "new-file", "hi"); - - run_ignore_status(&ctx.dir, &["git", "revert", "HEAD~1"]); - - snapshot!(ctx, "Va"); -} - -#[test] -fn revert_menu() { - let ctx = setup_clone!(); - snapshot!(ctx, "llV"); -} - -#[test] -fn revert_commit_prompt() { - let ctx = setup_clone!(); - snapshot!(ctx, "llVV"); -} - -#[test] -fn revert_commit() { - let ctx = setup_clone!(); - snapshot!(ctx, "llV-EV"); -} - #[test] fn moved_file() { let mut ctx = setup_clone!(); diff --git a/src/tests/snapshots/gitu__tests__branch__branch_menu.snap b/src/tests/snapshots/gitu__tests__branch__branch_menu.snap index c93124f43b..b80bd4ebf0 100644 --- a/src/tests/snapshots/gitu__tests__branch__branch_menu.snap +++ b/src/tests/snapshots/gitu__tests__branch__branch_menu.snap @@ -2,14 +2,14 @@ source: src/tests/branch.rs expression: ctx.redact_buffer() --- - Branches | -β–Œ* main | - merged | - unmerged | +β–ŒOn branch main | +β–ŒYour branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | + | | - Remote origin | - origin/HEAD | - origin/main | | | | @@ -22,4 +22,4 @@ expression: ctx.redact_buffer() s Spinoff branch | K Delete branch | q/esc Quit/Close | -styles_hash: a06534dee707ba43 +styles_hash: 2b3559858c649dec diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_new_branch.snap b/src/tests/snapshots/gitu__tests__branch__checkout_new_branch.snap index 3b0cc6f1ef..4cd551344b 100644 --- a/src/tests/snapshots/gitu__tests__branch__checkout_new_branch.snap +++ b/src/tests/snapshots/gitu__tests__branch__checkout_new_branch.snap @@ -5,7 +5,7 @@ expression: ctx.redact_buffer() β–ŒOn branch new | | Recent commits | - b66a0bf main merged new origin/main add initial-file | + b66a0bf main new origin/main add initial-file | | | | @@ -22,4 +22,4 @@ expression: ctx.redact_buffer() ────────────────────────────────────────────────────────────────────────────────| $ git checkout -b new | Switched to a new branch 'new' | -styles_hash: 2afc72138214b087 +styles_hash: fc716abcbd3de04a diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_picker.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker.snap new file mode 100644 index 0000000000..ae5b9c3855 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__checkout_picker.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- + On branch main | + Your branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | + | + | +────────────────────────────────────────────────────────────────────────────────| + 7/7 Checkout β€Ί | +β–Œbugfix-123 | + feature-a | + feature-b | + origin/HEAD | + origin/main | + v1.0.0 | + v2.0.0 | + | + | + | +styles_hash: d0729ae36786267b diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_picker_cancel.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker_cancel.snap new file mode 100644 index 0000000000..b80bd4ebf0 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__checkout_picker_cancel.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- +β–ŒOn branch main | +β–ŒYour branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | + | + | + | + | + | + | + | +────────────────────────────────────────────────────────────────────────────────| + Branch | + b Checkout branch/revision | + c Checkout new branch | + s Spinoff branch | + K Delete branch | + q/esc Quit/Close | +styles_hash: 2b3559858c649dec diff --git a/src/tests/snapshots/gitu__tests__branch__switch_branch_selected.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker_filter.snap similarity index 67% rename from src/tests/snapshots/gitu__tests__branch__switch_branch_selected.snap rename to src/tests/snapshots/gitu__tests__branch__checkout_picker_filter.snap index aceab54432..783c09625d 100644 --- a/src/tests/snapshots/gitu__tests__branch__switch_branch_selected.snap +++ b/src/tests/snapshots/gitu__tests__branch__checkout_picker_filter.snap @@ -2,24 +2,24 @@ source: src/tests/branch.rs expression: ctx.redact_buffer() --- - Branches | - main | -β–Œ* merged | - unmerged | + On branch main | + Your branch is up to date with 'origin/main'. | | - Remote origin | - origin/HEAD | - origin/main | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | | | | +────────────────────────────────────────────────────────────────────────────────| + 2/7 Checkout β€Ί feat | +β–Œfeature-a | + feature-b | + feat | | | | | | | -────────────────────────────────────────────────────────────────────────────────| -$ git checkout merged | -Switched to branch 'merged' | -styles_hash: c4b788b765812f1b + | +styles_hash: 44c060aaeb156b24 diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_picker_navigate.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker_navigate.snap new file mode 100644 index 0000000000..4754a0f284 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__checkout_picker_navigate.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- + On branch main | + Your branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | + | + | +────────────────────────────────────────────────────────────────────────────────| + 7/7 Checkout β€Ί | + bugfix-123 | + feature-a | +β–Œfeature-b | + origin/HEAD | + origin/main | + v1.0.0 | + v2.0.0 | + | + | + | +styles_hash: e15bb56a3ebe4b42 diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_picker_scroll.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker_scroll.snap new file mode 100644 index 0000000000..8f5befaa63 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__checkout_picker_scroll.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- + On branch main | + Your branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf branch-01 branch-02 branch-03 branch-04 branch-05 branch-06 branch-07 …| + | + | + | +────────────────────────────────────────────────────────────────────────────────| + 22/22 Checkout β€Ί | + branch-06 | + branch-07 | + branch-08 | + branch-09 | + branch-10 | +β–Œbranch-11 | + branch-12 | + branch-13 | + branch-14 | + branch-15 | +styles_hash: 58b0321e6ec28469 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_branch_selected.snap b/src/tests/snapshots/gitu__tests__branch__checkout_select_from_list.snap similarity index 71% rename from src/tests/snapshots/gitu__tests__branch__delete_branch_selected.snap rename to src/tests/snapshots/gitu__tests__branch__checkout_select_from_list.snap index 72017301f8..44d0c8a5a5 100644 --- a/src/tests/snapshots/gitu__tests__branch__delete_branch_selected.snap +++ b/src/tests/snapshots/gitu__tests__branch__checkout_select_from_list.snap @@ -2,13 +2,13 @@ source: src/tests/branch.rs expression: ctx.redact_buffer() --- - Branches | - * main | -β–Œ unmerged | +β–ŒOn branch feature-a | + | + Recent commits | + 3b23a7d feature-a add feature-a commit | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | | - Remote origin | - origin/HEAD | - origin/main | | | | @@ -20,6 +20,6 @@ expression: ctx.redact_buffer() | | ────────────────────────────────────────────────────────────────────────────────| -$ git branch -d merged | -Deleted branch merged (was b66a0bf). | -styles_hash: dd0c306c9b4c03e8 +$ git checkout feature-a | +Switched to branch 'feature-a' | +styles_hash: ed07bb3ef72d6e56 diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_use_custom_input.snap b/src/tests/snapshots/gitu__tests__branch__checkout_use_custom_input.snap new file mode 100644 index 0000000000..d502f11baf --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__checkout_use_custom_input.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- +β–ŒNo branch | + | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | + | + | +────────────────────────────────────────────────────────────────────────────────| +$ git checkout b66a0bf82020d6a386e94d0fceedec1f817d20c7 | +Note: switching to 'b66a0bf82020d6a386e94d0fceedec1f817d20c7'. | +You are in 'detached HEAD' state. You can look around, make experimental | +changes and commit them, and you can discard any commits you make in this | +state without impacting any branches by switching back to a branch. | +If you want to create a new branch to retain commits you create, you may | +do so (now or later) by using -c with the switch command. Example: | + git switch -c | +Or undo this operation with: | + git switch - | +Turn off this advice by setting config variable advice.detachedHead to false | +HEAD is now at b66a0bf add initial-file | +styles_hash: cfd01b18ca92dee4 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker.snap new file mode 100644 index 0000000000..c54fd84f78 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__delete_picker.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- + On branch main | + Your branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | + | + | +────────────────────────────────────────────────────────────────────────────────| + 7/7 Delete β€Ί | +β–Œbugfix-123 | + feature-a | + feature-b | + origin/HEAD | + origin/main | + v1.0.0 | + v2.0.0 | + | + | + | +styles_hash: 6a255f9ee8d30c59 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker_cancel.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker_cancel.snap new file mode 100644 index 0000000000..b80bd4ebf0 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__delete_picker_cancel.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- +β–ŒOn branch main | +β–ŒYour branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | + | + | + | + | + | + | + | +────────────────────────────────────────────────────────────────────────────────| + Branch | + b Checkout branch/revision | + c Checkout new branch | + s Spinoff branch | + K Delete branch | + q/esc Quit/Close | +styles_hash: 2b3559858c649dec diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker_filter.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker_filter.snap new file mode 100644 index 0000000000..d5f289cdcb --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__delete_picker_filter.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- + On branch main | + Your branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | + | + | +────────────────────────────────────────────────────────────────────────────────| + 2/7 Delete β€Ί feat | +β–Œfeature-a | + feature-b | + feat | + | + | + | + | + | + | + | +styles_hash: d49e1fc3270642e8 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker_navigate.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker_navigate.snap new file mode 100644 index 0000000000..b1e6c44fd2 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__delete_picker_navigate.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- + On branch main | + Your branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | + | + | +────────────────────────────────────────────────────────────────────────────────| + 7/7 Delete β€Ί | + bugfix-123 | + feature-a | +β–Œfeature-b | + origin/HEAD | + origin/main | + v1.0.0 | + v2.0.0 | + | + | + | +styles_hash: 8018be1197551da8 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker_scroll.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker_scroll.snap new file mode 100644 index 0000000000..1c2fbd397c --- /dev/null +++ b/src/tests/snapshots/gitu__tests__branch__delete_picker_scroll.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/branch.rs +expression: ctx.redact_buffer() +--- + On branch main | + Your branch is up to date with 'origin/main'. | + | + Recent commits | + b66a0bf branch-01 branch-02 branch-03 branch-04 branch-05 branch-06 branch-07 …| + | + | + | +────────────────────────────────────────────────────────────────────────────────| + 22/22 Delete β€Ί | + branch-06 | + branch-07 | + branch-08 | + branch-09 | + branch-10 | +β–Œbranch-11 | + branch-12 | + branch-13 | + branch-14 | + branch-15 | +styles_hash: 67846a237fd80596 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_branch_empty.snap b/src/tests/snapshots/gitu__tests__branch__delete_select_from_list.snap similarity index 90% rename from src/tests/snapshots/gitu__tests__branch__delete_branch_empty.snap rename to src/tests/snapshots/gitu__tests__branch__delete_select_from_list.snap index 5e19878d05..8711580f00 100644 --- a/src/tests/snapshots/gitu__tests__branch__delete_branch_empty.snap +++ b/src/tests/snapshots/gitu__tests__branch__delete_select_from_list.snap @@ -6,7 +6,7 @@ expression: ctx.redact_buffer() β–ŒYour branch is up to date with 'origin/main'. | | Recent commits | - b66a0bf main merged origin/main add initial-file | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | | | | @@ -21,5 +21,5 @@ expression: ctx.redact_buffer() | | ────────────────────────────────────────────────────────────────────────────────| -! Branch name required | -styles_hash: e1391c67392b2270 +? Branch is not fully merged. Really delete? (y or n) β€Ί β–ˆ | +styles_hash: 34185cd7d71d1f27 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_unmerged_branch.snap b/src/tests/snapshots/gitu__tests__branch__delete_unmerged_branch.snap index 9bf5109dce..eab5a80e98 100644 --- a/src/tests/snapshots/gitu__tests__branch__delete_unmerged_branch.snap +++ b/src/tests/snapshots/gitu__tests__branch__delete_unmerged_branch.snap @@ -6,7 +6,7 @@ expression: ctx.redact_buffer() β–ŒYour branch is up to date with 'origin/main'. | | Recent commits | - b66a0bf main merged origin/main add initial-file | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | | | | @@ -20,6 +20,6 @@ expression: ctx.redact_buffer() | | ────────────────────────────────────────────────────────────────────────────────| -$ git branch -d -f unmerged | -Deleted branch unmerged (was c84f226). | -styles_hash: 50fae40f3cb39dd3 +$ git branch -d -f bugfix-123 | +Deleted branch bugfix-123 (was 33a8c4d). | +styles_hash: 86ceb55a114a2ae diff --git a/src/tests/snapshots/gitu__tests__branch__delete_branch_input.snap b/src/tests/snapshots/gitu__tests__branch__delete_use_custom_input.snap similarity index 87% rename from src/tests/snapshots/gitu__tests__branch__delete_branch_input.snap rename to src/tests/snapshots/gitu__tests__branch__delete_use_custom_input.snap index 10ec0d736e..8711580f00 100644 --- a/src/tests/snapshots/gitu__tests__branch__delete_branch_input.snap +++ b/src/tests/snapshots/gitu__tests__branch__delete_use_custom_input.snap @@ -6,7 +6,8 @@ expression: ctx.redact_buffer() β–ŒYour branch is up to date with 'origin/main'. | | Recent commits | - b66a0bf main origin/main add initial-file | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | + | | | | @@ -20,6 +21,5 @@ expression: ctx.redact_buffer() | | ────────────────────────────────────────────────────────────────────────────────| -$ git branch -d merged | -Deleted branch merged (was b66a0bf). | -styles_hash: dce6312dfc6aa477 +? Branch is not fully merged. Really delete? (y or n) β€Ί β–ˆ | +styles_hash: 34185cd7d71d1f27 diff --git a/src/tests/snapshots/gitu__tests__branch__spinoff_branch.snap b/src/tests/snapshots/gitu__tests__branch__spinoff_branch.snap index e6106037c4..674d904349 100644 --- a/src/tests/snapshots/gitu__tests__branch__spinoff_branch.snap +++ b/src/tests/snapshots/gitu__tests__branch__spinoff_branch.snap @@ -5,7 +5,7 @@ expression: ctx.redact_buffer() β–ŒOn branch new | | Recent commits | - b66a0bf main merged new origin/main add initial-file | + b66a0bf main new v1.0.0 v2.0.0 origin/main add initial-file | | | | @@ -22,4 +22,4 @@ expression: ctx.redact_buffer() $ git checkout -b new | Switched to a new branch 'new' | > Branch main not changed | -styles_hash: f6b1f1b8641cb19a +styles_hash: 510f0d108f9759f2 diff --git a/src/tests/snapshots/gitu__tests__branch__spinoff_existing_branch.snap b/src/tests/snapshots/gitu__tests__branch__spinoff_existing_branch.snap index a5bcfdbb21..dbaca57824 100644 --- a/src/tests/snapshots/gitu__tests__branch__spinoff_existing_branch.snap +++ b/src/tests/snapshots/gitu__tests__branch__spinoff_existing_branch.snap @@ -6,7 +6,7 @@ expression: ctx.redact_buffer() β–ŒYour branch is up to date with 'origin/main'. | | Recent commits | - b66a0bf main merged origin/main add initial-file | + b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | | | | @@ -21,5 +21,5 @@ expression: ctx.redact_buffer() | | ────────────────────────────────────────────────────────────────────────────────| -! Cannot spin-off unmerged. It already exists | -styles_hash: bde5e651489b5245 +! Cannot spin-off feature-a. It already exists | +styles_hash: 67e9d103b840ee58 diff --git a/src/tests/snapshots/gitu__tests__editor__exit_from_prompt_exits_menu.snap b/src/tests/snapshots/gitu__tests__editor__exit_from_prompt_exits_menu.snap index d03704f938..addeb11594 100644 --- a/src/tests/snapshots/gitu__tests__editor__exit_from_prompt_exits_menu.snap +++ b/src/tests/snapshots/gitu__tests__editor__exit_from_prompt_exits_menu.snap @@ -15,11 +15,11 @@ expression: ctx.redact_buffer() | | | - | - | - | - | - | - | - | -styles_hash: f47a6512af0aca26 +────────────────────────────────────────────────────────────────────────────────| + Branch | + b Checkout branch/revision | + c Checkout new branch | + s Spinoff branch | + K Delete branch | + q/esc Quit/Close | +styles_hash: 7ec5204ca252dbc6 diff --git a/src/tests/snapshots/gitu__tests__editor__re_enter_prompt_from_menu.snap b/src/tests/snapshots/gitu__tests__editor__re_enter_prompt_from_menu.snap index 225503bda1..1db0d25e74 100644 --- a/src/tests/snapshots/gitu__tests__editor__re_enter_prompt_from_menu.snap +++ b/src/tests/snapshots/gitu__tests__editor__re_enter_prompt_from_menu.snap @@ -2,14 +2,17 @@ source: src/tests/editor.rs expression: ctx.redact_buffer() --- -β–ŒOn branch main | -β–ŒYour branch is up to date with 'origin/main'. | + On branch main | + Your branch is up to date with 'origin/main'. | | Recent commits | b66a0bf main origin/main add initial-file | | | | +────────────────────────────────────────────────────────────────────────────────| + 0/2 Checkout β€Ί b | +β–Œb | | | | @@ -19,7 +22,4 @@ expression: ctx.redact_buffer() | | | - | -────────────────────────────────────────────────────────────────────────────────| -? Checkout: β€Ί β–ˆ | -styles_hash: 43da189f53b3be3d +styles_hash: 8fd07f0d3bbdf3d6 From f10991d301a1ddcd9df4538941afcc39933406d2 Mon Sep 17 00:00:00 2001 From: Seong Yong-ju Date: Mon, 19 Jan 2026 01:16:17 +0900 Subject: [PATCH 2/5] test: remove redundant picker UI tests from branch tests Remove 6 tests that duplicate functionality already covered by unit tests in src/picker.rs and src/ui/picker.rs: - checkout_picker_filter - checkout_picker_navigate - checkout_picker_scroll - delete_picker_filter - delete_picker_navigate - delete_picker_scroll These tests verify basic picker functionality (filtering, navigation, scrolling) which is comprehensively tested at the unit level. The branch integration tests now focus on branch-specific operations: candidate retrieval, cancellation, and actual git command execution. Remove setup_many_branches helper function that was only used by the deleted scroll tests. --- src/tests/branch.rs | 48 ------------------- .../gitu__tests__branch__checkout_picker.snap | 2 +- ...tests__branch__checkout_picker_filter.snap | 25 ---------- ...sts__branch__checkout_picker_navigate.snap | 25 ---------- ...tests__branch__checkout_picker_scroll.snap | 25 ---------- .../gitu__tests__branch__delete_picker.snap | 2 +- ...__tests__branch__delete_picker_filter.snap | 25 ---------- ...tests__branch__delete_picker_navigate.snap | 25 ---------- ...__tests__branch__delete_picker_scroll.snap | 25 ---------- ...u__tests__branch__switch_branch_input.snap | 25 ---------- 10 files changed, 2 insertions(+), 225 deletions(-) delete mode 100644 src/tests/snapshots/gitu__tests__branch__checkout_picker_filter.snap delete mode 100644 src/tests/snapshots/gitu__tests__branch__checkout_picker_navigate.snap delete mode 100644 src/tests/snapshots/gitu__tests__branch__checkout_picker_scroll.snap delete mode 100644 src/tests/snapshots/gitu__tests__branch__delete_picker_filter.snap delete mode 100644 src/tests/snapshots/gitu__tests__branch__delete_picker_navigate.snap delete mode 100644 src/tests/snapshots/gitu__tests__branch__delete_picker_scroll.snap delete mode 100644 src/tests/snapshots/gitu__tests__branch__switch_branch_input.snap diff --git a/src/tests/branch.rs b/src/tests/branch.rs index 6da0b3ddf0..49e8e291b3 100644 --- a/src/tests/branch.rs +++ b/src/tests/branch.rs @@ -21,18 +21,6 @@ fn setup_picker(ctx: TestContext) -> TestContext { ctx } -fn setup_many_branches(ctx: TestContext) -> TestContext { - // Create many branches to test scrolling - for i in 1..=20 { - run( - &ctx.dir, - &["git", "checkout", "-b", &format!("branch-{:02}", i)], - ); - run(&ctx.dir, &["git", "checkout", "main"]); - } - ctx -} - // ==================== Checkout Tests ==================== #[test] @@ -40,24 +28,6 @@ fn checkout_picker() { snapshot!(setup_picker(setup_clone!()), "bb"); } -#[test] -fn checkout_picker_filter() { - snapshot!(setup_picker(setup_clone!()), "bbfeat"); -} - -#[test] -fn checkout_picker_navigate() { - snapshot!(setup_picker(setup_clone!()), "bb"); -} - -#[test] -fn checkout_picker_scroll() { - snapshot!( - setup_many_branches(setup_clone!()), - "bb" - ); -} - #[test] fn checkout_picker_cancel() { snapshot!(setup_picker(setup_clone!()), "bb"); @@ -85,24 +55,6 @@ fn delete_picker() { snapshot!(setup_picker(setup_clone!()), "bK"); } -#[test] -fn delete_picker_filter() { - snapshot!(setup_picker(setup_clone!()), "bKfeat"); -} - -#[test] -fn delete_picker_navigate() { - snapshot!(setup_picker(setup_clone!()), "bK"); -} - -#[test] -fn delete_picker_scroll() { - snapshot!( - setup_many_branches(setup_clone!()), - "bK" - ); -} - #[test] fn delete_picker_cancel() { snapshot!(setup_picker(setup_clone!()), "bK"); diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_picker.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker.snap index ae5b9c3855..369e53aa82 100644 --- a/src/tests/snapshots/gitu__tests__branch__checkout_picker.snap +++ b/src/tests/snapshots/gitu__tests__branch__checkout_picker.snap @@ -11,7 +11,7 @@ expression: ctx.redact_buffer() | | ────────────────────────────────────────────────────────────────────────────────| - 7/7 Checkout β€Ί | + 7/7 Checkout β€Ί β–ˆ | β–Œbugfix-123 | feature-a | feature-b | diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_picker_filter.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker_filter.snap deleted file mode 100644 index 783c09625d..0000000000 --- a/src/tests/snapshots/gitu__tests__branch__checkout_picker_filter.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/branch.rs -expression: ctx.redact_buffer() ---- - On branch main | - Your branch is up to date with 'origin/main'. | - | - Recent commits | - b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | - | - | - | -────────────────────────────────────────────────────────────────────────────────| - 2/7 Checkout β€Ί feat | -β–Œfeature-a | - feature-b | - feat | - | - | - | - | - | - | - | -styles_hash: 44c060aaeb156b24 diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_picker_navigate.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker_navigate.snap deleted file mode 100644 index 4754a0f284..0000000000 --- a/src/tests/snapshots/gitu__tests__branch__checkout_picker_navigate.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/branch.rs -expression: ctx.redact_buffer() ---- - On branch main | - Your branch is up to date with 'origin/main'. | - | - Recent commits | - b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | - | - | - | -────────────────────────────────────────────────────────────────────────────────| - 7/7 Checkout β€Ί | - bugfix-123 | - feature-a | -β–Œfeature-b | - origin/HEAD | - origin/main | - v1.0.0 | - v2.0.0 | - | - | - | -styles_hash: e15bb56a3ebe4b42 diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_picker_scroll.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker_scroll.snap deleted file mode 100644 index 8f5befaa63..0000000000 --- a/src/tests/snapshots/gitu__tests__branch__checkout_picker_scroll.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/branch.rs -expression: ctx.redact_buffer() ---- - On branch main | - Your branch is up to date with 'origin/main'. | - | - Recent commits | - b66a0bf branch-01 branch-02 branch-03 branch-04 branch-05 branch-06 branch-07 …| - | - | - | -────────────────────────────────────────────────────────────────────────────────| - 22/22 Checkout β€Ί | - branch-06 | - branch-07 | - branch-08 | - branch-09 | - branch-10 | -β–Œbranch-11 | - branch-12 | - branch-13 | - branch-14 | - branch-15 | -styles_hash: 58b0321e6ec28469 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker.snap index c54fd84f78..fd5eea07dd 100644 --- a/src/tests/snapshots/gitu__tests__branch__delete_picker.snap +++ b/src/tests/snapshots/gitu__tests__branch__delete_picker.snap @@ -11,7 +11,7 @@ expression: ctx.redact_buffer() | | ────────────────────────────────────────────────────────────────────────────────| - 7/7 Delete β€Ί | + 7/7 Delete β€Ί β–ˆ | β–Œbugfix-123 | feature-a | feature-b | diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker_filter.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker_filter.snap deleted file mode 100644 index d5f289cdcb..0000000000 --- a/src/tests/snapshots/gitu__tests__branch__delete_picker_filter.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/branch.rs -expression: ctx.redact_buffer() ---- - On branch main | - Your branch is up to date with 'origin/main'. | - | - Recent commits | - b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | - | - | - | -────────────────────────────────────────────────────────────────────────────────| - 2/7 Delete β€Ί feat | -β–Œfeature-a | - feature-b | - feat | - | - | - | - | - | - | - | -styles_hash: d49e1fc3270642e8 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker_navigate.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker_navigate.snap deleted file mode 100644 index b1e6c44fd2..0000000000 --- a/src/tests/snapshots/gitu__tests__branch__delete_picker_navigate.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/branch.rs -expression: ctx.redact_buffer() ---- - On branch main | - Your branch is up to date with 'origin/main'. | - | - Recent commits | - b66a0bf main v1.0.0 v2.0.0 origin/main add initial-file | - | - | - | -────────────────────────────────────────────────────────────────────────────────| - 7/7 Delete β€Ί | - bugfix-123 | - feature-a | -β–Œfeature-b | - origin/HEAD | - origin/main | - v1.0.0 | - v2.0.0 | - | - | - | -styles_hash: 8018be1197551da8 diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker_scroll.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker_scroll.snap deleted file mode 100644 index 1c2fbd397c..0000000000 --- a/src/tests/snapshots/gitu__tests__branch__delete_picker_scroll.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/branch.rs -expression: ctx.redact_buffer() ---- - On branch main | - Your branch is up to date with 'origin/main'. | - | - Recent commits | - b66a0bf branch-01 branch-02 branch-03 branch-04 branch-05 branch-06 branch-07 …| - | - | - | -────────────────────────────────────────────────────────────────────────────────| - 22/22 Delete β€Ί | - branch-06 | - branch-07 | - branch-08 | - branch-09 | - branch-10 | -β–Œbranch-11 | - branch-12 | - branch-13 | - branch-14 | - branch-15 | -styles_hash: 67846a237fd80596 diff --git a/src/tests/snapshots/gitu__tests__branch__switch_branch_input.snap b/src/tests/snapshots/gitu__tests__branch__switch_branch_input.snap deleted file mode 100644 index 60d9238c34..0000000000 --- a/src/tests/snapshots/gitu__tests__branch__switch_branch_input.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/branch.rs -expression: ctx.redact_buffer() ---- -β–ŒBranches | -β–Œ main | -β–Œ* merged | -β–Œ unmerged | - | - Remote origin | - origin/HEAD | - origin/main | - | - | - | - | - | - | - | - | - | -────────────────────────────────────────────────────────────────────────────────| -$ git checkout merged | -Switched to branch 'merged' | -styles_hash: f62456b7eae3080f From e3f3e06623885ec136afcd9d9c88cf8e2a15b1bc Mon Sep 17 00:00:00 2001 From: Seong Yong-ju Date: Mon, 19 Jan 2026 01:23:17 +0900 Subject: [PATCH 3/5] fix: close menu when opening branch picker Close the submenu when opening the branch picker (checkout/delete) so that cancelling the picker returns to the main view instead of the submenu. This provides a better UX where ESC consistently closes everything rather than requiring multiple ESC presses. Before: Picker -> ESC -> Submenu -> ESC -> Main view After: Picker -> ESC -> Main view --- src/ops/branch.rs | 4 ++-- ...u__tests__branch__checkout_picker_cancel.snap | 16 ++++++++-------- ...itu__tests__branch__delete_picker_cancel.snap | 16 ++++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/ops/branch.rs b/src/ops/branch.rs index 7064e8913c..55ec95ab70 100644 --- a/src/ops/branch.rs +++ b/src/ops/branch.rs @@ -23,6 +23,7 @@ impl OpTrait for Checkout { fn get_action(&self, _target: &ItemData) -> Option { Some(Rc::new(move |app: &mut App, term: &mut Term| { let picker = create_branch_picker(app, "Checkout", true)?; + app.close_menu(); let result = app.picker(term, picker)?; if let Some(data) = result { @@ -43,7 +44,6 @@ fn checkout(app: &mut App, term: &mut Term, rev: &str) -> Res<()> { let mut cmd = Command::new("git"); cmd.args(["checkout", rev]); - app.close_menu(); app.run_cmd(term, &[], cmd)?; Ok(()) } @@ -93,6 +93,7 @@ impl OpTrait for Delete { Some(Rc::new(move |app: &mut App, term: &mut Term| { let default = default.clone(); let picker = create_branch_picker_with_default(app, "Delete", true, default)?; + app.close_menu(); let result = app.picker(term, picker)?; if let Some(data) = result { @@ -128,7 +129,6 @@ pub fn delete(app: &mut App, term: &mut Term, branch_name: &str) -> Res<()> { cmd.arg(branch_name); - app.close_menu(); app.run_cmd(term, &[], cmd)?; Ok(()) } diff --git a/src/tests/snapshots/gitu__tests__branch__checkout_picker_cancel.snap b/src/tests/snapshots/gitu__tests__branch__checkout_picker_cancel.snap index b80bd4ebf0..fe93e837d7 100644 --- a/src/tests/snapshots/gitu__tests__branch__checkout_picker_cancel.snap +++ b/src/tests/snapshots/gitu__tests__branch__checkout_picker_cancel.snap @@ -15,11 +15,11 @@ expression: ctx.redact_buffer() | | | -────────────────────────────────────────────────────────────────────────────────| - Branch | - b Checkout branch/revision | - c Checkout new branch | - s Spinoff branch | - K Delete branch | - q/esc Quit/Close | -styles_hash: 2b3559858c649dec + | + | + | + | + | + | + | +styles_hash: 5ea219649635416a diff --git a/src/tests/snapshots/gitu__tests__branch__delete_picker_cancel.snap b/src/tests/snapshots/gitu__tests__branch__delete_picker_cancel.snap index b80bd4ebf0..fe93e837d7 100644 --- a/src/tests/snapshots/gitu__tests__branch__delete_picker_cancel.snap +++ b/src/tests/snapshots/gitu__tests__branch__delete_picker_cancel.snap @@ -15,11 +15,11 @@ expression: ctx.redact_buffer() | | | -────────────────────────────────────────────────────────────────────────────────| - Branch | - b Checkout branch/revision | - c Checkout new branch | - s Spinoff branch | - K Delete branch | - q/esc Quit/Close | -styles_hash: 2b3559858c649dec + | + | + | + | + | + | + | +styles_hash: 5ea219649635416a From b15c23c2c420029b5b863ab753c3cf0cc46dc712 Mon Sep 17 00:00:00 2001 From: Seong Yong-ju Date: Mon, 19 Jan 2026 01:25:57 +0900 Subject: [PATCH 4/5] test: rename prompt tests to picker tests Update editor test names to reflect that branch operations now use the picker instead of prompts: - exit_from_prompt_exits_menu -> exit_from_picker_exits_menu - re_enter_prompt_from_menu -> re_enter_picker_from_menu --- src/tests/editor.rs | 4 ++-- ...ts__editor__exit_from_picker_exits_menu.snap} | 16 ++++++++-------- ...ests__editor__re_enter_picker_from_menu.snap} | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) rename src/tests/snapshots/{gitu__tests__editor__exit_from_prompt_exits_menu.snap => gitu__tests__editor__exit_from_picker_exits_menu.snap} (65%) rename src/tests/snapshots/{gitu__tests__editor__re_enter_prompt_from_menu.snap => gitu__tests__editor__re_enter_picker_from_menu.snap} (87%) diff --git a/src/tests/editor.rs b/src/tests/editor.rs index 062eccf594..7481df8d6d 100644 --- a/src/tests/editor.rs +++ b/src/tests/editor.rs @@ -56,11 +56,11 @@ fn move_next_then_parent_section() { } #[test] -fn exit_from_prompt_exits_menu() { +fn exit_from_picker_exits_menu() { snapshot!(setup_clone!(), "bb"); } #[test] -fn re_enter_prompt_from_menu() { +fn re_enter_picker_from_menu() { snapshot!(setup_clone!(), "bbbb"); } diff --git a/src/tests/snapshots/gitu__tests__editor__exit_from_prompt_exits_menu.snap b/src/tests/snapshots/gitu__tests__editor__exit_from_picker_exits_menu.snap similarity index 65% rename from src/tests/snapshots/gitu__tests__editor__exit_from_prompt_exits_menu.snap rename to src/tests/snapshots/gitu__tests__editor__exit_from_picker_exits_menu.snap index addeb11594..d03704f938 100644 --- a/src/tests/snapshots/gitu__tests__editor__exit_from_prompt_exits_menu.snap +++ b/src/tests/snapshots/gitu__tests__editor__exit_from_picker_exits_menu.snap @@ -15,11 +15,11 @@ expression: ctx.redact_buffer() | | | -────────────────────────────────────────────────────────────────────────────────| - Branch | - b Checkout branch/revision | - c Checkout new branch | - s Spinoff branch | - K Delete branch | - q/esc Quit/Close | -styles_hash: 7ec5204ca252dbc6 + | + | + | + | + | + | + | +styles_hash: f47a6512af0aca26 diff --git a/src/tests/snapshots/gitu__tests__editor__re_enter_prompt_from_menu.snap b/src/tests/snapshots/gitu__tests__editor__re_enter_picker_from_menu.snap similarity index 87% rename from src/tests/snapshots/gitu__tests__editor__re_enter_prompt_from_menu.snap rename to src/tests/snapshots/gitu__tests__editor__re_enter_picker_from_menu.snap index 1db0d25e74..eea969d927 100644 --- a/src/tests/snapshots/gitu__tests__editor__re_enter_prompt_from_menu.snap +++ b/src/tests/snapshots/gitu__tests__editor__re_enter_picker_from_menu.snap @@ -11,8 +11,9 @@ expression: ctx.redact_buffer() | | ────────────────────────────────────────────────────────────────────────────────| - 0/2 Checkout β€Ί b | -β–Œb | + 2/2 Checkout β€Ί β–ˆ | +β–Œorigin/HEAD | + origin/main | | | | @@ -21,5 +22,4 @@ expression: ctx.redact_buffer() | | | - | -styles_hash: 8fd07f0d3bbdf3d6 +styles_hash: 49e995be810c0237 From 5be4fe89d86ae55a9c9fb548d14e6bc20a1deab3 Mon Sep 17 00:00:00 2001 From: Seong Yong-ju Date: Mon, 19 Jan 2026 01:27:34 +0900 Subject: [PATCH 5/5] test: remove unreferenced revert snapshots Remove snapshot files that are no longer referenced by any tests. --- .../snapshots/gitu__tests__revert_abort.snap | 25 ------------------- .../snapshots/gitu__tests__revert_commit.snap | 25 ------------------- .../gitu__tests__revert_commit_prompt.snap | 25 ------------------- .../gitu__tests__revert_conflict.snap | 25 ------------------- .../snapshots/gitu__tests__revert_menu.snap | 25 ------------------- 5 files changed, 125 deletions(-) delete mode 100644 src/tests/snapshots/gitu__tests__revert_abort.snap delete mode 100644 src/tests/snapshots/gitu__tests__revert_commit.snap delete mode 100644 src/tests/snapshots/gitu__tests__revert_commit_prompt.snap delete mode 100644 src/tests/snapshots/gitu__tests__revert_conflict.snap delete mode 100644 src/tests/snapshots/gitu__tests__revert_menu.snap diff --git a/src/tests/snapshots/gitu__tests__revert_abort.snap b/src/tests/snapshots/gitu__tests__revert_abort.snap deleted file mode 100644 index 57fc9a5110..0000000000 --- a/src/tests/snapshots/gitu__tests__revert_abort.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/mod.rs -expression: ctx.redact_buffer() ---- -β–ŒOn branch main | -β–ŒYour branch is ahead of 'origin/main' by 2 commit(s). | - | - Recent commits | - 7294ba4 main modify new-file | - 57409cb add new-file | - b66a0bf origin/main add initial-file | - | - | - | - | - | - | - | - | - | - | - | -────────────────────────────────────────────────────────────────────────────────| -$ git revert --abort | -styles_hash: 8d5b31c704dbb728 diff --git a/src/tests/snapshots/gitu__tests__revert_commit.snap b/src/tests/snapshots/gitu__tests__revert_commit.snap deleted file mode 100644 index e316f3b71c..0000000000 --- a/src/tests/snapshots/gitu__tests__revert_commit.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/mod.rs -expression: ctx.redact_buffer() ---- -β–Œ6324471 main Revert "add initial-file" | - b66a0bf origin/main add initial-file | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | -────────────────────────────────────────────────────────────────────────────────| -$ git revert --edit --no-edit b66a0bf82020d6a386e94d0fceedec1f817d20c7 | -styles_hash: 6dd7ad347925516e diff --git a/src/tests/snapshots/gitu__tests__revert_commit_prompt.snap b/src/tests/snapshots/gitu__tests__revert_commit_prompt.snap deleted file mode 100644 index 0b236c9536..0000000000 --- a/src/tests/snapshots/gitu__tests__revert_commit_prompt.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/mod.rs -expression: ctx.redact_buffer() ---- -β–Œb66a0bf main origin/main add initial-file | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | -────────────────────────────────────────────────────────────────────────────────| -? Revert commit (default b66a0bf82020d6a386e94d0fceedec1f817d20c7): β€Ί β–ˆ | -styles_hash: eed2121b6c3c5b0f diff --git a/src/tests/snapshots/gitu__tests__revert_conflict.snap b/src/tests/snapshots/gitu__tests__revert_conflict.snap deleted file mode 100644 index 119b9cba60..0000000000 --- a/src/tests/snapshots/gitu__tests__revert_conflict.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/mod.rs -expression: ctx.redact_buffer() ---- -β–ŒReverting 57409cb | - | - Unstaged changes (1) | - unmerged new-file… | - | - Staged changes (1) | - unmerged new-file… | - | - Recent commits | - 7294ba4 main modify new-file | - 57409cb add new-file | - b66a0bf origin/main add initial-file | - | - | - | - | - | - | - | - | -styles_hash: ce1bcac7e4255e31 diff --git a/src/tests/snapshots/gitu__tests__revert_menu.snap b/src/tests/snapshots/gitu__tests__revert_menu.snap deleted file mode 100644 index 60a36e955c..0000000000 --- a/src/tests/snapshots/gitu__tests__revert_menu.snap +++ /dev/null @@ -1,25 +0,0 @@ ---- -source: src/tests/mod.rs -expression: ctx.redact_buffer() ---- -β–Œb66a0bf main origin/main add initial-file | - | - | - | - | - | - | - | - | - | - | - | - | - | -────────────────────────────────────────────────────────────────────────────────| - Revert Arguments | - a Abort -e Edit commit message (--edit) | - c Continue -E Don't edit commit message (--no-edit) | - V Revert commit(s) -s Add Signed-off-by lines (--signoff) | - q/esc Quit/Close | -styles_hash: 64dda6a1259ae722