package cmd import ( "context" "fmt" "strings" "github.com/spf13/cobra" "github.com/iwasforcedtobehere/git-automation-cli/internal/git" "github.com/iwasforcedtobehere/git-automation-cli/internal/config" ) func init() { rootCmd.AddCommand(syncCmd) rootCmd.AddCommand(cleanCmd) } var syncCmd = &cobra.Command{ Use: "sync", Short: "Sync with remote", Long: `Fetch the latest changes from remote, rebase the current branch onto its upstream tracking branch, and push the changes back to remote.`, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() // Check if we're in a Git repository if _, err := git.CurrentBranch(ctx); err != nil { return fmt.Errorf("not a git repository or no branch found") } // Fetch latest changes if config.GlobalConfig.Verbose { fmt.Println("Fetching latest changes from remote...") } if err := git.Fetch(ctx); err != nil { return fmt.Errorf("failed to fetch from remote: %w", err) } // Rebase onto tracking branch if config.GlobalConfig.Verbose { fmt.Println("Rebasing current branch onto tracking branch...") } if err := git.RebaseOntoTracking(ctx); err != nil { return fmt.Errorf("failed to rebase: %w", err) } // Push changes if config.GlobalConfig.Verbose { fmt.Println("Pushing changes to remote...") } if err := git.PushCurrent(ctx, false); err != nil { return fmt.Errorf("failed to push: %w", err) } fmt.Println("Successfully synced with remote") return nil }, } var cleanCmd = &cobra.Command{ Use: "clean", Short: "Clean local feature branches", Long: `Delete local feature branches that have been merged or are no longer needed. By default, only deletes branches with the 'feature/' prefix.`, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() // Check if we're in a Git repository if _, err := git.CurrentBranch(ctx); err != nil { return fmt.Errorf("not a git repository or no branch found") } // Get all local branches branches, err := git.LocalBranches(ctx) if err != nil { return fmt.Errorf("failed to list branches: %w", err) } // Get current branch to avoid deleting it currentBranch, err := git.CurrentBranch(ctx) if err != nil { return fmt.Errorf("failed to get current branch: %w", err) } var removed []string var prefix string // Determine which prefix to use for cleaning if config.GlobalConfig.FeaturePrefix != "" { prefix = config.GlobalConfig.FeaturePrefix } else { prefix = "feature/" } for _, b := range branches { // Skip current branch and main/master branches if b == currentBranch || b == "main" || b == "master" { continue } // Check if branch matches the prefix if strings.HasPrefix(b, prefix) { // Confirm deletion if configured if config.GlobalConfig.ConfirmDestructive { fmt.Printf("Delete branch '%s'? [y/N]: ", b) var response string fmt.Scanln(&response) if strings.ToLower(response) != "y" && strings.ToLower(response) != "yes" { continue } } if err := git.DeleteBranch(ctx, b); err == nil { removed = append(removed, b) if config.GlobalConfig.Verbose { fmt.Printf("Deleted branch: %s\n", b) } } else if config.GlobalConfig.Verbose { fmt.Printf("Failed to delete branch %s: %v\n", b, err) } } } if len(removed) > 0 { fmt.Printf("Deleted %d branches:\n", len(removed)) for _, branch := range removed { fmt.Printf(" - %s\n", branch) } } else { fmt.Println("No branches to clean") } return nil }, }