Extract branch changes calculation logic into separate class
<!--IssueSummary start-->
<details>
<summary>
Everyone can contribute. [Help move this issue forward](https://handbook.gitlab.com/handbook/marketing/developer-relations/contributor-success/community-contributors-workflows/#contributor-links) while earning points, leveling up and collecting rewards.
</summary>
- [Close this issue](https://contributors.gitlab.com/manage-issue?action=close&projectId=278964&issueIid=561037)
</details>
<!--IssueSummary end-->
## Summary
As a follow-up to !198736 (LFS mirroring timeout issue), we should extract the branch changes calculation logic from `Projects::UpdateMirrorService` into a dedicated class for better separation of concerns and maintainability.
## Background
In !198736, we added logic to calculate which branches have changed during mirroring to optimize LFS object processing. Currently, this logic is embedded within the `UpdateMirrorService`, but it doesn't directly belong to the mirroring logic and could be extracted for better code organization.
## Proposal
Create a new service class to handle branch changes calculation: :warning: suggested by Duo :warning:
```ruby
# app/services/projects/repository/branch_changes_calculator.rb
module Projects
module Repository
class BranchChangesCalculator
def initialize(project)
@project = project
end
def calculate_changed_revisions(local_branches)
# Move the logic from UpdateMirrorService here
end
private
def get_remote_branches
# Extract from UpdateMirrorService
end
end
end
end
```
## Benefits
- **Single Responsibility**: Separates branch comparison logic from mirroring orchestration
- **Testability**: Easier to unit test branch calculation logic in isolation
- **Reusability**: Could be used by other services that need to detect branch changes
- **Maintainability**: Cleaner, more focused code in both classes
## Implementation Details
The new class should handle:
- Comparing local vs remote branch states
- Generating appropriate revision formats (commit ranges vs full refs)
- Applying thresholds for fallback to `--all`
## Related
- Original MR: !198736
- Related issue: #415229
issue