Skip to content

Commit b0bc6d5

Browse files
committed
refactor: Begin Repository.cs restructuring with partial class and interface
- Create IRepositoryService interface to define repository contract - Convert Repository class to partial class for future splitting - Add comprehensive refactoring plan document - Prepare foundation for extracting repository operations into separate files This is the first step in breaking down the 2549-line Repository.cs file into more manageable, focused partial class files following SOLID principles.
1 parent 62a62a9 commit b0bc6d5

File tree

3 files changed

+194
-1
lines changed

3 files changed

+194
-1
lines changed

REFACTORING_PLAN.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Repository.cs Refactoring Plan
2+
3+
## Current State
4+
- Repository.cs has 2549 lines of code
5+
- Successfully converted to partial class
6+
- Build is working
7+
8+
## Refactoring Strategy
9+
10+
### Phase 1: Preparation ✅ COMPLETED
11+
- [x] Create IRepositoryService interface
12+
- [x] Convert Repository.cs to partial class declaration
13+
- [x] Ensure build still works
14+
15+
### Phase 2: Gradual Extraction (RECOMMENDED APPROACH)
16+
17+
#### Step 1: Extract Refresh Operations
18+
Create `Repository.Refresh.cs` with:
19+
- RefreshAfterOperation()
20+
- RefreshAll()
21+
- RefreshBranches()
22+
- RefreshTags()
23+
- RefreshCommits()
24+
- RefreshWorkingCopyChanges()
25+
- RefreshStashes()
26+
- RefreshSubmodules()
27+
- RefreshWorktrees()
28+
29+
**Note**: These methods have complex dependencies on internal fields and other methods. Need careful extraction.
30+
31+
#### Step 2: Extract Git Operations
32+
Create `Repository.GitOperations.cs` with:
33+
- FetchAsync()
34+
- PullAsync()
35+
- PushAsync()
36+
- CheckoutBranchAsync()
37+
- CreateBranch()
38+
- DeleteBranch()
39+
- MergeMultipleBranches()
40+
41+
#### Step 3: Extract Branch Management
42+
Create `Repository.Branches.cs` with:
43+
- Branch tree building methods
44+
- Branch filtering methods
45+
- GitFlow related methods
46+
- Branch context menu creation
47+
48+
#### Step 4: Extract UI/Popup Management
49+
Create `Repository.UI.cs` with:
50+
- ShowPopup()
51+
- ShowAndStartPopupAsync()
52+
- CanCreatePopup()
53+
- All popup creation methods
54+
55+
#### Step 5: Extract Search Operations
56+
Create `Repository.Search.cs` with:
57+
- StartSearchCommits()
58+
- CalcWorktreeFilesForSearching()
59+
- CalcMatchedFilesForSearching()
60+
- Search-related properties
61+
62+
## Key Challenges Identified
63+
64+
1. **Complex Dependencies**: Methods are tightly coupled with private fields and other methods
65+
2. **UI Thread Dispatching**: Many methods use Dispatcher.UIThread.Invoke
66+
3. **Async/Await Patterns**: Mix of synchronous and asynchronous operations
67+
4. **State Management**: Extensive use of private fields that need to be accessible across partial classes
68+
69+
## Recommendations
70+
71+
1. **Start Small**: Begin with methods that have fewer dependencies
72+
2. **Test Incrementally**: Build and test after each extraction
73+
3. **Keep Related Methods Together**: Group methods that work closely together
74+
4. **Document Dependencies**: Note which fields and methods each extracted group needs
75+
5. **Consider Service Pattern**: Eventually move to service-based architecture for better separation
76+
77+
## Alternative Approach: Service-Based Architecture
78+
79+
Instead of just splitting into partial classes, consider:
80+
81+
1. **Create Service Interfaces**:
82+
- IGitOperationService
83+
- IRefreshService
84+
- IBranchManagementService
85+
- ISearchService
86+
87+
2. **Implement Services**: Each service handles its specific domain
88+
89+
3. **Use Dependency Injection**: Repository becomes a coordinator that delegates to services
90+
91+
4. **Benefits**:
92+
- Better testability
93+
- Clear separation of concerns
94+
- Easier to maintain and extend
95+
- Follows SOLID principles
96+
97+
## Next Steps
98+
99+
1. Attempt careful extraction of refresh methods with proper dependency handling
100+
2. If extraction proves too complex, maintain current structure but document sections
101+
3. Consider gradual migration to service pattern over time
102+
4. Add unit tests for extracted components
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using Avalonia.Collections;
5+
6+
namespace SourceGit.ViewModels
7+
{
8+
/// <summary>
9+
/// Interface defining core repository services and operations
10+
/// </summary>
11+
public interface IRepositoryService
12+
{
13+
// Core Properties
14+
string FullPath { get; }
15+
string GitDir { get; }
16+
bool IsBare { get; }
17+
Models.RepositorySettings Settings { get; }
18+
19+
// Branch Management
20+
Models.Branch CurrentBranch { get; }
21+
AvaloniaList<Models.Branch> Branches { get; }
22+
AvaloniaList<BranchTreeNode> LocalBranchTrees { get; }
23+
AvaloniaList<BranchTreeNode> RemoteBranchTrees { get; }
24+
25+
// Remote Management
26+
AvaloniaList<Models.Remote> Remotes { get; }
27+
28+
// Tag Management
29+
AvaloniaList<Models.Tag> Tags { get; }
30+
AvaloniaList<Models.Tag> VisibleTags { get; }
31+
32+
// Working Copy
33+
WorkingCopy WorkingCopy { get; }
34+
35+
// Stash Management
36+
List<Models.Stash> Stashes { get; }
37+
38+
// Submodule Management
39+
List<Models.Submodule> Submodules { get; }
40+
41+
// Core Operations
42+
void Close();
43+
void OpenInFileManager();
44+
void OpenInTerminal();
45+
46+
// Refresh Operations
47+
Task RefreshBranches();
48+
Task RefreshTags();
49+
Task RefreshCommits();
50+
Task RefreshWorkingCopy();
51+
Task RefreshStashes();
52+
Task RefreshRemotes();
53+
Task RefreshSubmodules();
54+
Task RefreshAfterOperation(Models.RefreshOptions options);
55+
56+
// Git Operations
57+
bool Fetch(Models.Remote remote, bool prune, bool noTags, Action<string> onProgress);
58+
bool Pull(Models.Branch branch, Action<string> onProgress);
59+
bool Push(Models.Branch branch, bool force, bool withTags, Action<string> onProgress);
60+
bool Checkout(string target);
61+
bool CreateBranch(string name, string basedOn);
62+
bool DeleteBranch(Models.Branch branch, bool force);
63+
bool CreateTag(string name, string basedOn, string message);
64+
bool DeleteTag(Models.Tag tag);
65+
66+
// Stash Operations
67+
bool Stash(bool includeUntracked, string message);
68+
bool ApplyStash(Models.Stash stash);
69+
bool DropStash(Models.Stash stash);
70+
71+
// Submodule Operations
72+
bool AddSubmodule(string url, string path);
73+
bool UpdateSubmodule(string path);
74+
bool RemoveSubmodule(string path);
75+
76+
// History Navigation
77+
void NavigateToCommit(string sha);
78+
void NavigateToBranch(Models.Branch branch);
79+
void NavigateToTag(Models.Tag tag);
80+
81+
// Search Operations
82+
void SearchCommits(string query);
83+
void ClearSearchFilter();
84+
85+
// UI State Management
86+
void SetWatcherEnabled(bool enabled);
87+
void MarkBranchesDirty();
88+
void MarkTagsDirty();
89+
void MarkWorkingCopyDirty();
90+
}
91+
}

src/ViewModels/Repository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace SourceGit.ViewModels
1616
{
17-
public class Repository : ObservableObject, Models.IRepository
17+
public partial class Repository : ObservableObject, Models.IRepository
1818
{
1919
public bool IsBare
2020
{

0 commit comments

Comments
 (0)