From 702528d8e16b702bccc70df3ddfee687391e2955 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 24 Jun 2025 01:30:19 +0300 Subject: feat: add branch exclusion feature with regex patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Users can now exclude branches from synchronization using regex patterns in the configuration file. This is useful for: - Excluding temporary or experimental branches - Skipping vendor or third-party branches - Ignoring deployment-specific branches Configuration example: ```json { "exclude_branches": [ "^codex/", // Exclude branches starting with "codex/" "^temp-", // Exclude branches starting with "temp-" "-wip$" // Exclude branches ending with "-wip" ] } ``` Features: - Regex pattern matching for flexible exclusion rules - Clear reporting of excluded branches during sync - Excluded branches are filtered from sync but still analyzed for abandonment - Invalid regex patterns are reported but don't stop sync The feature helps maintain cleaner synchronization by allowing users to ignore branches that shouldn't be synchronized across all repositories. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- internal/sync/sync.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'internal/sync/sync.go') diff --git a/internal/sync/sync.go b/internal/sync/sync.go index 4d46ca8..b413318 100644 --- a/internal/sync/sync.go +++ b/internal/sync/sync.go @@ -16,15 +16,25 @@ type Syncer struct { workDir string repoName string abandonedReports map[string]*AbandonedBranchReport // Collects reports across repos + branchFilter *BranchFilter // Filter for excluding branches } // CLAUDE: Is there a reason, we return a pointer to Syncer? // New creates a new Syncer instance func New(cfg *config.Config, workDir string) *Syncer { + // Create branch filter + branchFilter, err := NewBranchFilter(cfg.ExcludeBranches) + if err != nil { + // Log error but continue without filter + fmt.Printf("Warning: Failed to create branch filter: %v\n", err) + branchFilter = &BranchFilter{} + } + return &Syncer{ config: cfg, workDir: workDir, abandonedReports: make(map[string]*AbandonedBranchReport), + branchFilter: branchFilter, } } @@ -57,11 +67,20 @@ func (s *Syncer) SyncRepository(repoName string) error { } // Get all branches - branches, err := s.getAllBranches() + allBranches, err := s.getAllBranches() if err != nil { return fmt.Errorf("failed to get branches: %w", err) } + // Filter branches based on exclusion patterns + branches := s.branchFilter.FilterBranches(allBranches) + excludedBranches := s.branchFilter.GetExcludedBranches(allBranches) + + // Report excluded branches if any + if exclusionReport := FormatExclusionReport(excludedBranches, s.config.ExcludeBranches); exclusionReport != "" { + fmt.Print(exclusionReport) + } + // Get remotes map remotes := s.getRemotesMap() -- cgit v1.2.3