Code Quality: Moved implementation of Git operations into abstraction#18068
Code Quality: Moved implementation of Git operations into abstraction#18068Lamparter wants to merge 4 commits intofiles-community:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces an abstraction layer for Git operations to support future implementation of alternative Git backends (like git.exe), as part of the requirements outlined in issue #16738.
Changes:
- Created
IVersionControlinterface defining the contract for version control operations - Extracted LibGit2Sharp implementation from
GitHelpersstatic class into a newLibGit2class implementingIVersionControl - Refactored
GitHelpersto act as a static facade that delegates all operations to a singletonLibGit2instance
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/Files.App/Utils/Git/IVersionControl.cs | New interface defining the contract for version control operations with comprehensive documentation |
| src/Files.App/Utils/Git/LibGit2.cs | New file containing the LibGit2Sharp implementation moved from GitHelpers, now implementing IVersionControl |
| src/Files.App/Utils/Git/GitHelpers.cs | Refactored to be a thin static wrapper that delegates to IVersionControl implementation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| foreach (TreeEntryChanges c in repository.Diff.Compare<TreeChanges>(repository.Commits.FirstOrDefault()?.Tree, DiffTargets.Index | DiffTargets.WorkingDirectory)) | ||
| { | ||
| if (c.Path.StartsWith(relativePath)) | ||
| { | ||
| changeKind = c.Status; | ||
| break; | ||
| } | ||
| } |
There was a problem hiding this comment.
This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.
| public async Task RequireGitAuthenticationAsync() | ||
| { | ||
| var pending = true; | ||
| var client = new HttpClient(); |
There was a problem hiding this comment.
Disposable 'HttpClient' is created but not disposed.
| var client = new HttpClient(); | |
| using var client = new HttpClient(); |
| { | ||
| var codeResponse = await client.PostAsync( | ||
| $"https://github.com/login/device/code?client_id={_clientId}&scope=repo", | ||
| new StringContent("")); |
There was a problem hiding this comment.
Disposable 'StringContent' is created but not disposed.
| var loginResponse = await client.PostAsync( | ||
| $"https://github.com/login/oauth/access_token?client_id={_clientId}&device_code={deviceCode}&grant_type=urn:ietf:params:oauth:grant-type:device_code", | ||
| new StringContent("")); |
There was a problem hiding this comment.
Disposable 'StringContent' is created but not disposed.
| var loginResponse = await client.PostAsync( | |
| $"https://github.com/login/oauth/access_token?client_id={_clientId}&device_code={deviceCode}&grant_type=urn:ietf:params:oauth:grant-type:device_code", | |
| new StringContent("")); | |
| using var content = new StringContent(""); | |
| var loginResponse = await client.PostAsync( | |
| $"https://github.com/login/oauth/access_token?client_id={_clientId}&device_code={deviceCode}&grant_type=urn:ietf:params:oauth:grant-type:device_code", | |
| content); |
| var (result, returnValue) = await DoGitOperationAsync<(GitOperationResult, BranchItem[])>(() => | ||
| { | ||
| var branches = Array.Empty<BranchItem>(); | ||
| var result = GitOperationResult.Success; | ||
| try | ||
| { | ||
| using var repository = new Repository(path); | ||
|
|
||
| branches = GetValidBranches(repository.Branches) | ||
| .Where(b => !b.IsRemote || b.RemoteName == "origin") | ||
| .OrderByDescending(b => b.Tip?.Committer.When) | ||
| .Take(MAX_NUMBER_OF_BRANCHES) | ||
| .OrderByDescending(b => b.IsCurrentRepositoryHead) | ||
| .Select(b => new BranchItem(b.FriendlyName, b.IsCurrentRepositoryHead, b.IsRemote, TryGetTrackingDetails(b)?.AheadBy ?? 0, TryGetTrackingDetails(b)?.BehindBy ?? 0)) | ||
| .ToArray(); | ||
| } | ||
| catch | ||
| { | ||
| result = GitOperationResult.GenericError; | ||
| } | ||
|
|
||
| return (result, branches); | ||
| }); |
Resolved / Related Issues
Steps used to test these changes
Not yet fully tested on my side, but no changes to the implementation have been made.
This PR continues the (previously removed parts of) #18040 by moving the implementation for GitHelpers via the LibGit2 library into its own separate file (and therefore making use of the
IVersionControlinterface introduced in the previous PR)