@@ -8,14 +8,17 @@ use crate::{
88 branchloc:: BranchLocator ,
99 ext:: RepositoryExtended ,
1010 stack:: { InitializationPolicy , Stack , StackStateAccess } ,
11+ stupid:: Stupid ,
1112} ;
1213
14+ use super :: get_stgit_parent;
15+
1316pub ( super ) fn command ( ) -> clap:: Command {
1417 clap:: Command :: new ( "--delete" )
1518 . short_flag ( 'D' )
1619 . override_usage ( super :: super :: make_usage (
1720 "stg branch --delete" ,
18- & [ "[--force] <branch>" ] ,
21+ & [ "[--force] [ <branch>] " ] ,
1922 ) )
2023 . about ( "Delete a branch" )
2124 . long_about (
@@ -24,13 +27,16 @@ pub(super) fn command() -> clap::Command {
2427 The branch will not be deleted if there are any patches remaining unless \
2528 the '--force' option is provided.\n \
2629 \n \
30+ If the current branch is selected for deletion, its parent branch must be \
31+ configured and the worktree must be clean. The parent branch will be \
32+ checked-out after the current branch is deleted.\n \
33+ \n \
2734 A protected branch may not be deleted; it must be unprotected first.",
2835 )
2936 . arg (
3037 clap:: Arg :: new ( "branch-any" )
3138 . help ( "Branch to delete" )
3239 . value_name ( "branch" )
33- . required ( true )
3440 . value_parser ( clap:: value_parser!( BranchLocator ) ) ,
3541 )
3642 . arg (
@@ -42,25 +48,49 @@ pub(super) fn command() -> clap::Command {
4248}
4349
4450pub ( super ) fn dispatch ( repo : & gix:: Repository , matches : & clap:: ArgMatches ) -> Result < ( ) > {
45- let target_branch = matches
46- . get_one :: < BranchLocator > ( "branch-any" )
47- . expect ( "required argument" )
48- . resolve ( repo) ?;
49- let target_branchname = target_branch. get_branch_partial_name ( ) ?;
51+ let ( target_branch, target_branchname) = if let Some ( branch_loc) = matches. get_one :: < BranchLocator > ( "branch-any" ) {
52+ let branch = branch_loc. resolve ( repo) ?;
53+ let branchname = branch. get_branch_partial_name ( ) ?;
54+ ( branch, branchname)
55+ } else if let Ok ( branch) = repo. get_current_branch ( ) {
56+ let branchname = branch. get_branch_partial_name ( ) ?;
57+ ( branch, branchname)
58+ } else {
59+ return Err ( anyhow ! ( "no target branch specified and no current branch" ) ) ;
60+ } ;
61+
5062 let current_branch = repo. get_current_branch ( ) . ok ( ) ;
5163 let current_branchname = current_branch
5264 . as_ref ( )
5365 . and_then ( |branch| branch. get_branch_partial_name ( ) . ok ( ) ) ;
54- if Some ( & target_branchname) == current_branchname. as_ref ( ) {
55- return Err ( anyhow ! ( "cannot delete the current branch" ) ) ;
56- }
66+ let config_snapshot = repo. config_snapshot ( ) ;
67+ let stupid = repo. stupid ( ) ;
68+
69+ let switch_to_branch = if Some ( & target_branchname) == current_branchname. as_ref ( ) {
70+ if let Some ( parent_branch) = get_stgit_parent ( & config_snapshot, & target_branchname) {
71+ let statuses = stupid. statuses ( None ) ?;
72+ if let Err ( e) = statuses
73+ . check_worktree_clean ( )
74+ . and_then ( |_| statuses. check_conflicts ( ) )
75+ {
76+ return Err ( anyhow ! ( "cannot delete the current branch: {e}" ) ) ;
77+ }
78+ Some ( parent_branch)
79+ } else {
80+ return Err ( anyhow ! (
81+ "cannot delete the current branch without a known parent branch"
82+ ) ) ;
83+ }
84+ } else {
85+ None
86+ } ;
5787
5888 if let Ok ( stack) = Stack :: from_branch (
5989 repo,
6090 target_branch. clone ( ) ,
6191 InitializationPolicy :: RequireInitialized ,
6292 ) {
63- if stack. is_protected ( & repo . config_snapshot ( ) ) {
93+ if stack. is_protected ( & config_snapshot) {
6494 return Err ( anyhow ! ( "delete not permitted: this branch is protected" ) ) ;
6595 } else if !matches. get_flag ( "force" ) && stack. all_patches ( ) . count ( ) > 0 {
6696 return Err ( anyhow ! (
@@ -70,11 +100,18 @@ pub(super) fn dispatch(repo: &gix::Repository, matches: &clap::ArgMatches) -> Re
70100 stack. deinitialize ( ) ?;
71101 }
72102
103+ if let Some ( branch_name) = switch_to_branch {
104+ stupid
105+ . checkout ( & branch_name)
106+ . context ( "switching to parent branch" ) ?;
107+ }
108+
73109 target_branch. delete ( ) ?;
74110
75111 let mut local_config_file = repo. local_config_file ( ) ?;
76112 local_config_file. remove_section ( "branch" , Some ( target_branchname. as_ref ( ) . into ( ) ) ) ;
77- repo. write_local_config ( local_config_file) . context ( "writing local config file" ) ?;
113+ repo. write_local_config ( local_config_file)
114+ . context ( "writing local config file" ) ?;
78115
79116 Ok ( ( ) )
80117}
0 commit comments