@@ -44,19 +44,15 @@ Examples:
4444 RunE : func (cmd * cobra.Command , args []string ) error {
4545 target := args [0 ]
4646
47- // Find repository
4847 repo , err := findRepository ()
4948 if err != nil {
5049 return err
5150 }
5251
53- // Create branch manager
5452 manager := branch .NewManager (repo )
5553 ctx := context .Background ()
5654
57- // Build checkout options
5855 var opts []branch.CheckoutOption
59-
6056 if force {
6157 opts = append (opts , branch .WithForceCheckout ())
6258 }
@@ -105,3 +101,202 @@ Examples:
105101
106102 return cmd
107103}
104+
105+ func newBranchCmd () * cobra.Command {
106+ var deleteFlag bool
107+ var listFlag bool
108+ var renameFlag bool
109+ var verboseFlag bool
110+ var forceFlag bool
111+ var startPoint string
112+
113+ cmd := & cobra.Command {
114+ Use : "branch [branch-name] [start-point]" ,
115+ Short : "List, create, delete, or rename branches" ,
116+ Long : `List, create, delete, or rename branches.
117+
118+ With no arguments, lists all branches. The current branch is highlighted.
119+ With a name argument, creates a new branch.
120+
121+ Examples:
122+ # List all branches
123+ srcc branch
124+
125+ # List branches with verbose output
126+ srcc branch -v
127+
128+ # Create a new branch
129+ srcc branch feature-name
130+
131+ # Create a new branch from a specific commit
132+ srcc branch feature-name abc123
133+
134+ # Create a branch with --start-point flag
135+ srcc branch feature-name --start-point=main
136+
137+ # Delete a branch
138+ srcc branch -d feature-name
139+
140+ # Force delete a branch
141+ srcc branch -D feature-name
142+
143+ # Rename the current branch
144+ srcc branch -m new-name
145+
146+ # Rename a specific branch
147+ srcc branch -m old-name new-name
148+
149+ # Force rename (overwrite existing)
150+ srcc branch -M old-name new-name` ,
151+ Args : cobra .MaximumNArgs (2 ),
152+ RunE : func (cmd * cobra.Command , args []string ) error {
153+ repo , err := findRepository ()
154+ if err != nil {
155+ return err
156+ }
157+
158+ manager := branch .NewManager (repo )
159+ ctx := context .Background ()
160+
161+ switch {
162+ case renameFlag :
163+ return renameBranch (ctx , args , manager , forceFlag )
164+ case deleteFlag :
165+ return deleteBranch (ctx , args , manager , forceFlag )
166+ case len (args ) == 0 || listFlag :
167+ return listBranches (ctx , manager , verboseFlag )
168+ default :
169+ return createBranch (ctx , args , manager , startPoint , forceFlag )
170+ }
171+ },
172+ }
173+
174+ cmd .Flags ().BoolVarP (& deleteFlag , "delete" , "d" , false , "Delete a branch" )
175+ cmd .Flags ().BoolVarP (& listFlag , "list" , "l" , false , "List all branches" )
176+ cmd .Flags ().BoolVarP (& renameFlag , "move" , "m" , false , "Rename a branch" )
177+ cmd .Flags ().BoolVarP (& verboseFlag , "verbose" , "v" , false , "Show verbose output with commit info" )
178+ cmd .Flags ().BoolVarP (& forceFlag , "force" , "f" , false , "Force operation (use with -d or -m)" )
179+ cmd .Flags ().StringVar (& startPoint , "start-point" , "" , "Create branch from this commit/branch" )
180+ cmd .Flags ().BoolP ("force-delete" , "D" , false , "Force delete a branch (shorthand for -d -f)" )
181+ cmd .Flags ().BoolP ("force-move" , "M" , false , "Force rename a branch (shorthand for -m -f)" )
182+
183+ cmd .PreRunE = func (cmd * cobra.Command , args []string ) error {
184+ if forceDelete , _ := cmd .Flags ().GetBool ("force-delete" ); forceDelete {
185+ deleteFlag = true
186+ forceFlag = true
187+ }
188+ if forceMove , _ := cmd .Flags ().GetBool ("force-move" ); forceMove {
189+ renameFlag = true
190+ forceFlag = true
191+ }
192+ return nil
193+ }
194+
195+ return cmd
196+ }
197+
198+ func renameBranch (ctx context.Context , args []string , manager * branch.Manager , force bool ) error {
199+ var oldName , newName string
200+
201+ if len (args ) == 0 {
202+ return fmt .Errorf ("new branch name required for rename" )
203+ } else if len (args ) == 1 {
204+ currentBranch , err := manager .CurrentBranch ()
205+ if err != nil {
206+ return fmt .Errorf ("failed to get current branch: %w" , err )
207+ }
208+ if currentBranch == "" {
209+ return fmt .Errorf ("not on any branch (detached HEAD)" )
210+ }
211+ oldName = currentBranch
212+ newName = args [0 ]
213+ } else {
214+ oldName = args [0 ]
215+ newName = args [1 ]
216+ }
217+
218+ opts := []branch.RenameOption {}
219+ if force {
220+ opts = append (opts , branch .WithForceRename ())
221+ }
222+
223+ if err := manager .RenameBranch (ctx , oldName , newName , opts ... ); err != nil {
224+ return fmt .Errorf ("failed to rename branch: %w" , err )
225+ }
226+
227+ fmt .Printf ("Branch %s renamed to %s\n " , oldName , newName )
228+ return nil
229+ }
230+
231+ func deleteBranch (ctx context.Context , args []string , manager * branch.Manager , force bool ) error {
232+ if len (args ) == 0 {
233+ return fmt .Errorf ("branch name required for deletion" )
234+ }
235+ branchName := args [0 ]
236+
237+ opts := []branch.DeleteOption {}
238+ if force {
239+ opts = append (opts , branch .WithForceDelete ())
240+ }
241+
242+ if err := manager .DeleteBranch (ctx , branchName , opts ... ); err != nil {
243+ return fmt .Errorf ("failed to delete branch: %w" , err )
244+ }
245+
246+ fmt .Printf ("Deleted branch %s\n " , branchName )
247+ return nil
248+ }
249+
250+ func listBranches (ctx context.Context , manager * branch.Manager , verbose bool ) error {
251+ branches , err := manager .ListBranches (ctx )
252+ if err != nil {
253+ return fmt .Errorf ("failed to list branches: %w" , err )
254+ }
255+ currentBranch , _ := manager .CurrentBranch ()
256+
257+ if len (branches ) == 0 {
258+ fmt .Println ("No branches found" )
259+ return nil
260+ }
261+
262+ for _ , br := range branches {
263+ prefix := " "
264+ if br .Name == currentBranch {
265+ prefix = "* "
266+ }
267+
268+ if verbose {
269+ fmt .Printf ("%s%-20s %s %s\n " ,
270+ prefix ,
271+ br .Name ,
272+ br .SHA .Short (),
273+ br .LastCommitMessage )
274+ } else {
275+ fmt .Printf ("%s%s\n " , prefix , br .Name )
276+ }
277+ }
278+
279+ return nil
280+ }
281+
282+ func createBranch (ctx context.Context , args []string , manager * branch.Manager , startPoint string , force bool ) error {
283+ branchName := args [0 ]
284+ opts := []branch.CreateOption {}
285+
286+ if len (args ) > 1 {
287+ opts = append (opts , branch .WithStartPoint (args [1 ]))
288+ } else if startPoint != "" {
289+ opts = append (opts , branch .WithStartPoint (startPoint ))
290+ }
291+
292+ if force {
293+ opts = append (opts , branch .WithForceCreate ())
294+ }
295+
296+ if _ , err := manager .CreateBranch (ctx , branchName , opts ... ); err != nil {
297+ return fmt .Errorf ("failed to create branch: %w" , err )
298+ }
299+
300+ fmt .Printf ("Created branch %s\n " , branchName )
301+ return nil
302+ }
0 commit comments