
- Add comprehensive Git workflow automation tools - Include branch management utilities - Add commit helpers with conventional commit support - Implement GitHub integration for PR management - Add configuration management system - Include comprehensive test coverage - Add professional documentation and examples
135 lines
3.6 KiB
Go
135 lines
3.6 KiB
Go
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
|
|
},
|
|
}
|