Documentation
¶
Overview ¶
Package git provides cobra commands for managing multiple git repositories in a development folder.
Index ¶
Constants ¶
This section is empty.
Variables ¶
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") setup, err := setupGitCommand(cmd) if err != nil { log.Error("%s", err) return } repos, err := findGitRepositories(setup.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", setup.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(cmd.Context(), repoPath) if err != nil { log.Error(" %s: Failed to get current branch - %s", repoName, err) continue } mainBranch, err := repo.GetMainBranch(cmd.Context(), 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.
var CleanAllCmd = &cobra.Command{ Use: "clean-all", Short: "Clean untracked files in all git repositories in development folder", Long: `Preview untracked files across all repos, confirm, then clean. Use --dry-run to preview only, --force with --yes to skip confirmation.`, Example: ` eng git clean-all --dry-run eng git clean-all eng git clean-all --force --yes -d`, Run: func(cmd *cobra.Command, _args []string) { printHeader("🧹 Clean Development Repositories") setup, err := setupGitCommand(cmd) if err != nil { log.Error("%s", err) return } force, _ := cmd.Flags().GetBool("force") assumeYes, _ := cmd.Flags().GetBool("yes") skipConfirm := force || assumeYes directories, _ := cmd.Flags().GetBool("directories") var scanSpinner *ui.Spinner if !ui.DisableProgress { scanSpinner = ui.NewSpinner(fmt.Sprintf( "Scanning git repositories in %s for untracked files...", setup.DevPath, )) scanSpinner.Start() } repos, err := findGitRepositories(setup.DevPath) if err != nil { if scanSpinner != nil { scanSpinner.Fail("Scan failed") } log.Error("Failed to find git repositories: %s", err) return } type RepoCleanSummary struct { Path string Name string UntrackedCount int SizeBytes int64 } var reposToClean []RepoCleanSummary var totalUntrackedBytes int64 for _, repoPath := range repos { untrackedFiles, sizeBytes := getUntrackedFilesAndSize(repoPath) if len(untrackedFiles) > 0 { repoName := filepath.Base(repoPath) reposToClean = append(reposToClean, RepoCleanSummary{ Path: repoPath, Name: repoName, UntrackedCount: len(untrackedFiles), SizeBytes: sizeBytes, }) totalUntrackedBytes += sizeBytes } } if scanSpinner != nil { scanSpinner.Success(fmt.Sprintf("Scanned %d repositories", len(repos))) } if len(reposToClean) == 0 { theme.SuccessMessage("No untracked files found across any development repositories. Everything is clean!") return } totalSizeStr := humanize.Bytes(uint64(totalUntrackedBytes)) // Render Callout Box var boxLines []string boxLines = append(boxLines, fmt.Sprintf( "Found %s repository(ies) with untracked files reclaiming %s space:", theme.PrimaryText.Bold(true).Render(fmt.Sprintf("%d", len(reposToClean))), theme.SuccessText.Bold(true).Render(totalSizeStr), )) for _, r := range reposToClean { sizeStr := "" if r.SizeBytes > 0 { sizeStr = fmt.Sprintf(" (%s)", humanize.Bytes(uint64(r.SizeBytes))) } boxLines = append(boxLines, fmt.Sprintf( " • %s: %s untracked file(s)%s", theme.BoldText.Render(r.Name), theme.MutedText.Render(fmt.Sprintf("%d", r.UntrackedCount)), theme.MutedText.Render(sizeStr), )) } if !ui.DisableProgress { fmt.Fprintln(log.Out, theme.InfoBox.Render(strings.Join(boxLines, "\n"))) } if setup.DryRun { theme.InfoMessage( fmt.Sprintf( "Dry run complete. Previewed cleaning %d repository(ies) reclaiming %s disk space.", len(reposToClean), totalSizeStr, ), ) return } if !skipConfirm { confirmMsg := fmt.Sprintf( "Clean untracked files across %d repository(ies) to reclaim %s?", len(reposToClean), totalSizeStr, ) confirmed, err := ui.Confirm(confirmMsg, false) if err != nil || !confirmed { log.Info("Clean operation canceled.") return } } totalCount := len(reposToClean) var progressSpinner *ui.Spinner if !ui.DisableProgress { progressSpinner = ui.NewProgressSpinner(fmt.Sprintf("Cleaning %d git repository(ies)...", totalCount)) } var successCount int var failureCount int var freedBytes int64 for i, r := range reposToClean { ratio := float64(i+1) / float64(totalCount) statusMsg := fmt.Sprintf("[%d/%d] Cleaning %s", i+1, totalCount, r.Name) if progressSpinner != nil { progressSpinner.SetProgressBar(ratio, statusMsg) } if err := cleanRepository(r.Path, directories); err != nil { failureCount++ if progressSpinner != nil { progressSpinner.Logf(" %s Failed to clean %s: %v\n", theme.ErrorText.Render("✗"), r.Name, err) } else { log.Error("Failed to clean %s: %v", r.Name, err) } } else { successCount++ freedBytes += r.SizeBytes sizeStr := "" if r.SizeBytes > 0 { sizeStr = fmt.Sprintf(" (freed %s)", humanize.Bytes(uint64(r.SizeBytes))) } if progressSpinner != nil { progressSpinner.Logf(" %s Cleaned %s%s\n", theme.SuccessText.Render("✓"), r.Name, sizeStr) } else { log.Success("Cleaned %s%s", r.Name, sizeStr) } } } if progressSpinner != nil { progressSpinner.SetProgressBar(1.0, "Cleaning complete") progressSpinner.Stop() } freedStr := humanize.Bytes(uint64(freedBytes)) if failureCount > 0 { theme.WarningMessage( fmt.Sprintf( "Cleaned %d repository(ies) freeing %s, but %d failed.", successCount, freedStr, failureCount, ), ) } else { theme.SuccessMessage( fmt.Sprintf( "Successfully cleaned %d git repository(ies) freeing %s of disk space!", successCount, freedStr, ), ) } }, }
CleanAllCmd defines the cobra command for cleaning untracked files in all git repositories.
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) { printHeader("🔍 Fetching Git Repositories") setup, err := setupGitCommand(cmd) if err != nil { log.Error("%s", err) return } repos, err := findGitRepositories(setup.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", setup.DevPath) return } log.Info("Found %d git repositories", len(repos)) logPath, stopLog := runlog.Start("git-fetch-all") defer stopLog() defer runlog.Finish(logPath) var successCount atomic.Int32 var failureCount atomic.Int32 multi, err := ui.NewMultiSpinner() if err != nil { log.Error("Failed to initialize UI: %s", err) return } defer multi.Stop() var eg errgroup.Group eg.SetLimit(10) for _, repoPath := range repos { rPath := repoPath eg.Go(func() error { repoName := filepath.Base(rPath) if setup.DryRun { spinner := multi.AddSpinner(fmt.Sprintf("[DRY RUN] Would fetch repository at: %s", rPath)) spinner.Success() successCount.Add(1) return nil } spinner := multi.AddSpinner(fmt.Sprintf("Fetching %s...", repoName)) if err := fetchRepository(rPath); err != nil { spinner.Fail(fmt.Sprintf("Failed to fetch %s: %s", repoName, err)) failureCount.Add(1) return nil } spinner.Success(fmt.Sprintf("Fetched %s", repoName)) successCount.Add(1) return nil }) } _ = eg.Wait() multi.Stop() summaryMsg := fmt.Sprintf( "Fetch completed: %d successful, %d failed across %d repositories.", successCount.Load(), failureCount.Load(), len(repos), ) if failureCount.Load() > 0 { theme.WarningMessage(summaryMsg) } else { theme.SuccessMessage(summaryMsg) } }, }
FetchAllCmd defines the cobra command for fetching all git repositories. It fetches updates from remote for all repositories in the development folder.
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 := cmdutil.IsVerbose(cmd) if showInfo { log.Info("Current git repository management configuration:") gitCfg := config.GetGitConfig() devPath := gitCfg.DevPath if devPath == "" { log.Warn(" Development Path: Not Set") log.Info(" Use 'eng config git-dev-path' to set your development folder path") } else { log.Info(" Development Path: %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.
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) { printHeader("📁 Development Git Repositories") setup, err := setupGitCommand(cmd) if err != nil { log.Error("%s", err) return } showPaths, _ := cmd.Flags().GetBool("paths") repos, err := findGitRepositories(setup.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", setup.DevPath) return } var cardLines []string cardLines = append(cardLines, fmt.Sprintf("Found %s repositories in %s:", theme.PrimaryText.Bold(true).Render(fmt.Sprintf("%d", len(repos))), theme.BoldText.Render(setup.DevPath), )) cardLines = append(cardLines, "") for i, repoPath := range repos { repoName := filepath.Base(repoPath) branch := getRepoBranch(repoPath) if showPaths { cardLines = append(cardLines, fmt.Sprintf(" %-3d %-25s %-15s %s", i+1, theme.PrimaryText.Render(repoName), theme.MutedText.Render(branch), theme.BaseText.Render(repoPath), )) } else { cardLines = append(cardLines, fmt.Sprintf(" %-3d %-25s %s", i+1, theme.PrimaryText.Render(repoName), theme.MutedText.Render(branch), )) } } if !ui.DisableProgress { boxStyle := lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(theme.Primary). Padding(0, 1). MarginBottom(1) fmt.Fprintln(log.Out, boxStyle.Render(strings.Join(cardLines, "\n"))) } else { for _, line := range cardLines { log.Info("%s", line) } } theme.SuccessMessage(fmt.Sprintf("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.
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) { printHeader("📥 Pulling Git Repositories") setup, err := setupGitCommand(cmd) if err != nil { log.Error("%s", err) return } repos, err := findGitRepositories(setup.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", setup.DevPath) return } log.Info("Found %d git repositories", len(repos)) logPath, stopLog := runlog.Start("git-pull-all") defer stopLog() defer runlog.Finish(logPath) var successCount atomic.Int32 var failureCount atomic.Int32 multi, err := ui.NewMultiSpinner() if err != nil { log.Error("Failed to initialize UI: %s", err) return } defer multi.Stop() var eg errgroup.Group eg.SetLimit(10) for _, repoPath := range repos { rPath := repoPath eg.Go(func() error { repoName := filepath.Base(rPath) if setup.DryRun { spinner := multi.AddSpinner(fmt.Sprintf("[DRY RUN] Would pull repository at: %s", rPath)) spinner.Success() successCount.Add(1) return nil } spinner := multi.AddSpinner(fmt.Sprintf("Pulling %s...", repoName)) isDirty, err := repo.IsDirty(cmd.Context(), rPath) if err != nil { spinner.Fail(fmt.Sprintf("Failed to check status for %s: %s", repoName, err)) failureCount.Add(1) return nil } if isDirty { spinner.Warning(fmt.Sprintf("Repository %s has uncommitted changes, skipping...", repoName)) failureCount.Add(1) return nil } if err := pullRepository(rPath); err != nil { spinner.Fail(fmt.Sprintf("Failed to pull %s: %s", repoName, err)) failureCount.Add(1) return nil } spinner.Success(fmt.Sprintf("Successfully pulled %s", repoName)) successCount.Add(1) return nil }) } _ = eg.Wait() multi.Stop() summaryMsg := fmt.Sprintf( "Pull completed: %d successful, %d failed across %d repositories.", successCount.Load(), failureCount.Load(), len(repos), ) if failureCount.Load() > 0 { theme.WarningMessage(summaryMsg) } else { theme.SuccessMessage(summaryMsg) } }, }
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).
var PushAllCmd = &cobra.Command{ Use: "push-all", Short: "Push all git repositories in development folder", Long: `Push commits for all git repositories in your development folder that have unpushed commits. Use --dry-run to preview, --force only with --yes confirmation for force-with-lease pushes.`, Example: ` eng git push-all --dry-run eng git push-all eng git push-all --force --yes`, Run: func(cmd *cobra.Command, args []string) { printHeader("📤 Pushing Git Repositories") setup, err := setupGitCommand(cmd) if err != nil { log.Error("%s", err) return } force, _ := cmd.Flags().GetBool("force") assumeYes, _ := cmd.Flags().GetBool("yes") if force { log.Warn("Force push mode enabled — uses --force-with-lease across all repos") if !assumeYes && !setup.DryRun { confirmed, err := ui.Confirm( "Force-push all repos with unpushed commits? This rewrites remote history.", false, ) if err != nil || !confirmed { log.Info("Push operation canceled.") return } } } repos, err := findGitRepositories(setup.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", setup.DevPath) return } log.Info("Found %d git repositories", len(repos)) logPath, stopLog := runlog.Start("git-push-all") defer stopLog() defer runlog.Finish(logPath) successCount := 0 failureCount := 0 skippedCount := 0 for _, repoPath := range repos { repoName := filepath.Base(repoPath) log.Verbose(setup.IsVerbose, "Checking repository: %s", repoName) if setup.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.Verbose(setup.IsVerbose, " [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.Verbose(setup.IsVerbose, " No unpushed commits, skipping: %s", repoName) skippedCount++ continue } isDirty, err := repo.IsDirty(cmd.Context(), repoPath) if err != nil { log.Error(" Failed to check repository status: %s", err) failureCount++ continue } if isDirty { log.Warn(" Repository %s has uncommitted changes, but proceeding with push...", repoName) } 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++ } summaryMsg := fmt.Sprintf( "Push completed: %d successful, %d failed, %d skipped across %d repositories.", successCount, failureCount, skippedCount, len(repos), ) if failureCount > 0 { theme.WarningMessage(summaryMsg) } else { theme.SuccessMessage(summaryMsg) } }, }
PushAllCmd defines the cobra command for pushing all git repositories. It pushes commits for all repositories in the development folder that have unpushed commits.
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") setup, err := setupGitCommand(cmd) if err != nil { log.Error("%s", err) return } message, _ := cmd.Flags().GetString("message") repos, err := findGitRepositories(setup.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", setup.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 setup.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.
var StatusAllCmd = &cobra.Command{ Use: "status-all", Short: "Check status of all git repositories in development folder", Long: `Check working-tree status across all git repositories in your development folder. Use --current to scan the current directory.`, Example: ` eng git status-all eng git status-all --current`, Run: func(cmd *cobra.Command, _args []string) { printHeader("📊 Development Repositories Status") setup, err := setupGitCommand(cmd) if err != nil { log.Error("%s", err) return } var scanSpinner *ui.Spinner if !ui.DisableProgress { scanSpinner = ui.NewSpinner(fmt.Sprintf("Scanning git repositories in %s...", setup.DevPath)) scanSpinner.Start() } repos, err := findGitRepositories(setup.DevPath) if err != nil { if scanSpinner != nil { scanSpinner.Fail("Scan failed") } log.Error("Failed to find git repositories: %s", err) return } if scanSpinner != nil { scanSpinner.Success(fmt.Sprintf("Scanned %d repositories", len(repos))) } if len(repos) == 0 { log.Warn("No git repositories found in %s", setup.DevPath) return } type RepoStatusSummary struct { Name string Branch string IsDirty bool } var summaries []RepoStatusSummary cleanCount := 0 dirtyCount := 0 for _, repoPath := range repos { repoName := filepath.Base(repoPath) branch := getRepoBranch(repoPath) isDirty, err := repo.IsDirty(cmd.Context(), repoPath) if err != nil { log.Error(" %s: Failed to check status - %s", repoName, err) continue } if isDirty { dirtyCount++ } else { cleanCount++ } summaries = append(summaries, RepoStatusSummary{ Name: repoName, Branch: branch, IsDirty: isDirty, }) } // Render Lipgloss Table Box var boxLines []string boxLines = append(boxLines, fmt.Sprintf("Checked %s repository(ies) in %s:", theme.PrimaryText.Bold(true).Render(fmt.Sprintf("%d", len(repos))), theme.BoldText.Render(setup.DevPath), )) boxLines = append(boxLines, "") boxLines = append(boxLines, fmt.Sprintf(" %-30s %-20s %s", theme.BoldText.Render("Repository"), theme.BoldText.Render("Branch"), theme.BoldText.Render("Status"), )) boxLines = append(boxLines, " "+strings.Repeat("─", 65)) for _, s := range summaries { statusTag := theme.SuccessText.Render("✓ Clean") if s.IsDirty { statusTag = theme.ErrorText.Render("⚠️ Uncommitted Changes") } boxLines = append(boxLines, fmt.Sprintf(" %-30s %-20s %s", theme.PrimaryText.Render(s.Name), theme.MutedText.Render(s.Branch), statusTag, )) } if !ui.DisableProgress { fmt.Fprintln(log.Out, theme.InfoBox.Render(strings.Join(boxLines, "\n"))) } summaryMsg := fmt.Sprintf( "Status summary: %d clean, %d with uncommitted changes across %d repositories.", cleanCount, dirtyCount, len(repos), ) if dirtyCount > 0 { theme.WarningMessage(summaryMsg) } else { theme.SuccessMessage(summaryMsg) } }, }
StatusAllCmd defines the cobra command for checking status of all git repositories.
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) { printHeader("🔄 Syncing Git Repositories") setup, err := setupGitCommand(cmd) if err != nil { log.Error("%s", err) return } repos, err := findGitRepositories(setup.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", setup.DevPath) return } log.Info("Found %d git repositories", len(repos)) logPath, stopLog := runlog.Start("git-sync-all") defer stopLog() defer runlog.Finish(logPath) var successCount atomic.Int32 var failureCount atomic.Int32 multi, err := ui.NewMultiSpinner() if err != nil { log.Error("Failed to initialize UI: %s", err) return } defer multi.Stop() var eg errgroup.Group eg.SetLimit(10) for _, repoPath := range repos { rPath := repoPath eg.Go(func() error { repoName := filepath.Base(rPath) if setup.DryRun { spinner := multi.AddSpinner(fmt.Sprintf("[DRY RUN] Would sync repository at: %s", rPath)) spinner.Success() successCount.Add(1) return nil } spinner := multi.AddSpinner(fmt.Sprintf("Processing %s...", repoName)) isDirty, err := repo.IsDirty(cmd.Context(), rPath) if err != nil { spinner.Fail(fmt.Sprintf("Failed to check status for %s: %s", repoName, err)) failureCount.Add(1) return nil } if isDirty { spinner.Warning(fmt.Sprintf("Repository %s has uncommitted changes, skipping...", repoName)) failureCount.Add(1) return nil } spinner.UpdateText(fmt.Sprintf("Pulling %s...", repoName)) if err := repo.PullLatestCode(cmd.Context(), rPath); err != nil { spinner.Fail(fmt.Sprintf("Failed to pull latest code for %s: %s", repoName, err)) failureCount.Add(1) return nil } spinner.Success(fmt.Sprintf("Successfully synced %s", repoName)) successCount.Add(1) return nil }) } _ = eg.Wait() multi.Stop() summaryMsg := fmt.Sprintf( "Sync completed: %d successful, %d failed across %d repositories.", successCount.Load(), failureCount.Load(), len(repos), ) if failureCount.Load() > 0 { theme.WarningMessage(summaryMsg) } else { theme.SuccessMessage(summaryMsg) } }, }
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 ¶
type GitCommandSetup ¶ added in v1.34.0
GitCommandSetup holds common variables and flags resolved during git command initialization.