git

package
v0.22.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2025 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package git provides cobra commands for managing multiple git repositories in a development folder.

Index

Constants

This section is empty.

Variables

View Source
var BranchAllCmd = &cobra.Command{
	Use:   "branch-all",
	Short: "Show current branch of all git repositories in development folder",
	Long:  `This command shows the current branch for all git repositories found in your development folder.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Start("Checking current branch of all git repositories")

		isVerbose := utils.IsVerbose(cmd)

		devPath, err := getWorkingPath(cmd)
		if err != nil {
			log.Error("%s", err)
			return
		}

		log.Verbose(isVerbose, "Development path: %s", devPath)

		repos, err := findGitRepositories(devPath)
		if err != nil {
			log.Error("Failed to find git repositories: %s", err)
			return
		}

		if len(repos) == 0 {
			log.Warn("No git repositories found in %s", devPath)
			return
		}

		log.Info("Checking branches of %d repositories:", len(repos))

		mainCount := 0
		otherBranchCount := 0

		for _, repoPath := range repos {
			repoName := filepath.Base(repoPath)

			branch, err := repo.GetCurrentBranch(repoPath)
			if err != nil {
				log.Error("  %s: Failed to get current branch - %s", repoName, err)
				continue
			}

			mainBranch, err := repo.GetMainBranch(repoPath)
			if err != nil {
				log.Warn("  %s: Could not determine main branch - %s", repoName, err)
				mainBranch = "main"
			}

			if branch == mainBranch {
				log.Success("  %s: %s", repoName, branch)
				mainCount++
			} else {
				log.Warn("  %s: %s", repoName, branch)
				otherBranchCount++
			}
		}

		log.Info("Branch summary: %d on default branch, %d on other branches", mainCount, otherBranchCount)
	},
}

BranchAllCmd defines the cobra command for showing current branch of all git repositories. It displays the current branch for all repositories in the development folder.

View Source
var CleanAllCmd = &cobra.Command{
	Use:   "clean-all",
	Short: "Clean untracked files in all git repositories in development folder",
	Long:  `This command removes untracked files and directories for all git repositories found in your development folder.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Start("Cleaning untracked files in all git repositories")

		isVerbose := utils.IsVerbose(cmd)
		dryRun, _ := cmd.Flags().GetBool("dry-run")
		force, _ := cmd.Flags().GetBool("force")
		directories, _ := cmd.Flags().GetBool("directories")

		devPath, err := getWorkingPath(cmd)
		if err != nil {
			log.Error("%s", err)
			return
		}

		log.Verbose(isVerbose, "Development path: %s", devPath)

		if dryRun {
			log.Info("Dry run mode - no actual git operations will be performed")
		}

		if !force && !dryRun {
			log.Warn("This will permanently delete untracked files. Use --force to confirm or --dry-run to preview.")
			return
		}

		repos, err := findGitRepositories(devPath)
		if err != nil {
			log.Error("Failed to find git repositories: %s", err)
			return
		}

		if len(repos) == 0 {
			log.Warn("No git repositories found in %s", devPath)
			return
		}

		log.Info("Found %d git repositories", len(repos))

		successCount := 0
		failureCount := 0
		skippedCount := 0

		for _, repoPath := range repos {
			repoName := filepath.Base(repoPath)
			log.Info("Checking repository: %s", repoName)

			if dryRun {
				hasUntracked, err := hasUntrackedFiles(repoPath)
				if err != nil {
					log.Error("  [DRY RUN] Failed to check for untracked files: %s", err)
					failureCount++
					continue
				}
				if hasUntracked {
					log.Info("  [DRY RUN] Would clean untracked files in: %s", repoPath)

					if err := showUntrackedFiles(repoPath); err != nil {
						log.Error("  [DRY RUN] Failed to show untracked files: %s", err)
					}
					successCount++
				} else {
					log.Info("  [DRY RUN] No untracked files to clean, skipping: %s", repoPath)
					skippedCount++
				}
				continue
			}

			hasUntracked, err := hasUntrackedFiles(repoPath)
			if err != nil {
				log.Error("  Failed to check for untracked files: %s", err)
				failureCount++
				continue
			}

			if !hasUntracked {
				log.Info("  No untracked files to clean, skipping...")
				skippedCount++
				continue
			}

			if err := cleanRepository(repoPath, directories); err != nil {
				log.Error("  Failed to clean %s: %s", repoName, err)
				failureCount++
				continue
			}

			log.Success("  Successfully cleaned untracked files in %s", repoName)
			successCount++
		}

		log.Info("Clean completed: %d successful, %d failed, %d skipped", successCount, failureCount, skippedCount)

		if failureCount > 0 {
			log.Warn("Some repositories failed to clean. Check the output above for details.")
		} else {
			log.Success("All git repositories with untracked files cleaned successfully")
		}
	},
}

CleanAllCmd defines the cobra command for cleaning untracked files in all git repositories. It removes untracked files and directories for all repositories in the development folder.

View Source
var FetchAllCmd = &cobra.Command{
	Use:   "fetch-all",
	Short: "Fetch all git repositories in development folder",
	Long:  `This command fetches updates from remote for all git repositories found in your development folder.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Start("Fetching all git repositories")

		isVerbose := utils.IsVerbose(cmd)
		dryRun, _ := cmd.Flags().GetBool("dry-run")

		devPath, err := getWorkingPath(cmd)
		if err != nil {
			log.Error("%s", err)
			return
		}

		log.Verbose(isVerbose, "Development path: %s", devPath)

		if dryRun {
			log.Info("Dry run mode - no actual git operations will be performed")
		}

		repos, err := findGitRepositories(devPath)
		if err != nil {
			log.Error("Failed to find git repositories: %s", err)
			return
		}

		if len(repos) == 0 {
			log.Warn("No git repositories found in %s", devPath)
			return
		}

		log.Info("Found %d git repositories", len(repos))

		successCount := 0
		failureCount := 0

		for _, repoPath := range repos {
			repoName := filepath.Base(repoPath)
			log.Info("Fetching repository: %s", repoName)

			if dryRun {
				log.Info("  [DRY RUN] Would fetch repository at: %s", repoPath)
				successCount++
				continue
			}

			if err := fetchRepository(repoPath); err != nil {
				log.Error("  Failed to fetch %s: %s", repoName, err)
				failureCount++
				continue
			}

			log.Success("  Successfully fetched %s", repoName)
			successCount++
		}

		log.Info("Fetch completed: %d successful, %d failed", successCount, failureCount)

		if failureCount > 0 {
			log.Warn("Some repositories failed to fetch. Check the output above for details.")
		} else {
			log.Success("All git repositories fetched successfully")
		}
	},
}

FetchAllCmd defines the cobra command for fetching all git repositories. It fetches updates from remote for all repositories in the development folder.

View Source
var GitCmd = &cobra.Command{
	Use:   "git",
	Short: "Manage multiple git repositories",
	Long:  `This command is used to facilitate the management of multiple git repositories in your development folder.`,
	Run: func(cmd *cobra.Command, args []string) {
		showInfo, _ := cmd.Flags().GetBool("info")
		isVerbose := utils.IsVerbose(cmd)

		if showInfo {
			log.Info("Current git repository management configuration:")
			devPath := viper.GetString("git.devPath")

			if devPath == "" {
				log.Warn("  Development Path (git.devPath): Not Set")
				log.Info("  Use 'eng config git-dev-path' to set your development folder path")
			} else {
				log.Info("  Development Path (git.devPath): %s", devPath)
			}
			return
		}

		if len(args) == 0 {
			log.Verbose(isVerbose, "No subcommand provided, showing help.")
			err := cmd.Help()
			cobra.CheckErr(err)
		} else {
			log.Verbose(isVerbose, "Subcommand '%s' provided.", args[0])
		}
	},
}

GitCmd serves as the base command for all git repository management operations. It doesn't perform any action itself but groups subcommands like sync-all, status-all, etc.

View Source
var ListCmd = &cobra.Command{
	Use:   "list",
	Short: "List all git repositories in development folder",
	Long:  `This command lists all git repositories found in your development folder.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Start("Listing git repositories")

		isVerbose := utils.IsVerbose(cmd)
		showPaths, _ := cmd.Flags().GetBool("paths")

		devPath, err := getWorkingPath(cmd)
		if err != nil {
			log.Error("%s", err)
			return
		}

		log.Verbose(isVerbose, "Development path: %s", devPath)

		repos, err := findGitRepositories(devPath)
		if err != nil {
			log.Error("Failed to find git repositories: %s", err)
			return
		}

		if len(repos) == 0 {
			log.Warn("No git repositories found in %s", devPath)
			return
		}

		log.Info("Found %d git repositories:", len(repos))

		for i, repoPath := range repos {
			repoName := filepath.Base(repoPath)
			if showPaths {
				log.Info("  %d. %s (%s)", i+1, repoName, repoPath)
			} else {
				log.Info("  %d. %s", i+1, repoName)
			}
		}

		log.Success("Listed %d git repositories", len(repos))
	},
}

ListCmd defines the cobra command for listing all git repositories. It lists all git repositories found in the development folder.

View Source
var PullAllCmd = &cobra.Command{
	Use:   "pull-all",
	Short: "Pull all git repositories in development folder",
	Long:  `This command pulls with rebase for all git repositories found in your development folder. Use this after fetch-all for faster operations.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Start("Pulling all git repositories")

		isVerbose := utils.IsVerbose(cmd)
		dryRun, _ := cmd.Flags().GetBool("dry-run")

		devPath, err := getWorkingPath(cmd)
		if err != nil {
			log.Error("%s", err)
			return
		}

		log.Verbose(isVerbose, "Development path: %s", devPath)

		if dryRun {
			log.Info("Dry run mode - no actual git operations will be performed")
		}

		repos, err := findGitRepositories(devPath)
		if err != nil {
			log.Error("Failed to find git repositories: %s", err)
			return
		}

		if len(repos) == 0 {
			log.Warn("No git repositories found in %s", devPath)
			return
		}

		log.Info("Found %d git repositories", len(repos))

		successCount := 0
		failureCount := 0

		for _, repoPath := range repos {
			repoName := filepath.Base(repoPath)
			log.Info("Pulling repository: %s", repoName)

			if dryRun {
				log.Info("  [DRY RUN] Would pull repository at: %s", repoPath)
				successCount++
				continue
			}

			isDirty, err := repo.IsDirty(repoPath)
			if err != nil {
				log.Error("  Failed to check repository status: %s", err)
				failureCount++
				continue
			}

			if isDirty {
				log.Warn("  Repository has uncommitted changes, skipping...")
				failureCount++
				continue
			}

			if err := repo.EnsureOnDefaultBranch(repoPath); err != nil {
				log.Error("  Failed to ensure on default branch: %s", err)
				failureCount++
				continue
			}

			if err := pullRepository(repoPath); err != nil {
				log.Error("  Failed to pull %s: %s", repoName, err)
				failureCount++
				continue
			}

			log.Success("  Successfully pulled %s", repoName)
			successCount++
		}

		log.Info("Pull completed: %d successful, %d failed", successCount, failureCount)

		if failureCount > 0 {
			log.Warn("Some repositories failed to pull. Check the output above for details.")
		} else {
			log.Success("All git repositories pulled successfully")
		}
	},
}

PullAllCmd defines the cobra command for pulling all git repositories. It pulls with rebase for all repositories in the development folder (assumes fetch was already done).

View Source
var PushAllCmd = &cobra.Command{
	Use:   "push-all",
	Short: "Push all git repositories in development folder",
	Long:  `This command pushes commits for all git repositories found in your development folder that have unpushed commits.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Start("Pushing all git repositories")

		isVerbose := utils.IsVerbose(cmd)
		dryRun, _ := cmd.Flags().GetBool("dry-run")
		force, _ := cmd.Flags().GetBool("force")

		devPath, err := getWorkingPath(cmd)
		if err != nil {
			log.Error("%s", err)
			return
		}

		log.Verbose(isVerbose, "Development path: %s", devPath)

		if dryRun {
			log.Info("Dry run mode - no actual git operations will be performed")
		}

		if force {
			log.Warn("Force push mode enabled - this will force push to remote")
		}

		repos, err := findGitRepositories(devPath)
		if err != nil {
			log.Error("Failed to find git repositories: %s", err)
			return
		}

		if len(repos) == 0 {
			log.Warn("No git repositories found in %s", devPath)
			return
		}

		log.Info("Found %d git repositories", len(repos))

		successCount := 0
		failureCount := 0
		skippedCount := 0

		for _, repoPath := range repos {
			repoName := filepath.Base(repoPath)
			log.Info("Checking repository: %s", repoName)

			if dryRun {
				hasUnpushed, err := hasUnpushedCommits(repoPath)
				if err != nil {
					log.Error("  [DRY RUN] Failed to check for unpushed commits: %s", err)
					failureCount++
					continue
				}
				if hasUnpushed {
					log.Info("  [DRY RUN] Would push repository at: %s", repoPath)
					successCount++
				} else {
					log.Info("  [DRY RUN] No unpushed commits, skipping: %s", repoPath)
					skippedCount++
				}
				continue
			}

			hasUnpushed, err := hasUnpushedCommits(repoPath)
			if err != nil {
				log.Error("  Failed to check for unpushed commits: %s", err)
				failureCount++
				continue
			}

			if !hasUnpushed {
				log.Info("  No unpushed commits, skipping...")
				skippedCount++
				continue
			}

			isDirty, err := repo.IsDirty(repoPath)
			if err != nil {
				log.Error("  Failed to check repository status: %s", err)
				failureCount++
				continue
			}

			if isDirty {
				log.Warn("  Repository has uncommitted changes, but proceeding with push...")
			}

			if err := pushRepository(repoPath, force); err != nil {
				log.Error("  Failed to push %s: %s", repoName, err)
				failureCount++
				continue
			}

			log.Success("  Successfully pushed %s", repoName)
			successCount++
		}

		log.Info("Push completed: %d successful, %d failed, %d skipped", successCount, failureCount, skippedCount)

		if failureCount > 0 {
			log.Warn("Some repositories failed to push. Check the output above for details.")
		} else {
			log.Success("All git repositories with unpushed commits pushed successfully")
		}
	},
}

PushAllCmd defines the cobra command for pushing all git repositories. It pushes commits for all repositories in the development folder that have unpushed commits.

View Source
var StashAllCmd = &cobra.Command{
	Use:   "stash-all",
	Short: "Stash changes in all git repositories in development folder",
	Long:  `This command stashes uncommitted changes for all git repositories found in your development folder that have uncommitted changes.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Start("Stashing changes in all git repositories")

		isVerbose := utils.IsVerbose(cmd)
		dryRun, _ := cmd.Flags().GetBool("dry-run")
		message, _ := cmd.Flags().GetString("message")

		devPath, err := getWorkingPath(cmd)
		if err != nil {
			log.Error("%s", err)
			return
		}

		log.Verbose(isVerbose, "Development path: %s", devPath)

		if dryRun {
			log.Info("Dry run mode - no actual git operations will be performed")
		}

		repos, err := findGitRepositories(devPath)
		if err != nil {
			log.Error("Failed to find git repositories: %s", err)
			return
		}

		if len(repos) == 0 {
			log.Warn("No git repositories found in %s", devPath)
			return
		}

		log.Info("Found %d git repositories", len(repos))

		successCount := 0
		failureCount := 0
		skippedCount := 0

		for _, repoPath := range repos {
			repoName := filepath.Base(repoPath)
			log.Info("Checking repository: %s", repoName)

			if dryRun {
				hasChanges, err := hasUncommittedChanges(repoPath)
				if err != nil {
					log.Error("  [DRY RUN] Failed to check for changes: %s", err)
					failureCount++
					continue
				}
				if hasChanges {
					log.Info("  [DRY RUN] Would stash changes in: %s", repoPath)
					successCount++
				} else {
					log.Info("  [DRY RUN] No changes to stash, skipping: %s", repoPath)
					skippedCount++
				}
				continue
			}

			hasChanges, err := hasUncommittedChanges(repoPath)
			if err != nil {
				log.Error("  Failed to check for uncommitted changes: %s", err)
				failureCount++
				continue
			}

			if !hasChanges {
				log.Info("  No uncommitted changes, skipping...")
				skippedCount++
				continue
			}

			if err := stashRepository(repoPath, message); err != nil {
				log.Error("  Failed to stash %s: %s", repoName, err)
				failureCount++
				continue
			}

			log.Success("  Successfully stashed changes in %s", repoName)
			successCount++
		}

		log.Info("Stash completed: %d successful, %d failed, %d skipped", successCount, failureCount, skippedCount)

		if failureCount > 0 {
			log.Warn("Some repositories failed to stash. Check the output above for details.")
		} else {
			log.Success("All git repositories with changes stashed successfully")
		}
	},
}

StashAllCmd defines the cobra command for stashing changes in all git repositories. It stashes uncommitted changes for all repositories in the development folder that have changes.

View Source
var StatusAllCmd = &cobra.Command{
	Use:   "status-all",
	Short: "Check status of all git repositories in development folder",
	Long:  `This command checks the status of all git repositories found in your development folder.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Start("Checking status of all git repositories")

		isVerbose := utils.IsVerbose(cmd)

		devPath, err := getWorkingPath(cmd)
		if err != nil {
			log.Error("%s", err)
			return
		}

		log.Verbose(isVerbose, "Development path: %s", devPath)

		repos, err := findGitRepositories(devPath)
		if err != nil {
			log.Error("Failed to find git repositories: %s", err)
			return
		}

		if len(repos) == 0 {
			log.Warn("No git repositories found in %s", devPath)
			return
		}

		log.Info("Checking status of %d repositories:", len(repos))

		cleanCount := 0
		dirtyCount := 0

		for _, repoPath := range repos {
			repoName := filepath.Base(repoPath)

			isDirty, err := repo.IsDirty(repoPath)
			if err != nil {
				log.Error("  %s: Failed to check status - %s", repoName, err)
				continue
			}

			if isDirty {
				log.Warn("  %s: Has uncommitted changes", repoName)
				dirtyCount++
			} else {
				log.Success("  %s: Clean", repoName)
				cleanCount++
			}
		}

		log.Info("Status summary: %d clean, %d with uncommitted changes", cleanCount, dirtyCount)
	},
}

StatusAllCmd defines the cobra command for checking status of all git repositories. It shows the status of all repositories in the development folder.

View Source
var SyncAllCmd = &cobra.Command{
	Use:   "sync-all",
	Short: "Sync all git repositories in development folder",
	Long:  `This command fetches and pulls with rebase for all git repositories found in your development folder.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Start("Syncing all git repositories")

		isVerbose := utils.IsVerbose(cmd)
		dryRun, _ := cmd.Flags().GetBool("dry-run")

		devPath, err := getWorkingPath(cmd)
		if err != nil {
			log.Error("%s", err)
			return
		}

		log.Verbose(isVerbose, "Development path: %s", devPath)

		if dryRun {
			log.Info("Dry run mode - no actual git operations will be performed")
		}

		repos, err := findGitRepositories(devPath)
		if err != nil {
			log.Error("Failed to find git repositories: %s", err)
			return
		}

		if len(repos) == 0 {
			log.Warn("No git repositories found in %s", devPath)
			return
		}

		log.Info("Found %d git repositories", len(repos))

		successCount := 0
		failureCount := 0

		for _, repoPath := range repos {
			repoName := filepath.Base(repoPath)
			log.Info("Processing repository: %s", repoName)

			if dryRun {
				log.Info("  [DRY RUN] Would sync repository at: %s", repoPath)
				successCount++
				continue
			}

			isDirty, err := repo.IsDirty(repoPath)
			if err != nil {
				log.Error("  Failed to check repository status: %s", err)
				failureCount++
				continue
			}

			if isDirty {
				log.Warn("  Repository has uncommitted changes, skipping...")
				failureCount++
				continue
			}

			if err := repo.EnsureOnDefaultBranch(repoPath); err != nil {
				log.Error("  Failed to ensure on default branch: %s", err)
				failureCount++
				continue
			}

			if err := repo.PullLatestCode(repoPath); err != nil {
				log.Error("  Failed to pull latest code: %s", err)
				failureCount++
				continue
			}

			log.Success("  Successfully synced %s", repoName)
			successCount++
		}

		log.Info("Sync completed: %d successful, %d failed", successCount, failureCount)

		if failureCount > 0 {
			log.Warn("Some repositories failed to sync. Check the output above for details.")
		} else {
			log.Success("All git repositories synced successfully")
		}
	},
}

SyncAllCmd defines the cobra command for syncing all git repositories. It fetches and pulls with rebase for all repositories in the development folder.

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL