1
1
use std:: path:: Path ;
2
2
3
+ use but_settings:: AppSettings ;
4
+ use gitbutler_command_context:: CommandContext ;
3
5
use gitbutler_project:: Project ;
4
6
5
7
#[ derive( Debug , clap:: Parser ) ]
@@ -14,21 +16,88 @@ pub enum Subcommands {
14
16
New {
15
17
/// Name of the new branch
16
18
branch_name : Option < String > ,
19
+ /// Anchor point - either a commit ID or branch name to create the new branch from
20
+ #[ clap( long, short = 'a' ) ]
21
+ anchor : Option < String > ,
17
22
} ,
18
23
}
19
24
20
25
pub fn handle ( cmd : & Subcommands , repo_path : & Path , _json : bool ) -> anyhow:: Result < ( ) > {
21
26
let project = Project :: find_by_path ( repo_path) ?;
22
27
match cmd {
23
- Subcommands :: New { branch_name } => {
24
- let req = gitbutler_branch:: BranchCreateRequest {
25
- name : branch_name. clone ( ) ,
26
- ownership : None ,
27
- order : None ,
28
- selected_for_changes : None ,
29
- } ;
30
- but_api:: virtual_branches:: create_virtual_branch ( project. id , req) ?;
31
- Ok ( ( ) )
28
+ Subcommands :: New {
29
+ branch_name,
30
+ anchor,
31
+ } => {
32
+ if let Some ( anchor_str) = anchor {
33
+ // Use the new create_reference API when anchor is provided
34
+ let ctx = CommandContext :: open (
35
+ & project,
36
+ AppSettings :: load_from_default_path_creating ( ) ?,
37
+ ) ?;
38
+ let mut ctx = ctx; // Make mutable for CliId resolution
39
+
40
+ // Resolve the anchor string to a CliId
41
+ let anchor_ids = crate :: id:: CliId :: from_str ( & mut ctx, anchor_str) ?;
42
+ if anchor_ids. is_empty ( ) {
43
+ return Err ( anyhow:: anyhow!( "Could not find anchor: {}" , anchor_str) ) ;
44
+ }
45
+ if anchor_ids. len ( ) > 1 {
46
+ return Err ( anyhow:: anyhow!(
47
+ "Ambiguous anchor '{}', matches multiple items" ,
48
+ anchor_str
49
+ ) ) ;
50
+ }
51
+ let anchor_id = & anchor_ids[ 0 ] ;
52
+
53
+ // Get branch name or use canned name
54
+ let branch_name = if let Some ( name) = branch_name {
55
+ name. clone ( )
56
+ } else {
57
+ but_api:: workspace:: canned_branch_name ( project. id ) ?
58
+ } ;
59
+
60
+ // Create the anchor for create_reference
61
+ let anchor = match anchor_id {
62
+ crate :: id:: CliId :: Commit { oid } => {
63
+ Some ( but_api:: stack:: create_reference:: Anchor :: AtCommit {
64
+ commit_id : ( * oid) . into ( ) ,
65
+ position : but_workspace:: branch:: create_reference:: Position :: Above ,
66
+ } )
67
+ }
68
+ crate :: id:: CliId :: Branch { name } => {
69
+ Some ( but_api:: stack:: create_reference:: Anchor :: AtReference {
70
+ short_name : name. clone ( ) ,
71
+ position : but_workspace:: branch:: create_reference:: Position :: Above ,
72
+ } )
73
+ }
74
+ _ => {
75
+ return Err ( anyhow:: anyhow!(
76
+ "Invalid anchor type: {}, expected commit or branch" ,
77
+ anchor_id. kind( )
78
+ ) ) ;
79
+ }
80
+ } ;
81
+
82
+ // Use create_reference API
83
+ let request = but_api:: stack:: create_reference:: Request {
84
+ new_name : branch_name. clone ( ) ,
85
+ anchor,
86
+ } ;
87
+ but_api:: stack:: create_reference ( project. id , request) ?;
88
+ println ! ( "Created branch {branch_name}" ) ;
89
+ Ok ( ( ) )
90
+ } else {
91
+ // Create an independent branch
92
+ let req = gitbutler_branch:: BranchCreateRequest {
93
+ name : branch_name. clone ( ) ,
94
+ ownership : None ,
95
+ order : None ,
96
+ selected_for_changes : None ,
97
+ } ;
98
+ but_api:: virtual_branches:: create_virtual_branch ( project. id , req) ?;
99
+ Ok ( ( ) )
100
+ }
32
101
}
33
102
}
34
103
}
0 commit comments