Skip to content

Commit 27e2121

Browse files
committed
Implement branch management commands in branch.go
This commit moves the branch management functionalities from the deleted cmd_branch.go file to branch.go. It introduces commands for listing, creating, deleting, and renaming branches, enhancing the modularity and organization of the code. The new implementation includes detailed command examples and integrates flags for various operations, improving user experience and command usability.
1 parent 7228951 commit 27e2121

2 files changed

Lines changed: 199 additions & 212 deletions

File tree

sourcecontrol/cmd/sourcecontrol/branch.go

Lines changed: 199 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)