From 67aee2e56dfefe48b513448b68b0504a40003585 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sat, 28 Mar 2026 18:50:11 +0100 Subject: [PATCH 01/13] refactor: simplify and modernize class initializations by switching to primary constructors - Transitioned several classes to use primary constructors, reducing boilerplate code. - Enabled nullable reference types across multiple projects for improved type safety. - Updated namespace references to streamline imports and align with project structure changes. --- source/Directory.Build.props | 13 +++---- .../CreativeCoders.Git.Abstractions.csproj | 5 --- .../ServiceCollectionExtensions.cs | 2 +- .../Auth/DefaultGitCredentialProviders.cs | 9 ++--- .../CreativeCoders.Git/Auth/GitCredential.cs | 14 +++----- .../Auth/GitCredentialsHandler.cs | 12 ++----- .../Branches/GitBranchCollection.cs | 2 +- .../CreativeCoders.Git.csproj | 4 --- .../DefaultGitRepositoryFactory.cs | 20 +++++------ .../CreativeCoders.Git/GitRepositoryInfo.cs | 19 +++-------- .../Git/CreativeCoders.Git/ILibGitCaller.cs | 1 + .../CreativeCoders.Git/RepositoryContext.cs | 34 +++++++------------ source/Git/Directory.Build.props | 15 ++++---- .../GitToolsServiceCollectionExtensions.cs | 4 +-- .../ServiceCollectionExtensionsTests.cs | 3 +- tests/Directory.Build.props | 11 +++--- 16 files changed, 61 insertions(+), 107 deletions(-) rename source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/{DependencyInjection => }/ServiceCollectionExtensions.cs (88%) diff --git a/source/Directory.Build.props b/source/Directory.Build.props index df8fb07..9decc12 100644 --- a/source/Directory.Build.props +++ b/source/Directory.Build.props @@ -1,8 +1,9 @@ - - net10.0 - CreativeCoders - False - $(NoWarn);IDE0079 - + + net10.0 + CreativeCoders + False + $(NoWarn);IDE0079 + enable + \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/CreativeCoders.Git.Abstractions.csproj b/source/Git/CreativeCoders.Git.Abstractions/CreativeCoders.Git.Abstractions.csproj index 4c6061a..6425d77 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/CreativeCoders.Git.Abstractions.csproj +++ b/source/Git/CreativeCoders.Git.Abstractions/CreativeCoders.Git.Abstractions.csproj @@ -10,9 +10,4 @@ - - - - - diff --git a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DependencyInjection/ServiceCollectionExtensions.cs b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/ServiceCollectionExtensions.cs similarity index 88% rename from source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DependencyInjection/ServiceCollectionExtensions.cs rename to source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/ServiceCollectionExtensions.cs index 235ead0..ea5dcf3 100644 --- a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DependencyInjection/ServiceCollectionExtensions.cs +++ b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/ServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -namespace CreativeCoders.Git.Auth.CredentialManagerCore.DependencyInjection; +namespace CreativeCoders.Git.Auth.CredentialManagerCore; [PublicAPI] public static class ServiceCollectionExtensions diff --git a/source/Git/CreativeCoders.Git/Auth/DefaultGitCredentialProviders.cs b/source/Git/CreativeCoders.Git/Auth/DefaultGitCredentialProviders.cs index ee94880..3f83098 100644 --- a/source/Git/CreativeCoders.Git/Auth/DefaultGitCredentialProviders.cs +++ b/source/Git/CreativeCoders.Git/Auth/DefaultGitCredentialProviders.cs @@ -3,14 +3,9 @@ namespace CreativeCoders.Git.Auth; -internal class DefaultGitCredentialProviders : IGitCredentialProviders +internal class DefaultGitCredentialProviders(IEnumerable providers) : IGitCredentialProviders { - private readonly IEnumerable _providers; - - public DefaultGitCredentialProviders(IEnumerable providers) - { - _providers = Ensure.NotNull(providers); - } + private readonly IEnumerable _providers = Ensure.NotNull(providers); public IGitCredentialProvider? GetProvider(string providerName) { diff --git a/source/Git/CreativeCoders.Git/Auth/GitCredential.cs b/source/Git/CreativeCoders.Git/Auth/GitCredential.cs index 66a91b7..be5669e 100644 --- a/source/Git/CreativeCoders.Git/Auth/GitCredential.cs +++ b/source/Git/CreativeCoders.Git/Auth/GitCredential.cs @@ -4,15 +4,9 @@ namespace CreativeCoders.Git.Auth; [ExcludeFromCodeCoverage] -public class GitCredential : IGitCredential +public class GitCredential(string userName, string password) : IGitCredential { - public GitCredential(string userName, string password) - { - UserName = userName; - Password = password; - } + public string UserName { get; } = userName; - public string UserName { get; } - - public string Password { get; } -} \ No newline at end of file + public string Password { get; } = password; +} diff --git a/source/Git/CreativeCoders.Git/Auth/GitCredentialsHandler.cs b/source/Git/CreativeCoders.Git/Auth/GitCredentialsHandler.cs index cb8e5e7..a93877e 100644 --- a/source/Git/CreativeCoders.Git/Auth/GitCredentialsHandler.cs +++ b/source/Git/CreativeCoders.Git/Auth/GitCredentialsHandler.cs @@ -3,17 +3,9 @@ namespace CreativeCoders.Git.Auth; -public class GitCredentialsHandler +public class GitCredentialsHandler(IGitCredentialProviders credentialProviders) { - private readonly IGitCredentialProviders _credentialProviders; - - public GitCredentialsHandler(IGitCredentialProviders credentialProviders) - { - _credentialProviders = Ensure - .Argument(credentialProviders) - .NotNull() - .Value; - } + private readonly IGitCredentialProviders _credentialProviders = Ensure.NotNull(credentialProviders); public Credentials? HandleCredentials(string url, string? usernameFromUrl, SupportedCredentialTypes types) { diff --git a/source/Git/CreativeCoders.Git/Branches/GitBranchCollection.cs b/source/Git/CreativeCoders.Git/Branches/GitBranchCollection.cs index 2bb4858..d524bdb 100644 --- a/source/Git/CreativeCoders.Git/Branches/GitBranchCollection.cs +++ b/source/Git/CreativeCoders.Git/Branches/GitBranchCollection.cs @@ -16,7 +16,7 @@ internal GitBranchCollection(RepositoryContext context) _context = Ensure.NotNull(context); _branchCollection = _context.LibGitRepository.Branches; - _libGitCaller = context.LibGitCaller; + _libGitCaller = _context.LibGitCaller; } public IGitBranch? CheckOut(string branchName) diff --git a/source/Git/CreativeCoders.Git/CreativeCoders.Git.csproj b/source/Git/CreativeCoders.Git/CreativeCoders.Git.csproj index 176c451..f963617 100644 --- a/source/Git/CreativeCoders.Git/CreativeCoders.Git.csproj +++ b/source/Git/CreativeCoders.Git/CreativeCoders.Git.csproj @@ -14,8 +14,4 @@ - - - - diff --git a/source/Git/CreativeCoders.Git/DefaultGitRepositoryFactory.cs b/source/Git/CreativeCoders.Git/DefaultGitRepositoryFactory.cs index e3bbe80..f9f9ed0 100644 --- a/source/Git/CreativeCoders.Git/DefaultGitRepositoryFactory.cs +++ b/source/Git/CreativeCoders.Git/DefaultGitRepositoryFactory.cs @@ -5,21 +5,17 @@ namespace CreativeCoders.Git; -internal class DefaultGitRepositoryFactory : IGitRepositoryFactory +internal class DefaultGitRepositoryFactory( + IGitCredentialProviders credentialProviders, + IGitRepositoryUtils repositoryUtils, + IServiceProvider serviceProvider) + : IGitRepositoryFactory { - private readonly IGitCredentialProviders _credentialProviders; + private readonly IGitCredentialProviders _credentialProviders = Ensure.NotNull(credentialProviders); - private readonly IGitRepositoryUtils _repositoryUtils; + private readonly IGitRepositoryUtils _repositoryUtils = Ensure.NotNull(repositoryUtils); - private readonly IServiceProvider _serviceProvider; - - public DefaultGitRepositoryFactory(IGitCredentialProviders credentialProviders, - IGitRepositoryUtils repositoryUtils, IServiceProvider serviceProvider) - { - _credentialProviders = Ensure.NotNull(credentialProviders); - _repositoryUtils = Ensure.NotNull(repositoryUtils); - _serviceProvider = Ensure.NotNull(serviceProvider); - } + private readonly IServiceProvider _serviceProvider = Ensure.NotNull(serviceProvider); public IGitRepository OpenRepository(string? path) { diff --git a/source/Git/CreativeCoders.Git/GitRepositoryInfo.cs b/source/Git/CreativeCoders.Git/GitRepositoryInfo.cs index bcd65ab..c458ea2 100644 --- a/source/Git/CreativeCoders.Git/GitRepositoryInfo.cs +++ b/source/Git/CreativeCoders.Git/GitRepositoryInfo.cs @@ -2,17 +2,8 @@ namespace CreativeCoders.Git; -internal class GitRepositoryInfo : IGitRepositoryInfo +internal class GitRepositoryInfo(IRepository repository) : IGitRepositoryInfo { - public GitRepositoryInfo(IRepository repository) - { - Path = repository.Info.Path; - - MainBranch = GetMainBranch(repository); - - RemoteUri = new Uri(repository.Network.Remotes[GitRemotes.Origin].Url); - } - private static GitMainBranch GetMainBranch(IRepository repository) { var mainBranch = repository.Branches[GitBranchNames.Remote.Main.CanonicalName]; @@ -29,9 +20,9 @@ private static GitMainBranch GetMainBranch(IRepository repository) : GitMainBranch.Custom; } - public string? Path { get; } + public string? Path { get; } = Ensure.NotNull(repository).Info.Path; - public GitMainBranch MainBranch { get; } + public GitMainBranch MainBranch { get; } = GetMainBranch(repository); - public Uri RemoteUri { get; } -} \ No newline at end of file + public Uri RemoteUri { get; } = new Uri(Ensure.NotNull(repository).Network.Remotes[GitRemotes.Origin].Url); +} diff --git a/source/Git/CreativeCoders.Git/ILibGitCaller.cs b/source/Git/CreativeCoders.Git/ILibGitCaller.cs index 0da8248..97123a0 100644 --- a/source/Git/CreativeCoders.Git/ILibGitCaller.cs +++ b/source/Git/CreativeCoders.Git/ILibGitCaller.cs @@ -3,5 +3,6 @@ public interface ILibGitCaller { void Invoke(Action action); + T Invoke(Func func); } diff --git a/source/Git/CreativeCoders.Git/RepositoryContext.cs b/source/Git/CreativeCoders.Git/RepositoryContext.cs index 7a274de..126dce4 100644 --- a/source/Git/CreativeCoders.Git/RepositoryContext.cs +++ b/source/Git/CreativeCoders.Git/RepositoryContext.cs @@ -2,27 +2,19 @@ namespace CreativeCoders.Git; -internal class RepositoryContext +internal class RepositoryContext( + DefaultGitRepository repository, + Repository libGitRepository, + ILibGitCaller libGitCaller, + Func getSignature, + Func getCredentialsHandler, + Func certificateCheckHandler) { - private readonly Func _certificateCheckHandler; + private readonly Func _certificateCheckHandler = Ensure.NotNull(certificateCheckHandler); - private readonly Func _getCredentialsHandler; + private readonly Func _getCredentialsHandler = Ensure.NotNull(getCredentialsHandler); - private readonly Func _getSignature; - - public RepositoryContext(DefaultGitRepository repository, Repository libGitRepository, ILibGitCaller libGitCaller, - Func getSignature, Func getCredentialsHandler, - Func certificateCheckHandler) - { - _getCredentialsHandler = Ensure.NotNull(getCredentialsHandler); - _getSignature = Ensure.NotNull(getSignature); - - LibGitRepository = Ensure.NotNull(libGitRepository); - LibGitCaller = Ensure.NotNull(libGitCaller); - Repository = Ensure.NotNull(repository); - - _certificateCheckHandler = certificateCheckHandler; - } + private readonly Func _getSignature = Ensure.NotNull(getSignature); public Signature GetSignature() { @@ -39,9 +31,9 @@ public CredentialsHandler GetCredentialsHandler() return _certificateCheckHandler(); } - public Repository LibGitRepository { get; } + public Repository LibGitRepository { get; } = Ensure.NotNull(libGitRepository); - public ILibGitCaller LibGitCaller { get; } + public ILibGitCaller LibGitCaller { get; } = Ensure.NotNull(libGitCaller); - public DefaultGitRepository Repository { get; } + public DefaultGitRepository Repository { get; } = Ensure.NotNull(repository); } diff --git a/source/Git/Directory.Build.props b/source/Git/Directory.Build.props index 123e243..5ed8044 100644 --- a/source/Git/Directory.Build.props +++ b/source/Git/Directory.Build.props @@ -1,9 +1,10 @@ - - net10.0 - CreativeCoders - True - https://github.com/CreativeCodersTeam/GitTools - $(NoWarn);IDE0079 - + + net10.0 + CreativeCoders + True + https://github.com/CreativeCodersTeam/GitTools + $(NoWarn);IDE0079 + enable + \ No newline at end of file diff --git a/source/GitTool/CreativeCoders.GitTool.Base/GitToolsServiceCollectionExtensions.cs b/source/GitTool/CreativeCoders.GitTool.Base/GitToolsServiceCollectionExtensions.cs index 01cac50..c261439 100644 --- a/source/GitTool/CreativeCoders.GitTool.Base/GitToolsServiceCollectionExtensions.cs +++ b/source/GitTool/CreativeCoders.GitTool.Base/GitToolsServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -using CreativeCoders.Git.Auth.CredentialManagerCore.DependencyInjection; +using CreativeCoders.Git.Auth.CredentialManagerCore; using CreativeCoders.GitTool.Base; using CreativeCoders.GitTool.Base.Configurations; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -20,4 +20,4 @@ public static IServiceCollection AddGitTools(this IServiceCollection services) return services; } -} \ No newline at end of file +} diff --git a/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/DependencyInjection/ServiceCollectionExtensionsTests.cs b/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/DependencyInjection/ServiceCollectionExtensionsTests.cs index 68201a5..85d7042 100644 --- a/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/DependencyInjection/ServiceCollectionExtensionsTests.cs +++ b/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/DependencyInjection/ServiceCollectionExtensionsTests.cs @@ -1,5 +1,4 @@ using CreativeCoders.Git.Abstractions.Auth; -using CreativeCoders.Git.Auth.CredentialManagerCore.DependencyInjection; using AwesomeAssertions; using Microsoft.Extensions.DependencyInjection; using Xunit; @@ -25,4 +24,4 @@ public void AddGcmCoreCredentialProvider_NoArgs_RegistersDefaultGcmCoreCredentia .Should() .BeOfType(); } -} \ No newline at end of file +} diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props index 4be7d6f..db5135f 100644 --- a/tests/Directory.Build.props +++ b/tests/Directory.Build.props @@ -1,7 +1,8 @@ - - net10.0 - CreativeCoders - false - + + net10.0 + CreativeCoders + false + enable + \ No newline at end of file From e6b5e6146aaeef85ee5b4200a325cf575bf1b6fa Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sat, 28 Mar 2026 18:52:15 +0100 Subject: [PATCH 02/13] feat: add descriptions to project files for enhanced metadata clarity - Added `` tags to `.csproj` files for improved project descriptions. - Defined purposes and features for Git implementations, CLI tool, and abstractions. - Enhanced package metadata to aid in tool discovery and usage. --- .../CreativeCoders.Git.Abstractions.csproj | 1 + .../CreativeCoders.Git.Auth.CredentialManagerCore.csproj | 1 + source/Git/CreativeCoders.Git/CreativeCoders.Git.csproj | 1 + .../CreativeCoders.GitTool.Cli.GtApp.csproj | 1 + 4 files changed, 4 insertions(+) diff --git a/source/Git/CreativeCoders.Git.Abstractions/CreativeCoders.Git.Abstractions.csproj b/source/Git/CreativeCoders.Git.Abstractions/CreativeCoders.Git.Abstractions.csproj index 6425d77..0ab2668 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/CreativeCoders.Git.Abstractions.csproj +++ b/source/Git/CreativeCoders.Git.Abstractions/CreativeCoders.Git.Abstractions.csproj @@ -2,6 +2,7 @@ enable + Abstractions for Git operations including repositories, branches, commits, tags, remotes, and credential handling. Provides a strongly-typed interface layer on top of LibGit2Sharp. diff --git a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/CreativeCoders.Git.Auth.CredentialManagerCore.csproj b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/CreativeCoders.Git.Auth.CredentialManagerCore.csproj index d425713..3af223a 100644 --- a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/CreativeCoders.Git.Auth.CredentialManagerCore.csproj +++ b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/CreativeCoders.Git.Auth.CredentialManagerCore.csproj @@ -2,6 +2,7 @@ enable + Git credential provider backed by Git Credential Manager Core. Integrates with CreativeCoders.Git for secure credential storage and retrieval by URL or hostname. diff --git a/source/Git/CreativeCoders.Git/CreativeCoders.Git.csproj b/source/Git/CreativeCoders.Git/CreativeCoders.Git.csproj index f963617..4999902 100644 --- a/source/Git/CreativeCoders.Git/CreativeCoders.Git.csproj +++ b/source/Git/CreativeCoders.Git/CreativeCoders.Git.csproj @@ -2,6 +2,7 @@ enable + LibGit2Sharp-based implementation of CreativeCoders.Git.Abstractions. Provides repository operations, credential handling, and dependency injection registration via AddGit(). diff --git a/source/GitTool/CreativeCoders.GitTool.Cli.GtApp/CreativeCoders.GitTool.Cli.GtApp.csproj b/source/GitTool/CreativeCoders.GitTool.Cli.GtApp/CreativeCoders.GitTool.Cli.GtApp.csproj index 7a40e23..73b7260 100644 --- a/source/GitTool/CreativeCoders.GitTool.Cli.GtApp/CreativeCoders.GitTool.Cli.GtApp.csproj +++ b/source/GitTool/CreativeCoders.GitTool.Cli.GtApp/CreativeCoders.GitTool.Cli.GtApp.csproj @@ -7,6 +7,7 @@ gt CreativeCoders.GitTool.Cli.App true + CLI tool for managing Git repositories with GitHub and GitLab integration. Provides commands for branches, pull requests, releases, and tags. true gt CreativeCoders.GitTool From e2f3d72a33ddf0c37f482550c59deb59b856ec30 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sat, 28 Mar 2026 19:13:03 +0100 Subject: [PATCH 03/13] refactor: enhance interfaces and classes with detailed XML documentation - Added comprehensive XML comments to interfaces and methods for improved code clarity and documentation. - Updated constructors, properties, enums, and delegate parameters with summaries, parameter descriptions, and return value details. - Streamlined the readability of member comments by standardizing formatting and removing redundant remarks. --- .../Auth/IGitCredential.cs | 20 +++-- .../Auth/IGitCredentialProvider.cs | 27 +++---- .../Auth/IGitCredentialProviders.cs | 16 ++-- .../Branches/IGitBranch.cs | 24 ++++++ .../Branches/IGitBranchCollection.cs | 32 ++++++++ .../Certs/CertificateCheckArgs.cs | 26 +++++++ .../Certs/HostCertificateCheckHandler.cs | 6 ++ .../Certs/SshCertificate.cs | 24 ++++++ .../Commits/GitCommitFilter.cs | 16 ++++ .../Commits/GitCommitSortStrategies.cs | 3 + .../Commits/GitMergeResult.cs | 14 ++++ .../Commits/GitMergeStatus.cs | 3 + .../Commits/IGitCommit.cs | 15 ++++ .../Commits/IGitCommitLog.cs | 13 ++++ .../Common/IGitSignature.cs | 12 +++ .../Common/INamedReference.cs | 6 ++ .../Common/ReferenceName.cs | 44 +++++++++++ .../Common/ReferencePrefixes.cs | 18 +++++ .../Diffs/GitEntryChangeKind.cs | 14 ++++ .../Diffs/GitEntryMode.cs | 10 +++ .../Diffs/IGitDiffer.cs | 23 ++++++ .../Diffs/IGitTreeChanges.cs | 30 ++++++++ .../Diffs/IGitTreeEntryChanges.cs | 32 ++++++++ .../Exceptions/GitBranchNotExistsException.cs | 15 ++++ .../Exceptions/GitCheckoutFailedException.cs | 15 ++++ .../Exceptions/GitException.cs | 15 ++++ .../Exceptions/GitLockedFileException.cs | 4 + .../Exceptions/GitNoRemoteFoundException.cs | 3 + .../GitNoRepositoryPathException.cs | 4 + .../Exceptions/GitPushFailedException.cs | 15 ++++ .../Exceptions/GitRemoteNotFoundException.cs | 4 + .../Fetches/GitFetchTransferProgress.cs | 15 ++++ .../GitCheckoutFileConflictStrategy.cs | 3 + .../GitCommands/FetchTagsCommandOptions.cs | 11 +++ .../GitCommands/IFetchTagsCommand.cs | 7 ++ .../GitCommands/IGitCommands.cs | 15 ++++ .../GitCommands/IPullCommand.cs | 39 ++++++++++ .../GitCommands/IPushCommand.cs | 74 +++++++++++++++++++ .../GitFastForwardStrategy.cs | 3 + .../GitFetchOptions.cs | 13 ++++ .../GitMergeFileFavor.cs | 3 + .../GitMergeOptions.cs | 6 ++ .../GitPushOptions.cs | 7 ++ .../GitRepositoryBranchExtensions.cs | 22 ++++++ .../GitRepositoryFetchExtensions.cs | 26 +++++++ .../GitTagFetchMode.cs | 3 + .../IGitRepository.cs | 62 ++++++++++++++++ .../IGitRepositoryFactory.cs | 12 +++ .../IGitRepositoryInfo.cs | 12 +++ .../IGitRepositoryUtils.cs | 24 ++++++ .../Merges/GitCheckoutNotifyFlags.cs | 1 + .../Merges/GitCheckoutNotifyHandler.cs | 11 +++ .../Merges/GitCheckoutProgressHandler.cs | 6 ++ .../Objects/IGitObject.cs | 9 +++ .../Objects/IGitObjectId.cs | 11 +++ .../Pushes/GitPackBuilderProgress.cs | 18 +++++ .../Pushes/GitPackBuilderStage.cs | 5 ++ .../Pushes/GitPushStatusError.cs | 14 ++++ .../Pushes/GitPushTransferProgress.cs | 18 +++++ .../Pushes/GitPushUpdate.cs | 22 ++++++ .../RefSpecs/GitRefSpecDirection.cs | 5 ++ .../RefSpecs/IGitRefSpec.cs | 15 ++++ .../RefSpecs/IGitRefSpecCollection.cs | 3 + .../References/IGitReference.cs | 9 +++ .../References/IGitReferenceCollection.cs | 27 +++++++ .../Remotes/IGitRemote.cs | 21 ++++++ .../Remotes/IGitRemoteCollection.cs | 8 ++ .../Tags/IGitTag.cs | 13 ++++ .../Tags/IGitTagCollection.cs | 41 ++++++++++ 69 files changed, 1083 insertions(+), 34 deletions(-) diff --git a/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredential.cs b/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredential.cs index 02a6a35..af339cc 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredential.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredential.cs @@ -1,19 +1,17 @@ namespace CreativeCoders.Git.Abstractions.Auth; -/// Interface representing git credential. +/// +/// Represents a Git credential consisting of a user name and password. +/// public interface IGitCredential { - ///------------------------------------------------------------------------------------------------- - /// Gets the name of the user. - /// - /// The name of the user. - ///------------------------------------------------------------------------------------------------- + /// + /// Gets the user name. + /// string UserName { get; } - ///------------------------------------------------------------------------------------------------- - /// Gets the password. - /// - /// The password. - ///------------------------------------------------------------------------------------------------- + /// + /// Gets the password. + /// string Password { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredentialProvider.cs b/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredentialProvider.cs index 27350c1..13731e8 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredentialProvider.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredentialProvider.cs @@ -1,23 +1,20 @@ namespace CreativeCoders.Git.Abstractions.Auth; -/// Interface for git credential provider. +/// +/// Provides credentials for authenticating against a Git remote. +/// public interface IGitCredentialProvider { - ///------------------------------------------------------------------------------------------------- - /// Gets the credentials for a specific git url. - /// - /// URL of the resource. - /// URL of from. - /// - /// - /// The credentials. - ///------------------------------------------------------------------------------------------------- + /// + /// Gets the credentials for the specified URL. + /// + /// The URL of the remote resource. + /// The URL that initiated the credential request, or if not available. + /// The credential, or if no credential is available. IGitCredential? GetCredentials(string url, string? fromUrl); - ///------------------------------------------------------------------------------------------------- - /// Gets the name of the credential provider. - /// - /// The name. - ///------------------------------------------------------------------------------------------------- + /// + /// Gets the name of the credential provider. + /// string Name { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredentialProviders.cs b/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredentialProviders.cs index ae48ac0..41c710d 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredentialProviders.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Auth/IGitCredentialProviders.cs @@ -2,16 +2,16 @@ namespace CreativeCoders.Git.Abstractions.Auth; -/// Interface for collection of git credential providers. +/// +/// Represents a collection of instances and provides lookup by name. +/// [PublicAPI] public interface IGitCredentialProviders : IGitCredentialProvider { - ///------------------------------------------------------------------------------------------------- - /// Gets a provider for . - /// - /// Name of the provider. - /// - /// The provider. - ///------------------------------------------------------------------------------------------------- + /// + /// Gets the credential provider with the specified name. + /// + /// The name of the provider to retrieve. + /// The matching credential provider, or if no provider with the specified name exists. IGitCredentialProvider? GetProvider(string providerName); } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Branches/IGitBranch.cs b/source/Git/CreativeCoders.Git.Abstractions/Branches/IGitBranch.cs index 55dd6da..bed2924 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Branches/IGitBranch.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Branches/IGitBranch.cs @@ -5,18 +5,42 @@ namespace CreativeCoders.Git.Abstractions.Branches; +/// +/// Represents a Git branch. +/// [PublicAPI] public interface IGitBranch : IEquatable, IComparable, INamedReference { + /// + /// Gets the commit at the tip of the branch. + /// IGitCommit? Tip { get; } + /// + /// Gets a value that indicates whether this is a remote-tracking branch. + /// + /// if this is a remote-tracking branch; otherwise, . bool IsRemote { get; } + /// + /// Gets a value that indicates whether this branch is tracking a remote branch. + /// + /// if this branch tracks a remote branch; otherwise, . bool IsTracking { get; } + /// + /// Gets the remote-tracking branch that this branch is tracking. + /// IGitBranch? TrackedBranch { get; } + /// + /// Gets a value that indicates whether the branch represents a detached HEAD. + /// + /// if HEAD is detached; otherwise, . bool IsDetachedHead { get; } + /// + /// Gets the commit log for this branch. + /// IGitCommitLog? Commits { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Branches/IGitBranchCollection.cs b/source/Git/CreativeCoders.Git.Abstractions/Branches/IGitBranchCollection.cs index 8350ed0..7bafcb6 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Branches/IGitBranchCollection.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Branches/IGitBranchCollection.cs @@ -3,18 +3,50 @@ namespace CreativeCoders.Git.Abstractions.Branches; +/// +/// Represents the collection of branches in a Git repository. +/// [PublicAPI] public interface IGitBranchCollection : IEnumerable { + /// + /// Checks out the branch with the specified name. + /// + /// The name of the branch to check out. + /// The checked-out branch, or if the branch does not exist. IGitBranch? CheckOut(string branchName); + /// + /// Creates a new branch with the specified name from the current HEAD. + /// + /// The name of the branch to create. + /// The newly created branch, or if creation failed. IGitBranch? CreateBranch(string branchName); + /// + /// Deletes the local branch with the specified name. + /// + /// The name of the local branch to delete. void DeleteLocalBranch(string branchName); + /// + /// Gets the branch with the specified name. + /// + /// The name of the branch. + /// The matching branch, or if no branch with the specified name exists. IGitBranch? this[string name] { get; } + /// + /// Finds a local branch by its friendly name. + /// + /// The friendly name of the local branch. + /// The matching local branch, or if not found. IGitBranch? FindLocalBranchByFriendlyName(string branchName); + /// + /// Finds a remote-tracking branch by its friendly name. + /// + /// The friendly name of the remote branch. + /// The matching remote-tracking branch, or if not found. IGitBranch? FindRemoteBranchByFriendlyName(string branchName); } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Certs/CertificateCheckArgs.cs b/source/Git/CreativeCoders.Git.Abstractions/Certs/CertificateCheckArgs.cs index 209cfd8..b68daee 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Certs/CertificateCheckArgs.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Certs/CertificateCheckArgs.cs @@ -3,9 +3,18 @@ namespace CreativeCoders.Git.Abstractions.Certs; +/// +/// Provides the arguments for a certificate check callback during a Git remote operation. +/// [PublicAPI] public class CertificateCheckArgs { + /// + /// Initializes a new instance of the class. + /// + /// The X.509 certificate, or if not available. + /// The SSH certificate, or if the connection is not SSH. + /// The host name of the remote server. public CertificateCheckArgs(X509Certificate? certificate, SshCertificate? sshCertificate, string host) { Certificate = certificate; @@ -13,13 +22,30 @@ public CertificateCheckArgs(X509Certificate? certificate, SshCertificate? sshCer SshCertificate = sshCertificate; } + /// + /// Gets the X.509 certificate presented by the remote server. + /// public X509Certificate? Certificate { get; } + /// + /// Gets a value that indicates whether the connection uses SSH. + /// + /// if the connection uses SSH; otherwise, . public bool IsSsh => SshCertificate != null; + /// + /// Gets the SSH certificate presented by the remote server. + /// public SshCertificate? SshCertificate { get; } + /// + /// Gets or sets a value that indicates whether the certificate is valid. + /// + /// if the certificate is valid; otherwise, . public bool IsValid { get; set; } + /// + /// Gets the host name of the remote server. + /// public string Host { get; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Certs/HostCertificateCheckHandler.cs b/source/Git/CreativeCoders.Git.Abstractions/Certs/HostCertificateCheckHandler.cs index c58e8d0..5328c15 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Certs/HostCertificateCheckHandler.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Certs/HostCertificateCheckHandler.cs @@ -1,3 +1,9 @@ namespace CreativeCoders.Git.Abstractions.Certs; +/// +/// Represents the handler invoked to validate a server certificate during a Git remote operation. +/// +/// The repository performing the remote operation. +/// The certificate check arguments containing the certificate details. +/// if the certificate is accepted; otherwise, . public delegate bool HostCertificateCheckHandler(IGitRepository repository, CertificateCheckArgs args); diff --git a/source/Git/CreativeCoders.Git.Abstractions/Certs/SshCertificate.cs b/source/Git/CreativeCoders.Git.Abstractions/Certs/SshCertificate.cs index 2ab026d..f2dc111 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Certs/SshCertificate.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Certs/SshCertificate.cs @@ -2,9 +2,19 @@ namespace CreativeCoders.Git.Abstractions.Certs; +/// +/// Represents an SSH host key certificate with MD5 and SHA-1 fingerprint hashes. +/// [PublicAPI] public class SshCertificate { + /// + /// Initializes a new instance of the class. + /// + /// The MD5 hash of the host key. + /// The SHA-1 hash of the host key. + /// if the MD5 hash is available; otherwise, . + /// if the SHA-1 hash is available; otherwise, . public SshCertificate(byte[] hashMd5, byte[] hashSha1, bool hasMd5, bool hasSha1) { HashMd5 = hashMd5; @@ -13,11 +23,25 @@ public SshCertificate(byte[] hashMd5, byte[] hashSha1, bool hasMd5, bool hasSha1 HasSha1 = hasSha1; } + /// + /// Gets the MD5 hash of the host key. + /// public byte[] HashMd5 { get; } + /// + /// Gets the SHA-1 hash of the host key. + /// public byte[] HashSha1 { get; } + /// + /// Gets a value that indicates whether the MD5 hash is available. + /// + /// if the MD5 hash is available; otherwise, . public bool HasMd5 { get; } + /// + /// Gets a value that indicates whether the SHA-1 hash is available. + /// + /// if the SHA-1 hash is available; otherwise, . public bool HasSha1 { get; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitFilter.cs b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitFilter.cs index 7160038..98bbe3f 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitFilter.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitFilter.cs @@ -2,14 +2,30 @@ namespace CreativeCoders.Git.Abstractions.Commits; +/// +/// Represents filter criteria for querying the commit log. +/// [PublicAPI] public class GitCommitFilter { + /// + /// Gets or sets a value that indicates whether only the first parent of merge commits should be followed. + /// + /// to follow only the first parent; otherwise, . The default is . public bool FirstParentOnly { get; set; } + /// + /// Gets or sets the commit or reference from which reachable commits are included. + /// public object? IncludeReachableFrom { get; set; } + /// + /// Gets or sets the commit or reference from which reachable commits are excluded. + /// public object? ExcludeReachableFrom { get; set; } + /// + /// Gets or sets the sorting strategy for the returned commits. + /// public GitCommitSortStrategies SortBy { get; set; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitSortStrategies.cs b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitSortStrategies.cs index be2e792..ba573b4 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitSortStrategies.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitSortStrategies.cs @@ -3,6 +3,9 @@ namespace CreativeCoders.Git.Abstractions.Commits; +/// +/// Specifies the sort strategies for enumerating commits in a commit log. +/// [PublicAPI] [Flags] public enum GitCommitSortStrategies diff --git a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitMergeResult.cs b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitMergeResult.cs index 7ca94df..fff3ddc 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitMergeResult.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitMergeResult.cs @@ -1,14 +1,28 @@ namespace CreativeCoders.Git.Abstractions.Commits; +/// +/// Represents the result of a Git merge operation. +/// public class GitMergeResult { + /// + /// Initializes a new instance of the class. + /// + /// The status of the merge operation. + /// The merge commit, or if no merge commit was created. public GitMergeResult(GitMergeStatus mergeStatus, IGitCommit? commit) { MergeStatus = mergeStatus; Commit = commit; } + /// + /// Gets the status of the merge operation. + /// public GitMergeStatus MergeStatus { get; } + /// + /// Gets the merge commit, if one was created. + /// public IGitCommit? Commit { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitMergeStatus.cs b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitMergeStatus.cs index e36b8ef..1a78ef3 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitMergeStatus.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitMergeStatus.cs @@ -1,5 +1,8 @@ namespace CreativeCoders.Git.Abstractions.Commits; +/// +/// Specifies the status of a Git merge operation. +/// public enum GitMergeStatus { /// Merge was up-to-date. diff --git a/source/Git/CreativeCoders.Git.Abstractions/Commits/IGitCommit.cs b/source/Git/CreativeCoders.Git.Abstractions/Commits/IGitCommit.cs index ba756d7..e9e222d 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Commits/IGitCommit.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Commits/IGitCommit.cs @@ -6,14 +6,29 @@ namespace CreativeCoders.Git.Abstractions.Commits; +/// +/// Represents a Git commit object. +/// [PublicAPI] public interface IGitCommit : IEquatable, IComparable, IGitObject { + /// + /// Gets the parent commits of this commit. + /// IEnumerable Parents { get; } + /// + /// Gets the author signature of the commit. + /// IGitSignature Author { get; } + /// + /// Gets the committer signature of the commit. + /// IGitSignature Committer { get; } + /// + /// Gets the commit message. + /// string Message { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Commits/IGitCommitLog.cs b/source/Git/CreativeCoders.Git.Abstractions/Commits/IGitCommitLog.cs index 3b9eb83..ca9b5aa 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Commits/IGitCommitLog.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Commits/IGitCommitLog.cs @@ -4,10 +4,23 @@ namespace CreativeCoders.Git.Abstractions.Commits; +/// +/// Represents the queryable log of commits in a Git repository or branch. +/// [PublicAPI] public interface IGitCommitLog : IEnumerable { + /// + /// Gets all commits prior to the specified date. + /// + /// The date threshold; only commits older than this value are returned. + /// A sequence of commits older than . IEnumerable GetCommitsPriorTo(DateTimeOffset olderThan); + /// + /// Queries the commit log using the specified filter. + /// + /// The filter criteria for selecting commits. + /// A sequence of commits matching the filter. IEnumerable QueryBy(GitCommitFilter commitFilter); } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Common/IGitSignature.cs b/source/Git/CreativeCoders.Git.Abstractions/Common/IGitSignature.cs index 710e689..445abbd 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Common/IGitSignature.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Common/IGitSignature.cs @@ -3,12 +3,24 @@ namespace CreativeCoders.Git.Abstractions.Common; +/// +/// Represents the identity and timestamp of a Git commit author or committer. +/// [PublicAPI] public interface IGitSignature { + /// + /// Gets the date and time when the action was performed. + /// public DateTimeOffset When { get; } + /// + /// Gets the name of the person. + /// public string Name { get; } + /// + /// Gets the email address of the person. + /// public string Email { get; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Common/INamedReference.cs b/source/Git/CreativeCoders.Git.Abstractions/Common/INamedReference.cs index 324cc9e..2851133 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Common/INamedReference.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Common/INamedReference.cs @@ -1,6 +1,12 @@ namespace CreativeCoders.Git.Abstractions.Common; +/// +/// Represents a Git reference that has a . +/// public interface INamedReference { + /// + /// Gets the name of the reference. + /// ReferenceName Name { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Common/ReferenceName.cs b/source/Git/CreativeCoders.Git.Abstractions/Common/ReferenceName.cs index 5870fe1..02070ac 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Common/ReferenceName.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Common/ReferenceName.cs @@ -4,6 +4,9 @@ namespace CreativeCoders.Git.Abstractions.Common; +/// +/// Represents a parsed Git reference name with its canonical, friendly, and remote-stripped forms. +/// public class ReferenceName : ComparableObject { static ReferenceName() @@ -11,6 +14,10 @@ static ReferenceName() InitComparableObject(x => x.Canonical); } + /// + /// Initializes a new instance of the class. + /// + /// The canonical reference name (e.g. refs/heads/main). public ReferenceName(string canonical) { Canonical = Ensure.IsNotNullOrWhitespace(canonical); @@ -24,6 +31,12 @@ public ReferenceName(string canonical) || IsPrefixedBy(Canonical, ReferencePrefixes.PullRequest2); } + /// + /// Attempts to parse a canonical reference name. + /// + /// The canonical name to parse. + /// When this method returns, contains the parsed reference name, or if parsing failed. This parameter is treated as uninitialized. + /// if is a valid canonical reference name; otherwise, . public static bool TryParse(string canonicalName, out ReferenceName? referenceName) { if (IsPrefixedBy(canonicalName, ReferencePrefixes.LocalBranch) @@ -40,6 +53,12 @@ public static bool TryParse(string canonicalName, out ReferenceName? referenceNa return false; } + /// + /// Parses a canonical reference name. + /// + /// The canonical name to parse. + /// The parsed reference name. + /// is not a valid canonical reference name. public static ReferenceName Parse(string canonicalName) { if (TryParse(canonicalName, out var referenceName)) @@ -75,17 +94,42 @@ private string RemoveRemotePrefix() private static bool IsPrefixedBy(string input, string prefix) => input.StartsWith(prefix, StringComparison.Ordinal); + /// + /// Gets the full canonical name of the reference (e.g. refs/heads/main). + /// public string Canonical { get; } + /// + /// Gets the friendly (shortened) name of the reference (e.g. main). + /// public string Friendly { get; } + /// + /// Gets the friendly name without the remote prefix (e.g. main instead of origin/main). + /// public string WithoutRemote { get; } + /// + /// Gets a value that indicates whether this reference is a local branch. + /// + /// if this is a local branch; otherwise, . public bool IsLocalBranch { get; } + /// + /// Gets a value that indicates whether this reference is a remote-tracking branch. + /// + /// if this is a remote-tracking branch; otherwise, . public bool IsRemoteBranch { get; } + /// + /// Gets a value that indicates whether this reference is a tag. + /// + /// if this is a tag; otherwise, . public bool IsTag { get; } + /// + /// Gets a value that indicates whether this reference is a pull request. + /// + /// if this is a pull request; otherwise, . public bool IsPullRequest { get; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Common/ReferencePrefixes.cs b/source/Git/CreativeCoders.Git.Abstractions/Common/ReferencePrefixes.cs index 41151ac..3a4e120 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Common/ReferencePrefixes.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Common/ReferencePrefixes.cs @@ -1,14 +1,32 @@ namespace CreativeCoders.Git.Abstractions.Common; +/// +/// Provides well-known prefix strings for Git reference names. +/// public static class ReferencePrefixes { + /// + /// The prefix for local branch references (refs/heads/). + /// public const string LocalBranch = "refs/heads/"; + /// + /// The prefix for remote-tracking branch references (refs/remotes/). + /// public const string RemoteTrackingBranch = "refs/remotes/"; + /// + /// The prefix for tag references (refs/tags/). + /// public const string Tag = "refs/tags/"; + /// + /// The prefix for pull request references using the GitHub convention (refs/pull/). + /// public const string PullRequest1 = "refs/pull/"; + /// + /// The prefix for pull request references using the Bitbucket convention (refs/pull-requests/). + /// public const string PullRequest2 = "refs/pull-requests/"; } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Diffs/GitEntryChangeKind.cs b/source/Git/CreativeCoders.Git.Abstractions/Diffs/GitEntryChangeKind.cs index 3cf12e5..79c893e 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Diffs/GitEntryChangeKind.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Diffs/GitEntryChangeKind.cs @@ -1,16 +1,30 @@ namespace CreativeCoders.Git.Abstractions.Diffs; +/// +/// Specifies the kind of change applied to a tree entry. +/// public enum GitEntryChangeKind { + /// The entry was not modified. Unmodified, + /// The entry was added. Added, + /// The entry was deleted. Deleted, + /// The entry was modified. Modified, + /// The entry was renamed. Renamed, + /// The entry was copied. Copied, + /// The entry is ignored. Ignored, + /// The entry is untracked. Untracked, + /// The entry type was changed. TypeChanged, + /// The entry is unreadable. Unreadable, + /// The entry is in a conflicted state. Conflicted } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Diffs/GitEntryMode.cs b/source/Git/CreativeCoders.Git.Abstractions/Diffs/GitEntryMode.cs index a201fab..c889262 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Diffs/GitEntryMode.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Diffs/GitEntryMode.cs @@ -1,12 +1,22 @@ namespace CreativeCoders.Git.Abstractions.Diffs; +/// +/// Specifies the UNIX file mode of a Git tree entry. +/// public enum GitEntryMode { + /// The entry does not exist. Nonexistent = 0, + /// The entry is a directory (tree). Directory = 16384, // 0x00004000 + /// The entry is a non-executable file (blob). NonExecutableFile = 33188, // 0x000081A4 + /// The entry is a non-executable, group-writable file (blob). NonExecutableGroupWritableFile = 33204, // 0x000081B4 + /// The entry is an executable file (blob). ExecutableFile = 33261, // 0x000081ED + /// The entry is a symbolic link. SymbolicLink = 40960, // 0x0000A000 + /// The entry is a Git submodule link. GitLink = 57344 // 0x0000E000 } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitDiffer.cs b/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitDiffer.cs index 0cd2a39..8968991 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitDiffer.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitDiffer.cs @@ -3,14 +3,37 @@ namespace CreativeCoders.Git.Abstractions.Diffs; +/// +/// Provides methods for comparing trees and producing diffs in a Git repository. +/// [PublicAPI] public interface IGitDiffer { + /// + /// Compares the working directory against the index (staged area). + /// + /// The tree changes representing the differences. IGitTreeChanges Compare(); + /// + /// Compares the working directory against the index (staged area). + /// + /// to include untracked files in the comparison; otherwise, . + /// The tree changes representing the differences. IGitTreeChanges Compare(bool includeUntracked); + /// + /// Compares the working directory against the index for the specified paths. + /// + /// The file paths to include in the comparison. + /// The tree changes representing the differences. IGitTreeChanges Compare(IEnumerable paths); + /// + /// Compares the working directory against the index for the specified paths. + /// + /// The file paths to include in the comparison. + /// to include untracked files in the comparison; otherwise, . + /// The tree changes representing the differences. IGitTreeChanges Compare(IEnumerable paths, bool includeUntracked); } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitTreeChanges.cs b/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitTreeChanges.cs index b35cb63..35d84b4 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitTreeChanges.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitTreeChanges.cs @@ -4,24 +4,54 @@ namespace CreativeCoders.Git.Abstractions.Diffs; +/// +/// Represents the set of changes between two trees in a Git repository, grouped by change kind. +/// [PublicAPI] public interface IGitTreeChanges : IEnumerable, IDisposable { + /// + /// Gets the entries that were added. + /// IEnumerable Added { get; } + /// + /// Gets the entries that were deleted. + /// IEnumerable Deleted { get; } + /// + /// Gets the entries that were modified. + /// IEnumerable Modified { get; } + /// + /// Gets the entries whose type was changed. + /// IEnumerable TypeChanged { get; } + /// + /// Gets the entries that were renamed. + /// IEnumerable Renamed { get; } + /// + /// Gets the entries that were copied. + /// IEnumerable Copied { get; } + /// + /// Gets the entries that were not modified. + /// IEnumerable Unmodified { get; } + /// + /// Gets the entries that are in a conflicted state. + /// IEnumerable Conflicted { get; } + /// + /// Gets the total number of changed entries. + /// int Count { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitTreeEntryChanges.cs b/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitTreeEntryChanges.cs index bea7b42..d701c33 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitTreeEntryChanges.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Diffs/IGitTreeEntryChanges.cs @@ -3,24 +3,56 @@ namespace CreativeCoders.Git.Abstractions.Diffs; +/// +/// Represents the changes to a single entry in a Git tree diff. +/// [PublicAPI] public interface IGitTreeEntryChanges { + /// + /// Gets the current path of the entry. + /// string Path { get; } + /// + /// Gets the current file mode of the entry. + /// GitEntryMode Mode { get; } + /// + /// Gets the current object ID of the entry. + /// IGitObjectId Oid { get; } + /// + /// Gets a value that indicates whether the entry exists in the new tree. + /// + /// if the entry exists; otherwise, . bool Exists { get; } + /// + /// Gets the kind of change applied to the entry. + /// GitEntryChangeKind Status { get; } + /// + /// Gets the previous path of the entry before the change. + /// string OldPath { get; } + /// + /// Gets the previous file mode of the entry. + /// GitEntryMode OldMode { get; } + /// + /// Gets the previous object ID of the entry. + /// IGitObjectId OldOid { get; } + /// + /// Gets a value that indicates whether the entry existed in the old tree. + /// + /// if the entry existed; otherwise, . bool OldExists { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitBranchNotExistsException.cs b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitBranchNotExistsException.cs index 9b61a5b..bb0a451 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitBranchNotExistsException.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitBranchNotExistsException.cs @@ -4,18 +4,33 @@ namespace CreativeCoders.Git.Abstractions.Exceptions; +/// +/// Represents the exception thrown when a specified Git branch does not exist. +/// [PublicAPI] [ExcludeFromCodeCoverage] public class GitBranchNotExistsException : GitException { + /// + /// Initializes a new instance of the class. + /// public GitBranchNotExistsException() { } + /// + /// Initializes a new instance of the class with the name of the branch that was not found. + /// + /// The name of the branch that does not exist. public GitBranchNotExistsException(string? branchName) : base($"Branch '{branchName}' does not exist") { } + /// + /// Initializes a new instance of the class with a specified error message and inner exception. + /// + /// The message that describes the error. + /// The exception that is the cause of the current exception. public GitBranchNotExistsException(string? message, Exception? innerException) : base(message, innerException) { } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitCheckoutFailedException.cs b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitCheckoutFailedException.cs index 1466ee2..61aa1ef 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitCheckoutFailedException.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitCheckoutFailedException.cs @@ -3,17 +3,32 @@ namespace CreativeCoders.Git.Abstractions.Exceptions; +/// +/// Represents the exception thrown when a Git checkout operation fails. +/// [PublicAPI] public class GitCheckoutFailedException : GitException { + /// + /// Initializes a new instance of the class. + /// public GitCheckoutFailedException() { } + /// + /// Initializes a new instance of the class with the name of the branch that could not be checked out. + /// + /// The name of the branch that failed to check out. public GitCheckoutFailedException(string? branchName) : base($"Checkout branch '{branchName}' failed") { } + /// + /// Initializes a new instance of the class with a specified error message and inner exception. + /// + /// The message that describes the error. + /// The exception that is the cause of the current exception. public GitCheckoutFailedException(string? message, Exception? innerException) : base(message, innerException) { } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitException.cs b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitException.cs index 2128501..c752ea6 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitException.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitException.cs @@ -4,18 +4,33 @@ namespace CreativeCoders.Git.Abstractions.Exceptions; +/// +/// Represents the base exception for all Git-related errors. +/// [ExcludeFromCodeCoverage] [PublicAPI] public class GitException : Exception { + /// + /// Initializes a new instance of the class. + /// public GitException() { } + /// + /// Initializes a new instance of the class with a specified error message. + /// + /// The message that describes the error. public GitException(string? message) : base(message) { } + /// + /// Initializes a new instance of the class with a specified error message and inner exception. + /// + /// The message that describes the error. + /// The exception that is the cause of the current exception. public GitException(string? message, Exception? innerException) : base(message, innerException) { } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitLockedFileException.cs b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitLockedFileException.cs index 53e2fa3..ddd115a 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitLockedFileException.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitLockedFileException.cs @@ -2,4 +2,8 @@ namespace CreativeCoders.Git.Abstractions.Exceptions; +/// +/// Represents the exception thrown when a Git operation cannot proceed because a file is locked. +/// +/// The exception that is the cause of the current exception. public class GitLockedFileException(Exception innerException) : GitException("A file is locked", innerException); \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitNoRemoteFoundException.cs b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitNoRemoteFoundException.cs index 899b2d4..43f4e13 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitNoRemoteFoundException.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitNoRemoteFoundException.cs @@ -1,3 +1,6 @@ namespace CreativeCoders.Git.Abstractions.Exceptions; +/// +/// Represents the exception thrown when no remote is configured for the repository. +/// public class GitNoRemoteFoundException() : GitException("No remote can be found"); \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitNoRepositoryPathException.cs b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitNoRepositoryPathException.cs index 082ed8f..f26d9bf 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitNoRepositoryPathException.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitNoRepositoryPathException.cs @@ -1,3 +1,7 @@ namespace CreativeCoders.Git.Abstractions.Exceptions; +/// +/// Represents the exception thrown when a specified path is not a valid Git repository. +/// +/// The path that is not a Git repository. public class GitNoRepositoryPathException(string path) : GitException($"'{path}' is not git repository"); \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitPushFailedException.cs b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitPushFailedException.cs index 29f850b..780aa1b 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitPushFailedException.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitPushFailedException.cs @@ -3,17 +3,32 @@ namespace CreativeCoders.Git.Abstractions.Exceptions; +/// +/// Represents the exception thrown when a Git push operation fails. +/// [PublicAPI] public class GitPushFailedException : GitException { + /// + /// Initializes a new instance of the class. + /// public GitPushFailedException() { } + /// + /// Initializes a new instance of the class with a specified error message. + /// + /// The message that describes the error. public GitPushFailedException(string? message) : base(message) { } + /// + /// Initializes a new instance of the class with a specified error message and inner exception. + /// + /// The message that describes the error. + /// The exception that is the cause of the current exception. public GitPushFailedException(string? message, Exception? innerException) : base(message, innerException) { } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitRemoteNotFoundException.cs b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitRemoteNotFoundException.cs index a05c95e..f44dd0d 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitRemoteNotFoundException.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Exceptions/GitRemoteNotFoundException.cs @@ -1,3 +1,7 @@ namespace CreativeCoders.Git.Abstractions.Exceptions; +/// +/// Represents the exception thrown when a specified Git remote is not found. +/// +/// The name of the remote that was not found. public class GitRemoteNotFoundException(string remoteName) : GitException($"Remote '{remoteName}' not found"); \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Fetches/GitFetchTransferProgress.cs b/source/Git/CreativeCoders.Git.Abstractions/Fetches/GitFetchTransferProgress.cs index 91b04cd..1a77809 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Fetches/GitFetchTransferProgress.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Fetches/GitFetchTransferProgress.cs @@ -1,12 +1,27 @@ namespace CreativeCoders.Git.Abstractions.Fetches; +/// +/// Represents the progress of a Git fetch transfer operation. +/// public class GitFetchTransferProgress { + /// + /// Gets the number of objects that have been indexed. + /// public int IndexedObjects { get; init; } + /// + /// Gets the number of objects that have been received. + /// public int ReceivedObjects { get; init; } + /// + /// Gets the total number of objects to be transferred. + /// public int TotalObjects { get; init; } + /// + /// Gets the number of bytes received so far. + /// public long ReceivedBytes { get; init; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitCheckoutFileConflictStrategy.cs b/source/Git/CreativeCoders.Git.Abstractions/GitCheckoutFileConflictStrategy.cs index 4f1482e..f4feab4 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitCheckoutFileConflictStrategy.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitCheckoutFileConflictStrategy.cs @@ -1,6 +1,9 @@ namespace CreativeCoders.Git.Abstractions; // ReSharper disable CommentTypo +/// +/// Specifies how conflicting files should be written out during checkout. +/// public enum GitCheckoutFileConflictStrategy { /// diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/FetchTagsCommandOptions.cs b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/FetchTagsCommandOptions.cs index 3051eba..87e000e 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/FetchTagsCommandOptions.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/FetchTagsCommandOptions.cs @@ -1,8 +1,19 @@ namespace CreativeCoders.Git.Abstractions.GitCommands; +/// +/// Represents options for a fetch tags command. +/// public class FetchTagsCommandOptions { + /// + /// Gets or sets a value that indicates whether tags that no longer exist on the remote should be deleted locally. + /// + /// to prune deleted remote tags; otherwise, . The default is . public bool Prune { get; set; } = true; + /// + /// Gets or sets the name of the remote to fetch tags from. + /// + /// The remote name. The default is "origin". public string RemoteName { get; set; } = "origin"; } diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IFetchTagsCommand.cs b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IFetchTagsCommand.cs index fcd6a0c..d928baa 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IFetchTagsCommand.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IFetchTagsCommand.cs @@ -1,6 +1,13 @@ namespace CreativeCoders.Git.Abstractions.GitCommands; +/// +/// Represents a command for fetching tags from a remote repository. +/// public interface IFetchTagsCommand { + /// + /// Executes the fetch tags command with the specified options. + /// + /// The options controlling the fetch tags behavior. void Execute(FetchTagsCommandOptions commandOptions); } diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IGitCommands.cs b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IGitCommands.cs index 9542164..0f85730 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IGitCommands.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IGitCommands.cs @@ -1,10 +1,25 @@ namespace CreativeCoders.Git.Abstractions.GitCommands; +/// +/// Provides factory methods for creating Git command instances. +/// public interface IGitCommands { + /// + /// Creates a new pull command. + /// + /// A new instance. IPullCommand CreatePullCommand(); + /// + /// Creates a new push command. + /// + /// A new instance. IPushCommand CreatePushCommand(); + /// + /// Creates a new fetch tags command. + /// + /// A new instance. IFetchTagsCommand CreateFetchTagsCommand(); } diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IPullCommand.cs b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IPullCommand.cs index 876eb1b..b172b14 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IPullCommand.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IPullCommand.cs @@ -6,20 +6,59 @@ namespace CreativeCoders.Git.Abstractions.GitCommands; +/// +/// Represents a fluent builder for configuring and executing a Git pull operation. +/// [PublicAPI] public interface IPullCommand { + /// + /// Registers a simple checkout notification handler for all notification types. + /// + /// The handler to invoke on checkout notifications. + /// The current command instance for method chaining. IPullCommand OnCheckoutNotify(GitSimpleCheckoutNotifyHandler notify); + /// + /// Registers a simple checkout notification handler for the specified notification types. + /// + /// The handler to invoke on checkout notifications. + /// A bitwise combination of the enumeration values that specifies which notifications to receive. + /// The current command instance for method chaining. IPullCommand OnCheckoutNotify(GitSimpleCheckoutNotifyHandler notify, GitCheckoutNotifyFlags notifyFlags); + /// + /// Registers a checkout notification handler that can cancel the operation, for all notification types. + /// + /// The handler to invoke on checkout notifications. + /// The current command instance for method chaining. IPullCommand OnCheckoutNotify(GitCheckoutNotifyHandler notify); + /// + /// Registers a checkout notification handler that can cancel the operation, for the specified notification types. + /// + /// The handler to invoke on checkout notifications. + /// A bitwise combination of the enumeration values that specifies which notifications to receive. + /// The current command instance for method chaining. IPullCommand OnCheckoutNotify(GitCheckoutNotifyHandler notify, GitCheckoutNotifyFlags notifyFlags); + /// + /// Registers a handler to receive checkout progress updates. + /// + /// The handler to invoke with checkout progress information. + /// The current command instance for method chaining. IPullCommand OnCheckoutProgress(GitCheckoutProgressHandler progress); + /// + /// Registers a handler to receive fetch transfer progress updates. + /// + /// The handler to invoke with transfer progress information. + /// The current command instance for method chaining. IPullCommand OnTransferProgress(Action progress); + /// + /// Executes the pull operation. + /// + /// The result of the merge operation performed during the pull. GitMergeResult Run(); } diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IPushCommand.cs b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IPushCommand.cs index 68e197a..302e918 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IPushCommand.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitCommands/IPushCommand.cs @@ -7,36 +7,110 @@ namespace CreativeCoders.Git.Abstractions.GitCommands; +/// +/// Represents a fluent builder for configuring and executing a Git push operation. +/// [PublicAPI] public interface IPushCommand { + /// + /// Enables automatic creation of the remote branch if it does not exist. + /// + /// The current command instance for method chaining. IPushCommand CreateRemoteBranchIfNotExists(); + /// + /// Configures whether the remote branch should be created if it does not exist. + /// + /// to create the remote branch if it does not exist; otherwise, . + /// The current command instance for method chaining. IPushCommand CreateRemoteBranchIfNotExists(bool createRemoteBranchIfNotExists); + /// + /// Sets the branch to push. + /// + /// The branch to push. + /// The current command instance for method chaining. IPushCommand Branch(IGitBranch branch); + /// + /// Enables user confirmation before the push is executed. + /// + /// The current command instance for method chaining. IPushCommand Confirm(); + /// + /// Configures whether user confirmation is required before the push is executed. + /// + /// to require confirmation; otherwise, . + /// The current command instance for method chaining. IPushCommand Confirm(bool confirm); + /// + /// Registers a handler to receive push status errors. + /// + /// The handler to invoke when a push status error occurs. + /// The current command instance for method chaining. IPushCommand OnPushStatusError(Action pushStatusError); + /// + /// Registers a handler to receive pack builder progress updates. + /// + /// The handler to invoke with pack builder progress information. + /// The current command instance for method chaining. IPushCommand OnPackBuilderProgress(Action packBuilderProgress); + /// + /// Registers a handler to receive pack builder progress updates that can cancel the operation. + /// + /// The handler to invoke with pack builder progress information. Returns to continue; to cancel. + /// The current command instance for method chaining. IPushCommand OnPackBuilderProgress(Func packBuilderProgress); + /// + /// Registers a handler to receive push transfer progress updates. + /// + /// The handler to invoke with transfer progress information. + /// The current command instance for method chaining. IPushCommand OnTransferProgress(Action transferProgress); + /// + /// Registers a handler to receive push transfer progress updates that can cancel the operation. + /// + /// The handler to invoke with transfer progress information. Returns to continue; to cancel. + /// The current command instance for method chaining. IPushCommand OnTransferProgress(Func transferProgress); + /// + /// Registers a handler invoked after negotiation completes, before the push begins. + /// + /// The handler to invoke with the list of push updates. + /// The current command instance for method chaining. IPushCommand OnNegotiationCompletedBeforePush(Action> negotiationCompletedBeforePush); + /// + /// Registers a handler invoked after negotiation completes that can cancel the push. + /// + /// The handler to invoke with the list of push updates. Returns to continue; to cancel. + /// The current command instance for method chaining. IPushCommand OnNegotiationCompletedBeforePush(Func, bool> negotiationCompletedBeforePush); + /// + /// Registers a handler invoked with the list of commits that have not been pushed to the remote. + /// + /// The handler to invoke with the unpushed commits. + /// The current command instance for method chaining. IPushCommand OnUnPushedCommits(Action> unPushedCommits); + /// + /// Registers a confirmation callback invoked before the push is executed. + /// + /// The callback that returns to proceed with the push; to cancel. + /// The current command instance for method chaining. IPushCommand OnConfirm(Func doConfirm); + /// + /// Executes the push operation. + /// void Run(); } diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitFastForwardStrategy.cs b/source/Git/CreativeCoders.Git.Abstractions/GitFastForwardStrategy.cs index d61d119..6ba56be 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitFastForwardStrategy.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitFastForwardStrategy.cs @@ -1,5 +1,8 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Specifies the fast-forward strategy for a merge operation. +/// public enum GitFastForwardStrategy { /// diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitFetchOptions.cs b/source/Git/CreativeCoders.Git.Abstractions/GitFetchOptions.cs index a7a25cb..39f53ce 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitFetchOptions.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitFetchOptions.cs @@ -1,10 +1,23 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Represents options for a Git fetch operation. +/// public class GitFetchOptions { + /// + /// Gets or sets a value that indicates whether remote-tracking references that no longer exist on the remote should be removed. + /// + /// to prune stale remote-tracking references; otherwise, . The default is , which uses the configured default. public bool? Prune { get; set; } + /// + /// Gets or sets the tag fetch mode controlling which tags are downloaded. + /// public GitTagFetchMode? TagFetchMode { get; set; } + /// + /// Gets or sets custom headers to include in the fetch request. + /// public string[]? CustomHeaders { get; set; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitMergeFileFavor.cs b/source/Git/CreativeCoders.Git.Abstractions/GitMergeFileFavor.cs index 3f6d1ea..1eebbcd 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitMergeFileFavor.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitMergeFileFavor.cs @@ -1,5 +1,8 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Specifies how conflicting file content should be resolved during a merge. +/// public enum GitMergeFileFavor { /// diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitMergeOptions.cs b/source/Git/CreativeCoders.Git.Abstractions/GitMergeOptions.cs index b58ecd9..9d2320d 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitMergeOptions.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitMergeOptions.cs @@ -2,6 +2,9 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Represents options for a Git merge operation. +/// [PublicAPI] public class GitMergeOptions { @@ -16,6 +19,9 @@ public class GitMergeOptions /// public int TargetLimit { get; set; } = 200; + /// + /// Gets or sets the fast-forward strategy for the merge. + /// public GitFastForwardStrategy FastForwardStrategy { get; set; } /// diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitPushOptions.cs b/source/Git/CreativeCoders.Git.Abstractions/GitPushOptions.cs index 7c67f54..441bb98 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitPushOptions.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitPushOptions.cs @@ -2,8 +2,15 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Represents options for a Git push operation. +/// [ExcludeFromCodeCoverage] public class GitPushOptions { + /// + /// Gets or sets a value that indicates whether the remote branch should be created if it does not exist. + /// + /// to create the remote branch if it does not exist; otherwise, . The default is . public bool CreateRemoteBranchIfNotExists { get; set; } = true; } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitRepositoryBranchExtensions.cs b/source/Git/CreativeCoders.Git.Abstractions/GitRepositoryBranchExtensions.cs index 7b1fef5..1831377 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitRepositoryBranchExtensions.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitRepositoryBranchExtensions.cs @@ -6,9 +6,21 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Provides extension methods for branch operations on and . +/// [PublicAPI] public static class GitRepositoryBranchExtensions { + /// + /// Creates a new branch from the specified source branch. + /// + /// The repository in which to create the branch. + /// The name of the source branch to branch from. + /// The name of the new branch to create. + /// to fetch tags and pull the source branch before creating; otherwise, . + /// The newly created branch, or if creation failed. + /// The source branch does not exist. public static IGitBranch? CreateBranch(this IGitRepository gitRepository, string sourceBranchName, string newBranchName, bool updateSourceBranchBefore) { @@ -29,11 +41,21 @@ public static class GitRepositoryBranchExtensions return gitRepository.Branches.CreateBranch(newBranchName); } + /// + /// Determines whether the branch has been pushed to its tracked remote branch. + /// + /// The branch to check. + /// if the branch is remote or its tip matches the tracked branch tip; otherwise, . public static bool BranchIsPushedToRemote(this IGitBranch branch) { return branch.IsRemote || branch.Tip?.Sha == branch.TrackedBranch?.Tip?.Sha; } + /// + /// Enumerates the commits on the branch that have not yet been pushed to the tracked remote branch. + /// + /// The branch whose unpushed commits to enumerate. + /// A sequence of commits that exist locally but not on the tracked remote branch. public static IEnumerable UnPushedCommits(this IGitBranch branch) { if (branch.TrackedBranch == null || branch.Commits == null) diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitRepositoryFetchExtensions.cs b/source/Git/CreativeCoders.Git.Abstractions/GitRepositoryFetchExtensions.cs index e1927a0..1967a73 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitRepositoryFetchExtensions.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitRepositoryFetchExtensions.cs @@ -4,33 +4,59 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Provides extension methods for fetch operations on . +/// [PublicAPI] public static class GitRepositoryFetchExtensions { + /// + /// Fetches changes from the origin remote using the specified options. + /// + /// The repository to fetch into. + /// The options controlling fetch behavior. public static void FetchFromOrigin(this IGitRepository gitRepository, GitFetchOptions fetchOptions) { Ensure.NotNull(gitRepository) .Fetch(GitRemotes.Origin, fetchOptions); } + /// + /// Fetches all tags from the specified remote. + /// + /// The repository to fetch into. + /// The name of the remote to fetch tags from. public static void FetchAllTags(this IGitRepository gitRepository, string remoteName) { Ensure.NotNull(gitRepository) .Fetch(remoteName, new GitFetchOptions { TagFetchMode = GitTagFetchMode.All }); } + /// + /// Fetches all tags from the origin remote. + /// + /// The repository to fetch into. public static void FetchAllTagsFromOrigin(this IGitRepository gitRepository) { Ensure.NotNull(gitRepository) .Fetch(GitRemotes.Origin, new GitFetchOptions { TagFetchMode = GitTagFetchMode.All }); } + /// + /// Fetches from the specified remote with pruning enabled, removing stale remote-tracking references. + /// + /// The repository to fetch into. + /// The name of the remote to fetch from. public static void FetchPrune(this IGitRepository gitRepository, string remoteName) { Ensure.NotNull(gitRepository) .Fetch(remoteName, new GitFetchOptions { Prune = true }); } + /// + /// Fetches from the origin remote with pruning enabled, removing stale remote-tracking references. + /// + /// The repository to fetch into. public static void FetchPruneFromOrigin(this IGitRepository gitRepository) { Ensure.NotNull(gitRepository) diff --git a/source/Git/CreativeCoders.Git.Abstractions/GitTagFetchMode.cs b/source/Git/CreativeCoders.Git.Abstractions/GitTagFetchMode.cs index 7d53afa..b53034b 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/GitTagFetchMode.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/GitTagFetchMode.cs @@ -1,5 +1,8 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Specifies the behavior for downloading tags during a fetch operation. +/// public enum GitTagFetchMode { /// diff --git a/source/Git/CreativeCoders.Git.Abstractions/IGitRepository.cs b/source/Git/CreativeCoders.Git.Abstractions/IGitRepository.cs index 60967bb..612bab0 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/IGitRepository.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/IGitRepository.cs @@ -11,38 +11,100 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Represents a Git repository and provides access to common Git operations. +/// [PublicAPI] public interface IGitRepository : IDisposable { + /// + /// Pulls changes from the tracked remote branch into the current branch. + /// + /// The result of the merge operation performed during the pull. GitMergeResult Pull(); + /// + /// Pushes local changes to the remote repository. + /// + /// The options controlling push behavior. void Push(GitPushOptions gitPushOptions); + /// + /// Fetches changes from the specified remote. + /// + /// The name of the remote to fetch from. + /// The options controlling fetch behavior. void Fetch(string remoteName, GitFetchOptions gitFetchOptions); + /// + /// Merges the source branch into the target branch. + /// + /// The name of the branch to merge from. + /// The name of the branch to merge into. + /// The options controlling merge behavior. + /// The result of the merge operation. GitMergeResult Merge(string sourceBranchName, string targetBranchName, GitMergeOptions mergeOptions); + /// + /// Determines whether the repository has uncommitted changes. + /// + /// to include untracked files; otherwise, . + /// if the repository has uncommitted changes; otherwise, . bool HasUncommittedChanges(bool includeUntracked); + /// + /// Gets the repository information. + /// IGitRepositoryInfo Info { get; } + /// + /// Gets a value that indicates whether HEAD is detached. + /// + /// if HEAD is detached; otherwise, . bool IsHeadDetached { get; } + /// + /// Gets the current HEAD branch. + /// IGitBranch Head { get; } + /// + /// Gets the collection of tags in the repository. + /// IGitTagCollection Tags { get; } + /// + /// Gets the collection of references in the repository. + /// IGitReferenceCollection Refs { get; } + /// + /// Gets the collection of branches in the repository. + /// IGitBranchCollection Branches { get; } + /// + /// Gets the commit log for the repository. + /// IGitCommitLog Commits { get; } + /// + /// Gets the collection of remotes configured for the repository. + /// IGitRemoteCollection Remotes { get; } + /// + /// Gets the differ for comparing tree changes in the repository. + /// IGitDiffer Differ { get; } + /// + /// Gets the command factory for creating Git commands. + /// IGitCommands Commands { get; } + /// + /// Gets or sets the handler invoked when a server certificate needs to be validated. + /// HostCertificateCheckHandler? CertificateCheck { get; set; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryFactory.cs b/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryFactory.cs index 5d3c94a..5feda22 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryFactory.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryFactory.cs @@ -2,10 +2,22 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Provides factory methods for creating instances. +/// [PublicAPI] public interface IGitRepositoryFactory { + /// + /// Opens a Git repository at the specified path. + /// + /// The path to the repository, or to use the current directory. + /// The opened repository. IGitRepository OpenRepository(string? path); + /// + /// Opens a Git repository from the current working directory. + /// + /// The opened repository. IGitRepository OpenRepositoryFromCurrentDir(); } diff --git a/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryInfo.cs b/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryInfo.cs index 36a60ae..e188d14 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryInfo.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryInfo.cs @@ -4,12 +4,24 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Provides information about a Git repository. +/// [PublicAPI] public interface IGitRepositoryInfo { + /// + /// Gets the file system path of the repository. + /// string? Path { get; } + /// + /// Gets the main branch type of the repository. + /// GitMainBranch MainBranch { get; } + /// + /// Gets the URI of the primary remote. + /// Uri RemoteUri { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryUtils.cs b/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryUtils.cs index 0500879..0200eb3 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryUtils.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/IGitRepositoryUtils.cs @@ -2,14 +2,38 @@ namespace CreativeCoders.Git.Abstractions; +/// +/// Provides utility methods for discovering, validating, and initializing Git repositories. +/// [PublicAPI] public interface IGitRepositoryUtils { + /// + /// Determines whether the specified path is a valid Git repository. + /// + /// The file system path to check. + /// if the path is a valid Git repository; otherwise, . bool IsValidGitPath(string path); + /// + /// Discovers the Git repository path by searching upward from the specified path. + /// + /// The starting path to search from. + /// The discovered repository path, or if no repository is found. string? DiscoverGitPath(string path); + /// + /// Initializes a new Git repository at the specified path. + /// + /// The file system path where the repository should be created. + /// The path to the initialized repository, or if initialization failed. string? InitRepository(string path); + /// + /// Initializes a new Git repository at the specified path. + /// + /// The file system path where the repository should be created. + /// to create a bare repository; otherwise, . + /// The path to the initialized repository, or if initialization failed. string? InitRepository(string path, bool isBare); } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutNotifyFlags.cs b/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutNotifyFlags.cs index 4cd536a..6f1b0cc 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutNotifyFlags.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutNotifyFlags.cs @@ -23,5 +23,6 @@ public enum GitCheckoutNotifyFlags Untracked = 8, /// Notify about ignored file. Ignored = 16, + /// Notify on all checkout events. All = 31 } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutNotifyHandler.cs b/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutNotifyHandler.cs index 20c910c..6c9e1d8 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutNotifyHandler.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutNotifyHandler.cs @@ -1,5 +1,16 @@ namespace CreativeCoders.Git.Abstractions.Merges; +/// +/// Represents a handler for checkout notifications that can cancel the operation. +/// +/// The path of the file being checked out. +/// A bitwise combination of the enumeration values that specifies the type of notification. +/// to continue the checkout; otherwise, to cancel. public delegate bool GitCheckoutNotifyHandler(string path, GitCheckoutNotifyFlags notifyFlags); +/// +/// Represents a handler for checkout notifications that does not cancel the operation. +/// +/// The path of the file being checked out. +/// A bitwise combination of the enumeration values that specifies the type of notification. public delegate void GitSimpleCheckoutNotifyHandler(string path, GitCheckoutNotifyFlags notifyFlags); diff --git a/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutProgressHandler.cs b/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutProgressHandler.cs index e372b9c..a819290 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutProgressHandler.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Merges/GitCheckoutProgressHandler.cs @@ -1,3 +1,9 @@ namespace CreativeCoders.Git.Abstractions.Merges; +/// +/// Represents a handler for checkout progress updates. +/// +/// The path of the file currently being processed. +/// The number of completed checkout steps. +/// The total number of checkout steps. public delegate void GitCheckoutProgressHandler(string path, int completedSteps, int totalSteps); diff --git a/source/Git/CreativeCoders.Git.Abstractions/Objects/IGitObject.cs b/source/Git/CreativeCoders.Git.Abstractions/Objects/IGitObject.cs index ea18e41..0c84ff0 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Objects/IGitObject.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Objects/IGitObject.cs @@ -3,10 +3,19 @@ namespace CreativeCoders.Git.Abstractions.Objects; +/// +/// Represents a Git object with an identity and SHA hash. +/// [PublicAPI] public interface IGitObject : IEquatable, IComparable { + /// + /// Gets the object identifier. + /// IGitObjectId Id { get; } + /// + /// Gets the full SHA hash of the object. + /// string Sha { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Objects/IGitObjectId.cs b/source/Git/CreativeCoders.Git.Abstractions/Objects/IGitObjectId.cs index c75897f..0c4e988 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Objects/IGitObjectId.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Objects/IGitObjectId.cs @@ -3,10 +3,21 @@ namespace CreativeCoders.Git.Abstractions.Objects; +/// +/// Represents a unique identifier for a Git object. +/// [PublicAPI] public interface IGitObjectId : IEquatable, IComparable { + /// + /// Gets the full SHA hash of the object. + /// string Sha { get; } + /// + /// Returns the abbreviated SHA hash with the specified prefix length. + /// + /// The number of characters to include from the SHA hash. + /// The abbreviated SHA hash string. string ToString(int prefixLength); } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPackBuilderProgress.cs b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPackBuilderProgress.cs index 68d816c..63ae89e 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPackBuilderProgress.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPackBuilderProgress.cs @@ -1,7 +1,16 @@ namespace CreativeCoders.Git.Abstractions.Pushes; +/// +/// Represents the progress of the pack builder during a Git push operation. +/// public class GitPackBuilderProgress { + /// + /// Initializes a new instance of the class. + /// + /// One of the enumeration values that specifies the current pack builder stage. + /// The number of objects processed so far. + /// The total number of objects to process. public GitPackBuilderProgress(GitPackBuilderStage stage, int current, int total) { Stage = stage; @@ -9,9 +18,18 @@ public GitPackBuilderProgress(GitPackBuilderStage stage, int current, int total) Total = total; } + /// + /// Gets the current pack builder stage. + /// public GitPackBuilderStage Stage { get; } + /// + /// Gets the number of objects processed so far. + /// public int Current { get; } + /// + /// Gets the total number of objects to process. + /// public int Total { get; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPackBuilderStage.cs b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPackBuilderStage.cs index fc4328b..274012c 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPackBuilderStage.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPackBuilderStage.cs @@ -1,7 +1,12 @@ namespace CreativeCoders.Git.Abstractions.Pushes; +/// +/// Specifies the stage of the pack builder during a push operation. +/// public enum GitPackBuilderStage { + /// The pack builder is counting objects. Counting, + /// The pack builder is computing deltas. Deltafying } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushStatusError.cs b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushStatusError.cs index 8844467..1adf9b5 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushStatusError.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushStatusError.cs @@ -1,14 +1,28 @@ namespace CreativeCoders.Git.Abstractions.Pushes; +/// +/// Represents an error reported for a specific reference during a Git push operation. +/// public class GitPushStatusError { + /// + /// Initializes a new instance of the class. + /// + /// The name of the reference that failed. + /// The error message describing the failure. public GitPushStatusError(string reference, string message) { Reference = reference; Message = message; } + /// + /// Gets the name of the reference that failed. + /// public string Reference { get; } + /// + /// Gets the error message describing the failure. + /// public string Message { get; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushTransferProgress.cs b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushTransferProgress.cs index 623f4dd..c70a047 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushTransferProgress.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushTransferProgress.cs @@ -1,7 +1,16 @@ namespace CreativeCoders.Git.Abstractions.Pushes; +/// +/// Represents the progress of the data transfer during a Git push operation. +/// public class GitPushTransferProgress { + /// + /// Initializes a new instance of the class. + /// + /// The number of objects transferred so far. + /// The total number of objects to transfer. + /// The number of bytes transferred so far. public GitPushTransferProgress(int current, int total, long bytes) { Current = current; @@ -9,9 +18,18 @@ public GitPushTransferProgress(int current, int total, long bytes) Bytes = bytes; } + /// + /// Gets the number of objects transferred so far. + /// public int Current { get; } + /// + /// Gets the total number of objects to transfer. + /// public int Total { get; } + /// + /// Gets the number of bytes transferred so far. + /// public long Bytes { get; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushUpdate.cs b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushUpdate.cs index 6957259..2f0fc3e 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushUpdate.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Pushes/GitPushUpdate.cs @@ -3,8 +3,18 @@ namespace CreativeCoders.Git.Abstractions.Pushes; +/// +/// Represents the mapping of a source reference to a destination reference during a Git push operation. +/// public class GitPushUpdate { + /// + /// Initializes a new instance of the class. + /// + /// The object ID of the source reference. + /// The name of the source reference. + /// The object ID of the destination reference. + /// The name of the destination reference. public GitPushUpdate(IGitObjectId sourceObjectId, string sourceRefName, IGitObjectId destinationObjectId, string destinationRefName) { @@ -14,11 +24,23 @@ public GitPushUpdate(IGitObjectId sourceObjectId, string sourceRefName, IGitObje DestinationRefName = destinationRefName; } + /// + /// Gets the object ID of the source reference. + /// public IGitObjectId SourceObjectId { get; } + /// + /// Gets the name of the source reference. + /// public string SourceRefName { get; } + /// + /// Gets the object ID of the destination reference. + /// public IGitObjectId DestinationObjectId { get; } + /// + /// Gets the name of the destination reference. + /// public string DestinationRefName { get; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/GitRefSpecDirection.cs b/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/GitRefSpecDirection.cs index 46b1a2f..ec32ecd 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/GitRefSpecDirection.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/GitRefSpecDirection.cs @@ -1,7 +1,12 @@ namespace CreativeCoders.Git.Abstractions.RefSpecs; +/// +/// Specifies the direction of a Git refspec. +/// public enum GitRefSpecDirection { + /// The refspec is used for fetch operations. Fetch, + /// The refspec is used for push operations. Push } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/IGitRefSpec.cs b/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/IGitRefSpec.cs index 8d5e215..1fedba1 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/IGitRefSpec.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/IGitRefSpec.cs @@ -3,14 +3,29 @@ namespace CreativeCoders.Git.Abstractions.RefSpecs; +/// +/// Represents a Git refspec that maps source references to destination references. +/// [PublicAPI] public interface IGitRefSpec : IEquatable, IComparable { + /// + /// Gets the full refspec specification string. + /// string Specification { get; } + /// + /// Gets the direction of the refspec. + /// GitRefSpecDirection Direction { get; } + /// + /// Gets the source part of the refspec. + /// string Source { get; } + /// + /// Gets the destination part of the refspec. + /// string Destination { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/IGitRefSpecCollection.cs b/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/IGitRefSpecCollection.cs index afd0da7..14ec407 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/IGitRefSpecCollection.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/RefSpecs/IGitRefSpecCollection.cs @@ -2,4 +2,7 @@ namespace CreativeCoders.Git.Abstractions.RefSpecs; +/// +/// Represents a collection of instances. +/// public interface IGitRefSpecCollection : IEnumerable; diff --git a/source/Git/CreativeCoders.Git.Abstractions/References/IGitReference.cs b/source/Git/CreativeCoders.Git.Abstractions/References/IGitReference.cs index fd68ca0..6ece036 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/References/IGitReference.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/References/IGitReference.cs @@ -5,10 +5,19 @@ namespace CreativeCoders.Git.Abstractions.References; +/// +/// Represents a Git reference pointing to a target object or another reference. +/// [PublicAPI] public interface IGitReference : IEquatable, IComparable, INamedReference { + /// + /// Gets the target identifier of the reference (a SHA or another reference name). + /// string TargetIdentifier { get; } + /// + /// Gets the object ID that the reference ultimately points to. + /// IGitObjectId? ReferenceTargetId { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/References/IGitReferenceCollection.cs b/source/Git/CreativeCoders.Git.Abstractions/References/IGitReferenceCollection.cs index befdcdc..495592f 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/References/IGitReferenceCollection.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/References/IGitReferenceCollection.cs @@ -4,16 +4,43 @@ namespace CreativeCoders.Git.Abstractions.References; +/// +/// Represents the collection of references in a Git repository. +/// [PublicAPI] public interface IGitReferenceCollection : IEnumerable { + /// + /// Gets the HEAD reference. + /// IGitReference? Head { get; } + /// + /// Gets the reference with the specified name. + /// + /// The name of the reference. + /// The matching reference, or if not found. IGitReference? this[string name] { get; } + /// + /// Adds a new reference with the specified name and target. + /// + /// The name of the reference to create. + /// The canonical reference name or object SHA to point to. + /// to overwrite an existing reference; otherwise, . void Add(string name, string canonicalRefNameOrObjectish, bool allowOverwrite = false); + /// + /// Updates the target of a direct reference to point to a new object. + /// + /// The direct reference to update. + /// The new target object ID. void UpdateTarget(IGitReference directRef, IGitObjectId targetId); + /// + /// Returns all references whose names match the specified glob pattern. + /// + /// The glob pattern to match reference names against. + /// A sequence of matching references. IEnumerable FromGlob(string prefix); } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Remotes/IGitRemote.cs b/source/Git/CreativeCoders.Git.Abstractions/Remotes/IGitRemote.cs index 79df4a7..ef6ac4b 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Remotes/IGitRemote.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Remotes/IGitRemote.cs @@ -4,18 +4,39 @@ namespace CreativeCoders.Git.Abstractions.Remotes; +/// +/// Represents a configured Git remote. +/// [PublicAPI] public interface IGitRemote { + /// + /// Gets the name of the remote. + /// string Name { get; } + /// + /// Gets the fetch URL of the remote. + /// string Url { get; } + /// + /// Gets the push URL of the remote. + /// string PushUrl { get; } + /// + /// Gets all refspecs configured for the remote. + /// IEnumerable RefSpecs { get; } + /// + /// Gets the fetch refspecs configured for the remote. + /// IEnumerable FetchRefSpecs { get; } + /// + /// Gets the push refspecs configured for the remote. + /// IEnumerable PushRefSpecs { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Abstractions/Remotes/IGitRemoteCollection.cs b/source/Git/CreativeCoders.Git.Abstractions/Remotes/IGitRemoteCollection.cs index b86d174..db5d9b6 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Remotes/IGitRemoteCollection.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Remotes/IGitRemoteCollection.cs @@ -3,9 +3,17 @@ namespace CreativeCoders.Git.Abstractions.Remotes; +/// +/// Represents the collection of remotes configured for a Git repository. +/// [PublicAPI] public interface IGitRemoteCollection : IEnumerable { + /// + /// Gets the remote with the specified name. + /// + /// The name of the remote. + /// The matching remote, or if not found. IGitRemote? this[string name] { get; } //void Remove(string remoteName); diff --git a/source/Git/CreativeCoders.Git.Abstractions/Tags/IGitTag.cs b/source/Git/CreativeCoders.Git.Abstractions/Tags/IGitTag.cs index 7741689..3615185 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Tags/IGitTag.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Tags/IGitTag.cs @@ -5,12 +5,25 @@ namespace CreativeCoders.Git.Abstractions.Tags; +/// +/// Represents a Git tag pointing to a target object. +/// [PublicAPI] public interface IGitTag : IEquatable, IComparable, INamedReference { + /// + /// Gets the SHA hash of the target object. + /// string TargetSha { get; } + /// + /// Peels the tag to its target commit, resolving annotated tags to the underlying commit. + /// + /// The target commit, or if the tag does not point to a commit. IGitCommit? PeeledTargetCommit(); + /// + /// Gets the commit that the tag directly points to. + /// IGitCommit? TargetCommit { get; } } diff --git a/source/Git/CreativeCoders.Git.Abstractions/Tags/IGitTagCollection.cs b/source/Git/CreativeCoders.Git.Abstractions/Tags/IGitTagCollection.cs index d620e8a..7842303 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Tags/IGitTagCollection.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Tags/IGitTagCollection.cs @@ -2,21 +2,62 @@ namespace CreativeCoders.Git.Abstractions.Tags; +/// +/// Represents the collection of tags in a Git repository. +/// public interface IGitTagCollection : IEnumerable { + /// + /// Creates a lightweight tag with the specified name. + /// + /// The name of the tag to create. + /// The target object SHA or reference, or to tag HEAD. + /// The newly created tag. IGitTag CreateTag(string tagName, string? objectish = null); + /// + /// Creates an annotated tag with the specified name and message. + /// + /// The name of the tag to create. + /// The tag message. + /// The target object SHA or reference, or to tag HEAD. + /// The newly created tag. IGitTag CreateTagWithMessage(string tagName, string message, string? objectish = null); + /// + /// Deletes the tag with the specified name. + /// + /// The name of the tag to delete. + /// to also delete the tag on the remote; otherwise, . void DeleteTag(string tagName, bool deleteOnRemote = false); + /// + /// Deletes the specified tag. + /// + /// The tag to delete. + /// to also delete the tag on the remote; otherwise, . void DeleteTag(IGitTag tag, bool deleteOnRemote = false); + /// + /// Deletes a tag on the remote repository. + /// + /// The name of the remote tag to delete. void DeleteRemoteTag(string tagName); + /// + /// Pushes the tag with the specified name to the remote repository. + /// + /// The name of the tag to push. void PushTag(string tagName); + /// + /// Pushes the specified tag to the remote repository. + /// + /// The tag to push. void PushTag(IGitTag tag); + /// + /// Pushes all local tags to the remote repository. + /// void PushAllTags(); } From 0fb1854d2aa990af320650bb1faccb0132645f36 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sat, 28 Mar 2026 19:37:51 +0100 Subject: [PATCH 04/13] chore: add detailed XML documentation for classes and interfaces - Added comprehensive XML comments across the codebase to improve maintainability. - Enhanced constructors, methods, and properties with parameter and return value summaries. --- .../Auth/DefaultGitCredentialProviders.cs | 7 +++ .../CreativeCoders.Git/Auth/GitCredential.cs | 7 +++ .../Auth/GitCredentialsHandler.cs | 11 ++++ .../CreativeCoders.Git/Branches/GitBranch.cs | 18 ++++++ .../Branches/GitBranchCollection.cs | 9 +++ .../CreativeCoders.Git/Commits/GitCommit.cs | 17 +++++ .../Commits/GitCommitLog.cs | 9 +++ .../Common/ActionExceptionWrapper.cs | 22 +++++++ .../Common/FuncExceptionWrapper.cs | 24 +++++++ .../Common/GitConvertExtensions.cs | 62 +++++++++++++++++++ .../CreativeCoders.Git/Common/GitSignature.cs | 10 +++ .../DefaultGitRepository.cs | 29 +++++++++ .../DefaultGitRepositoryFactory.cs | 8 +++ .../GitRepositoryOptions.cs | 7 +++ .../GitServiceCollectionExtensions.cs | 13 ++++ .../Git/CreativeCoders.Git/Diffs/GitDiffer.cs | 11 ++++ .../Diffs/GitTreeChanges.cs | 17 +++++ .../Diffs/GitTreeEntryChanges.cs | 16 +++++ .../GitCommands/CommandConverters.cs | 9 +++ .../GitCommands/FetchTagsCommand.cs | 5 ++ .../GitCommands/GitCommands.cs | 10 +++ .../GitCommands/PullCommand.cs | 14 +++++ .../GitCommands/PushCommand.cs | 22 +++++++ .../CreativeCoders.Git/GitRepositoryInfo.cs | 7 +++ .../CreativeCoders.Git/GitRepositoryUtils.cs | 7 +++ .../Git/CreativeCoders.Git/ILibGitCaller.cs | 13 ++++ source/Git/CreativeCoders.Git/LibGitCaller.cs | 5 ++ .../GitCheckoutNotifyFlagsExtensions.cs | 13 ++++ .../Merges/GitMergeOptions.cs | 8 ++- .../CreativeCoders.Git/Objects/GitObject.cs | 9 +++ .../CreativeCoders.Git/Objects/GitObjectId.cs | 17 +++++ .../CreativeCoders.Git/RefSpecs/GitRefSpec.cs | 16 +++++ .../RefSpecs/GitRefSpecCollection.cs | 7 +++ .../References/GitReference.cs | 14 +++++ .../References/GitReferenceCollection.cs | 12 ++++ .../CreativeCoders.Git/Remotes/GitRemote.cs | 17 +++++ .../Remotes/GitRemoteCollection.cs | 8 +++ .../CreativeCoders.Git/RepositoryContext.cs | 31 ++++++++++ source/Git/CreativeCoders.Git/Tags/GitTag.cs | 15 +++++ .../Tags/GitTagCollection.cs | 11 ++++ 40 files changed, 566 insertions(+), 1 deletion(-) diff --git a/source/Git/CreativeCoders.Git/Auth/DefaultGitCredentialProviders.cs b/source/Git/CreativeCoders.Git/Auth/DefaultGitCredentialProviders.cs index 3f83098..6a364e1 100644 --- a/source/Git/CreativeCoders.Git/Auth/DefaultGitCredentialProviders.cs +++ b/source/Git/CreativeCoders.Git/Auth/DefaultGitCredentialProviders.cs @@ -3,16 +3,22 @@ namespace CreativeCoders.Git.Auth; +/// +/// Provides the default implementation of that aggregates multiple credential providers. +/// +/// The collection of registered credential providers. internal class DefaultGitCredentialProviders(IEnumerable providers) : IGitCredentialProviders { private readonly IEnumerable _providers = Ensure.NotNull(providers); + /// public IGitCredentialProvider? GetProvider(string providerName) { return _providers.FirstOrDefault(x => x.Name.Equals(providerName, StringComparison.InvariantCultureIgnoreCase)); } + /// public IGitCredential? GetCredentials(string url, string? fromUrl) { return _providers @@ -21,5 +27,6 @@ internal class DefaultGitCredentialProviders(IEnumerable .FirstOrDefault(credential => credential != null); } + /// [ExcludeFromCodeCoverage] public string Name => "Default"; } diff --git a/source/Git/CreativeCoders.Git/Auth/GitCredential.cs b/source/Git/CreativeCoders.Git/Auth/GitCredential.cs index be5669e..d6b0f3b 100644 --- a/source/Git/CreativeCoders.Git/Auth/GitCredential.cs +++ b/source/Git/CreativeCoders.Git/Auth/GitCredential.cs @@ -3,10 +3,17 @@ namespace CreativeCoders.Git.Auth; +/// +/// Represents a Git credential consisting of a username and password. +/// +/// The username. +/// The password. [ExcludeFromCodeCoverage] public class GitCredential(string userName, string password) : IGitCredential { + /// public string UserName { get; } = userName; + /// public string Password { get; } = password; } diff --git a/source/Git/CreativeCoders.Git/Auth/GitCredentialsHandler.cs b/source/Git/CreativeCoders.Git/Auth/GitCredentialsHandler.cs index a93877e..1b73af6 100644 --- a/source/Git/CreativeCoders.Git/Auth/GitCredentialsHandler.cs +++ b/source/Git/CreativeCoders.Git/Auth/GitCredentialsHandler.cs @@ -3,10 +3,21 @@ namespace CreativeCoders.Git.Auth; +/// +/// Handles credential requests from LibGit2Sharp by delegating to registered . +/// +/// The credential providers to query for credentials. public class GitCredentialsHandler(IGitCredentialProviders credentialProviders) { private readonly IGitCredentialProviders _credentialProviders = Ensure.NotNull(credentialProviders); + /// + /// Handles a credential request by resolving credentials from the registered providers. + /// + /// The URL of the remote repository. + /// The username extracted from the URL, or . + /// The supported credential types. + /// The resolved credentials, or if no credentials are available. public Credentials? HandleCredentials(string url, string? usernameFromUrl, SupportedCredentialTypes types) { var credential = _credentialProviders.GetCredentials(url, usernameFromUrl); diff --git a/source/Git/CreativeCoders.Git/Branches/GitBranch.cs b/source/Git/CreativeCoders.Git/Branches/GitBranch.cs index fb6240c..4c9dff7 100644 --- a/source/Git/CreativeCoders.Git/Branches/GitBranch.cs +++ b/source/Git/CreativeCoders.Git/Branches/GitBranch.cs @@ -5,10 +5,17 @@ namespace CreativeCoders.Git.Branches; +/// +/// Represents a Git branch wrapping a LibGit2Sharp . +/// public class GitBranch : ComparableObject, IGitBranch { private readonly Branch _branch; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp branch. internal GitBranch(Branch branch) { _branch = Ensure.NotNull(branch); @@ -28,19 +35,30 @@ internal GitBranch(Branch branch) : new GitBranch(branch); } + /// public ReferenceName Name { get; } + /// public IGitCommit? Tip { get; } + /// public bool IsRemote => _branch.IsRemote; + /// public bool IsTracking => _branch.IsTracking; + /// public IGitBranch? TrackedBranch { get; } + /// public bool IsDetachedHead => Name.Canonical.Equals("(no branch)", StringComparison.OrdinalIgnoreCase); + /// public IGitCommitLog? Commits { get; } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git branch to convert. public static implicit operator Branch(GitBranch branch) => branch._branch; } diff --git a/source/Git/CreativeCoders.Git/Branches/GitBranchCollection.cs b/source/Git/CreativeCoders.Git/Branches/GitBranchCollection.cs index d524bdb..428c1b3 100644 --- a/source/Git/CreativeCoders.Git/Branches/GitBranchCollection.cs +++ b/source/Git/CreativeCoders.Git/Branches/GitBranchCollection.cs @@ -3,6 +3,9 @@ namespace CreativeCoders.Git.Branches; +/// +/// Represents a collection of Git branches with operations for checkout, creation, and deletion. +/// public class GitBranchCollection : IGitBranchCollection { private readonly BranchCollection _branchCollection; @@ -19,6 +22,7 @@ internal GitBranchCollection(RepositoryContext context) _libGitCaller = _context.LibGitCaller; } + /// public IGitBranch? CheckOut(string branchName) { Ensure.Argument(branchName).NotNullOrEmpty(); @@ -36,11 +40,13 @@ internal GitBranchCollection(RepositoryContext context) return GitBranch.From(checkedOutBranch); } + /// public IGitBranch? CreateBranch(string branchName) { return GitBranch.From(_libGitCaller.Invoke(() => _context.LibGitRepository.CreateBranch(branchName))); } + /// public void DeleteLocalBranch(string branchName) { var branch = _libGitCaller.Invoke(() => _context.LibGitRepository.Branches[branchName]); @@ -61,8 +67,10 @@ IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); } + /// public IGitBranch? this[string name] => GitBranch.From(_branchCollection[name]); + /// public IGitBranch? FindLocalBranchByFriendlyName(string branchName) { return this.FirstOrDefault(x => @@ -70,6 +78,7 @@ IEnumerator IEnumerable.GetEnumerator() x.Name.Friendly.Equals(branchName, StringComparison.OrdinalIgnoreCase)); } + /// public IGitBranch? FindRemoteBranchByFriendlyName(string branchName) { var remoteNames = _context.Repository.Remotes.Select(x => x.Name); diff --git a/source/Git/CreativeCoders.Git/Commits/GitCommit.cs b/source/Git/CreativeCoders.Git/Commits/GitCommit.cs index 9138f64..0162465 100644 --- a/source/Git/CreativeCoders.Git/Commits/GitCommit.cs +++ b/source/Git/CreativeCoders.Git/Commits/GitCommit.cs @@ -4,10 +4,17 @@ namespace CreativeCoders.Git.Commits; +/// +/// Represents a Git commit containing author, committer, message, and parent information. +/// public sealed class GitCommit : Objects.GitObject, IGitCommit { private readonly Commit _commit; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp commit. internal GitCommit(Commit commit) : base(commit) { _commit = Ensure.NotNull(commit); @@ -24,23 +31,33 @@ internal GitCommit(Commit commit) : base(commit) : new GitCommit(commit); } + /// public bool Equals(IGitCommit? other) { return base.Equals(other); } + /// public int CompareTo(IGitCommit? other) { return base.CompareTo(other); } + /// public IEnumerable Parents { get; } + /// public IGitSignature Author { get; } + /// public IGitSignature Committer { get; } + /// public string Message => _commit.Message; + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git commit to convert. public static implicit operator Commit(GitCommit commit) => commit._commit; } diff --git a/source/Git/CreativeCoders.Git/Commits/GitCommitLog.cs b/source/Git/CreativeCoders.Git/Commits/GitCommitLog.cs index 7abaf0f..5eb11fe 100644 --- a/source/Git/CreativeCoders.Git/Commits/GitCommitLog.cs +++ b/source/Git/CreativeCoders.Git/Commits/GitCommitLog.cs @@ -2,10 +2,17 @@ namespace CreativeCoders.Git.Commits; +/// +/// Represents an enumerable log of Git commits. +/// public class GitCommitLog : IGitCommitLog { private readonly ICommitLog _commitLog; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp commit log. internal GitCommitLog(ICommitLog commitLog) { _commitLog = Ensure.NotNull(commitLog); @@ -26,9 +33,11 @@ IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); } + /// public IEnumerable GetCommitsPriorTo(DateTimeOffset olderThan) => this.SkipWhile(c => c.Committer.When > olderThan); + /// public IEnumerable QueryBy(GitCommitFilter commitFilter) { throw new NotImplementedException(); diff --git a/source/Git/CreativeCoders.Git/Common/ActionExceptionWrapper.cs b/source/Git/CreativeCoders.Git/Common/ActionExceptionWrapper.cs index e7f6ee7..7709cb2 100644 --- a/source/Git/CreativeCoders.Git/Common/ActionExceptionWrapper.cs +++ b/source/Git/CreativeCoders.Git/Common/ActionExceptionWrapper.cs @@ -1,5 +1,9 @@ namespace CreativeCoders.Git.Common; +/// +/// Wraps an and translates a specific exception type into a different exception. +/// +/// The type of exception to catch and wrap. [PublicAPI] public class ActionExceptionWrapper where TException : Exception @@ -8,11 +12,20 @@ public class ActionExceptionWrapper private Func? _createWrapperException; + /// + /// Initializes a new instance of the class. + /// + /// The action to wrap. public ActionExceptionWrapper(Action action) { _action = action; } + /// + /// Configures the factory function that creates the wrapper exception from the caught exception. + /// + /// A function that creates the wrapper exception. + /// The current instance for fluent chaining. public ActionExceptionWrapper Wrap(Func createWrapperException) { _createWrapperException = createWrapperException; @@ -20,6 +33,12 @@ public ActionExceptionWrapper Wrap(Func creat return this; } + /// + /// Chains an additional exception wrapper for a different exception type. + /// + /// The type of exception to catch in the chained wrapper. + /// A function that creates the wrapper exception. + /// A new wrapping this instance. public ActionExceptionWrapper AndWrap( Func createWrapperException) where TException2 : Exception @@ -27,6 +46,9 @@ public ActionExceptionWrapper AndWrap( return new ActionExceptionWrapper(Execute).Wrap(createWrapperException); } + /// + /// Executes the wrapped action, catching and translating the configured exception type. + /// public void Execute() { try diff --git a/source/Git/CreativeCoders.Git/Common/FuncExceptionWrapper.cs b/source/Git/CreativeCoders.Git/Common/FuncExceptionWrapper.cs index 41cf6c5..e084895 100644 --- a/source/Git/CreativeCoders.Git/Common/FuncExceptionWrapper.cs +++ b/source/Git/CreativeCoders.Git/Common/FuncExceptionWrapper.cs @@ -1,5 +1,10 @@ namespace CreativeCoders.Git.Common; +/// +/// Wraps a and translates a specific exception type into a different exception. +/// +/// The type of exception to catch and wrap. +/// The return type of the wrapped function. [PublicAPI] public class FuncExceptionWrapper where TException : Exception @@ -8,11 +13,20 @@ public class FuncExceptionWrapper private Func? _createWrapperException; + /// + /// Initializes a new instance of the class. + /// + /// The function to wrap. public FuncExceptionWrapper(Func func) { _func = func; } + /// + /// Configures the factory function that creates the wrapper exception from the caught exception. + /// + /// A function that creates the wrapper exception. + /// The current instance for fluent chaining. public FuncExceptionWrapper Wrap(Func createWrapperException) { _createWrapperException = createWrapperException; @@ -20,6 +34,12 @@ public FuncExceptionWrapper Wrap(Func + /// Chains an additional exception wrapper for a different exception type. + /// + /// The type of exception to catch in the chained wrapper. + /// A function that creates the wrapper exception. + /// A new wrapping this instance. public FuncExceptionWrapper AndWrap( Func createWrapperException) where TException2 : Exception @@ -27,6 +47,10 @@ public FuncExceptionWrapper AndWrap( return new FuncExceptionWrapper(Execute).Wrap(createWrapperException); } + /// + /// Executes the wrapped function, catching and translating the configured exception type. + /// + /// The result of the wrapped function. public TResult Execute() { try diff --git a/source/Git/CreativeCoders.Git/Common/GitConvertExtensions.cs b/source/Git/CreativeCoders.Git/Common/GitConvertExtensions.cs index dc37c4b..69ee48b 100644 --- a/source/Git/CreativeCoders.Git/Common/GitConvertExtensions.cs +++ b/source/Git/CreativeCoders.Git/Common/GitConvertExtensions.cs @@ -5,8 +5,17 @@ namespace CreativeCoders.Git.Common; +/// +/// Provides extension methods for converting between LibGit2Sharp types and their Git abstraction equivalents. +/// public static class GitConvertExtensions { + /// + /// Converts a LibGit2Sharp to a . + /// + /// The LibGit2Sharp ref spec direction. + /// The corresponding value. + /// The value is not a recognized direction. public static GitRefSpecDirection ToGitRefSpecDirection(this RefSpecDirection refSpecDirection) { return refSpecDirection switch @@ -17,6 +26,12 @@ public static GitRefSpecDirection ToGitRefSpecDirection(this RefSpecDirection re }; } + /// + /// Converts a LibGit2Sharp to a . + /// + /// The LibGit2Sharp merge status. + /// The corresponding value. + /// The value is not a recognized merge status. public static GitMergeStatus ToGitMergeStatus(this MergeStatus mergeStatus) { return mergeStatus switch @@ -29,6 +44,12 @@ public static GitMergeStatus ToGitMergeStatus(this MergeStatus mergeStatus) }; } + /// + /// Converts a nullable to a nullable LibGit2Sharp . + /// + /// The Git tag fetch mode, or . + /// The corresponding value, or . + /// The value is not a recognized tag fetch mode. public static TagFetchMode? ToTagFetchMode(this GitTagFetchMode? tagFetchMode) { if (tagFetchMode == null) @@ -46,6 +67,12 @@ public static GitMergeStatus ToGitMergeStatus(this MergeStatus mergeStatus) }; } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git fetch options. + /// The credentials handler for authentication. + /// A new instance. public static FetchOptions ToFetchOptions(this GitFetchOptions fetchOptions, CredentialsHandler credentialsHandler) { @@ -58,6 +85,12 @@ public static FetchOptions ToFetchOptions(this GitFetchOptions fetchOptions, }; } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git fast-forward strategy. + /// The corresponding value. + /// The value is not a recognized fast-forward strategy. public static FastForwardStrategy ToFastForwardStrategy(this GitFastForwardStrategy fastForwardStrategy) { return fastForwardStrategy switch @@ -69,6 +102,12 @@ public static FastForwardStrategy ToFastForwardStrategy(this GitFastForwardStrat }; } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git checkout file conflict strategy. + /// The corresponding value. + /// The value is not a recognized file conflict strategy. public static CheckoutFileConflictStrategy ToFileConflictStrategy( this GitCheckoutFileConflictStrategy fileConflictStrategy) { @@ -83,6 +122,12 @@ public static CheckoutFileConflictStrategy ToFileConflictStrategy( }; } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git merge file favor. + /// The corresponding value. + /// The value is not a recognized merge file favor. public static MergeFileFavor ToMergeFileFavor(this GitMergeFileFavor mergeFileFavor) { return mergeFileFavor switch @@ -95,6 +140,11 @@ public static MergeFileFavor ToMergeFileFavor(this GitMergeFileFavor mergeFileFa }; } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git merge options. + /// A new instance. public static MergeOptions ToMergeOptions(this GitMergeOptions mergeOptions) { return new MergeOptions @@ -112,6 +162,12 @@ public static MergeOptions ToMergeOptions(this GitMergeOptions mergeOptions) }; } + /// + /// Converts a LibGit2Sharp to a . + /// + /// The LibGit2Sharp change kind. + /// The corresponding value. + /// The value is not a recognized change kind. public static GitEntryChangeKind ToGitEntryChangeKind(this ChangeKind changeKind) { return changeKind switch @@ -131,6 +187,12 @@ public static GitEntryChangeKind ToGitEntryChangeKind(this ChangeKind changeKind }; } + /// + /// Converts a LibGit2Sharp to a . + /// + /// The LibGit2Sharp file mode. + /// The corresponding value. + /// The value is not a recognized file mode. public static GitEntryMode ToGitEntryMode(this Mode mode) { return mode switch diff --git a/source/Git/CreativeCoders.Git/Common/GitSignature.cs b/source/Git/CreativeCoders.Git/Common/GitSignature.cs index ea39fad..2fddd17 100644 --- a/source/Git/CreativeCoders.Git/Common/GitSignature.cs +++ b/source/Git/CreativeCoders.Git/Common/GitSignature.cs @@ -2,18 +2,28 @@ namespace CreativeCoders.Git.Common; +/// +/// Represents a Git signature containing name, email, and timestamp information. +/// public class GitSignature : IGitSignature { private readonly Signature _signature; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp signature. public GitSignature(Signature signature) { _signature = Ensure.NotNull(signature); } + /// public DateTimeOffset When => _signature.When; + /// public string Name => _signature.Name; + /// public string Email => _signature.Email; } diff --git a/source/Git/CreativeCoders.Git/DefaultGitRepository.cs b/source/Git/CreativeCoders.Git/DefaultGitRepository.cs index d05f781..5450430 100644 --- a/source/Git/CreativeCoders.Git/DefaultGitRepository.cs +++ b/source/Git/CreativeCoders.Git/DefaultGitRepository.cs @@ -20,6 +20,9 @@ namespace CreativeCoders.Git; +/// +/// Provides the default implementation of backed by LibGit2Sharp. +/// internal sealed class DefaultGitRepository : IGitRepository { private readonly IGitCredentialProviders _credentialProviders; @@ -28,6 +31,12 @@ internal sealed class DefaultGitRepository : IGitRepository private readonly Repository _repo; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp repository. + /// The credential providers for authentication. + /// The caller used to invoke LibGit2Sharp operations with exception handling. public DefaultGitRepository(Repository repo, IGitCredentialProviders credentialProviders, ILibGitCaller libGitCaller) { @@ -86,16 +95,19 @@ private Signature GetSignature() }; } + /// public void Dispose() { _repo.Dispose(); } + /// public GitMergeResult Pull() { return Commands.CreatePullCommand().Run(); } + /// public void Push(GitPushOptions gitPushOptions) { Commands.CreatePushCommand() @@ -103,6 +115,7 @@ public void Push(GitPushOptions gitPushOptions) .Run(); } + /// public void Fetch(string remoteName, GitFetchOptions gitFetchOptions) { var fetchOptions = gitFetchOptions.ToFetchOptions(GetCredentialsHandler()); @@ -119,6 +132,7 @@ public void Fetch(string remoteName, GitFetchOptions gitFetchOptions) _libGitCaller.Invoke(() => LibGit2Sharp.Commands.Fetch(_repo, remote.Name, refSpecs, fetchOptions, null)); } + /// public GitMergeResult Merge(string sourceBranchName, string targetBranchName, GitMergeOptions mergeOptions) { return _libGitCaller.Invoke(() => @@ -138,6 +152,7 @@ public GitMergeResult Merge(string sourceBranchName, string targetBranchName, Gi }); } + /// public bool HasUncommittedChanges(bool includeUntracked) { using var treeChanges = @@ -146,27 +161,41 @@ public bool HasUncommittedChanges(bool includeUntracked) return treeChanges.Count > 0; } + /// + /// Gets the underlying LibGit2Sharp repository instance. + /// internal Repository LibGit2Repository => _repo; + /// public IGitRepositoryInfo Info { get; } + /// public bool IsHeadDetached => _libGitCaller.Invoke(() => _repo.Info.IsHeadDetached); + /// public IGitBranch Head => GitBranch.From(_libGitCaller.Invoke(() => _repo.Head))!; + /// public IGitTagCollection Tags { get; } + /// public IGitReferenceCollection Refs { get; } + /// public IGitBranchCollection Branches { get; } + /// public IGitCommitLog Commits { get; } + /// public IGitRemoteCollection Remotes { get; } + /// public IGitDiffer Differ { get; } + /// public IGitCommands Commands { get; } + /// public HostCertificateCheckHandler? CertificateCheck { get; set; } } diff --git a/source/Git/CreativeCoders.Git/DefaultGitRepositoryFactory.cs b/source/Git/CreativeCoders.Git/DefaultGitRepositoryFactory.cs index f9f9ed0..9cceeb4 100644 --- a/source/Git/CreativeCoders.Git/DefaultGitRepositoryFactory.cs +++ b/source/Git/CreativeCoders.Git/DefaultGitRepositoryFactory.cs @@ -5,6 +5,12 @@ namespace CreativeCoders.Git; +/// +/// Provides the default implementation of for opening Git repositories. +/// +/// The credential providers for authentication. +/// The repository utilities for path discovery. +/// The service provider for resolving dependencies. internal class DefaultGitRepositoryFactory( IGitCredentialProviders credentialProviders, IGitRepositoryUtils repositoryUtils, @@ -17,6 +23,7 @@ internal class DefaultGitRepositoryFactory( private readonly IServiceProvider _serviceProvider = Ensure.NotNull(serviceProvider); + /// public IGitRepository OpenRepository(string? path) { var repo = path == null @@ -28,6 +35,7 @@ public IGitRepository OpenRepository(string? path) _serviceProvider.GetRequiredService()); } + /// public IGitRepository OpenRepositoryFromCurrentDir() { return OpenRepository(Env.CurrentDirectory); diff --git a/source/Git/CreativeCoders.Git/DependencyInjection/GitRepositoryOptions.cs b/source/Git/CreativeCoders.Git/DependencyInjection/GitRepositoryOptions.cs index 57cb81f..7293149 100644 --- a/source/Git/CreativeCoders.Git/DependencyInjection/GitRepositoryOptions.cs +++ b/source/Git/CreativeCoders.Git/DependencyInjection/GitRepositoryOptions.cs @@ -2,8 +2,15 @@ namespace CreativeCoders.Git.DependencyInjection; +/// +/// Represents the configuration options for opening a Git repository via dependency injection. +/// [ExcludeFromCodeCoverage] public class GitRepositoryOptions { + /// + /// Gets or sets the file system path to the Git repository. + /// + /// The repository path. The default is . public string Path { get; set; } = string.Empty; } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git/DependencyInjection/GitServiceCollectionExtensions.cs b/source/Git/CreativeCoders.Git/DependencyInjection/GitServiceCollectionExtensions.cs index c4f38b1..2acb513 100644 --- a/source/Git/CreativeCoders.Git/DependencyInjection/GitServiceCollectionExtensions.cs +++ b/source/Git/CreativeCoders.Git/DependencyInjection/GitServiceCollectionExtensions.cs @@ -7,8 +7,15 @@ // ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection; +/// +/// Provides extension methods for registering Git services in the dependency injection container. +/// public static class GitServiceCollectionExtensions { + /// + /// Registers the core Git services in the service collection. + /// + /// The service collection to add the services to. public static void AddGit(this IServiceCollection services) { services.TryAddTransient(); @@ -20,6 +27,12 @@ public static void AddGit(this IServiceCollection services) services.TryAddSingleton(); } + /// + /// Registers the core Git services and configures a transient using the specified options. + /// + /// The service collection to add the services to. + /// An action to configure the . + /// The service collection for further chaining. [PublicAPI] public static IServiceCollection AddGit(this IServiceCollection services, Action setupOptions) diff --git a/source/Git/CreativeCoders.Git/Diffs/GitDiffer.cs b/source/Git/CreativeCoders.Git/Diffs/GitDiffer.cs index 4198bda..37312c9 100644 --- a/source/Git/CreativeCoders.Git/Diffs/GitDiffer.cs +++ b/source/Git/CreativeCoders.Git/Diffs/GitDiffer.cs @@ -2,30 +2,41 @@ namespace CreativeCoders.Git.Diffs; +/// +/// Provides methods for comparing the working directory, index, and tree to produce diff results. +/// public class GitDiffer : IGitDiffer { private readonly Diff _diff; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp diff engine. public GitDiffer(Diff diff) { _diff = Ensure.NotNull(diff); } + /// public IGitTreeChanges Compare() { return new GitTreeChanges(_diff.Compare()); } + /// public IGitTreeChanges Compare(bool includeUntracked) { return new GitTreeChanges(_diff.Compare(null, includeUntracked)); } + /// public IGitTreeChanges Compare(IEnumerable paths) { return new GitTreeChanges(_diff.Compare(paths)); } + /// public IGitTreeChanges Compare(IEnumerable paths, bool includeUntracked) { return new GitTreeChanges(_diff.Compare(paths, includeUntracked)); diff --git a/source/Git/CreativeCoders.Git/Diffs/GitTreeChanges.cs b/source/Git/CreativeCoders.Git/Diffs/GitTreeChanges.cs index 02ae324..8362a1d 100644 --- a/source/Git/CreativeCoders.Git/Diffs/GitTreeChanges.cs +++ b/source/Git/CreativeCoders.Git/Diffs/GitTreeChanges.cs @@ -2,10 +2,17 @@ namespace CreativeCoders.Git.Diffs; +/// +/// Represents a set of tree changes resulting from a diff comparison, categorized by change type. +/// public sealed class GitTreeChanges : IGitTreeChanges { private readonly TreeChanges _treeChanges; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp tree changes. internal GitTreeChanges(TreeChanges treeChanges) { _treeChanges = Ensure.NotNull(treeChanges); @@ -19,6 +26,7 @@ IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); } + /// public void Dispose() { _treeChanges.Dispose(); @@ -28,29 +36,38 @@ private static IEnumerable ToGitTreeEntryChanges( IEnumerable treeEntryChanges) => treeEntryChanges.Select(x => new GitTreeEntryChanges(x)); + /// public IEnumerable Added => ToGitTreeEntryChanges(_treeChanges.Added); + /// public IEnumerable Deleted => ToGitTreeEntryChanges(_treeChanges.Deleted); + /// public IEnumerable Modified => ToGitTreeEntryChanges(_treeChanges.Modified); + /// public IEnumerable TypeChanged => ToGitTreeEntryChanges(_treeChanges.TypeChanged); + /// public IEnumerable Renamed => ToGitTreeEntryChanges(_treeChanges.Renamed); + /// public IEnumerable Copied => ToGitTreeEntryChanges(_treeChanges.Copied); + /// public IEnumerable Unmodified => ToGitTreeEntryChanges(_treeChanges.Unmodified); + /// public IEnumerable Conflicted => ToGitTreeEntryChanges(_treeChanges.Conflicted); + /// public int Count => _treeChanges.Count; } diff --git a/source/Git/CreativeCoders.Git/Diffs/GitTreeEntryChanges.cs b/source/Git/CreativeCoders.Git/Diffs/GitTreeEntryChanges.cs index cf2e754..ae88cc3 100644 --- a/source/Git/CreativeCoders.Git/Diffs/GitTreeEntryChanges.cs +++ b/source/Git/CreativeCoders.Git/Diffs/GitTreeEntryChanges.cs @@ -5,10 +5,17 @@ namespace CreativeCoders.Git.Diffs; +/// +/// Represents the changes to a single entry in a Git tree diff comparison. +/// public class GitTreeEntryChanges : IGitTreeEntryChanges { private readonly TreeEntryChanges _treeEntryChanges; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp tree entry changes. internal GitTreeEntryChanges(TreeEntryChanges treeEntryChanges) { _treeEntryChanges = Ensure.NotNull(treeEntryChanges); @@ -20,21 +27,30 @@ internal GitTreeEntryChanges(TreeEntryChanges treeEntryChanges) OldOid = new GitObjectId(treeEntryChanges.OldOid); } + /// public string Path => _treeEntryChanges.Path; + /// public GitEntryMode Mode { get; } + /// public IGitObjectId Oid { get; } + /// public bool Exists => _treeEntryChanges.Exists; + /// public GitEntryChangeKind Status { get; } + /// public string OldPath => _treeEntryChanges.OldPath; + /// public GitEntryMode OldMode { get; } + /// public IGitObjectId OldOid { get; } + /// public bool OldExists => _treeEntryChanges.OldExists; } diff --git a/source/Git/CreativeCoders.Git/GitCommands/CommandConverters.cs b/source/Git/CreativeCoders.Git/GitCommands/CommandConverters.cs index be3bfc5..ca98046 100644 --- a/source/Git/CreativeCoders.Git/GitCommands/CommandConverters.cs +++ b/source/Git/CreativeCoders.Git/GitCommands/CommandConverters.cs @@ -3,8 +3,17 @@ namespace CreativeCoders.Git.GitCommands; +/// +/// Provides extension methods for converting LibGit2Sharp command types to their Git abstraction equivalents. +/// public static class CommandConverters { + /// + /// Converts a LibGit2Sharp to a . + /// + /// The LibGit2Sharp pack builder stage. + /// The corresponding value. + /// The value is not a recognized pack builder stage. public static GitPackBuilderStage ToGitPackBuilderStage(this PackBuilderStage stage) { return stage switch diff --git a/source/Git/CreativeCoders.Git/GitCommands/FetchTagsCommand.cs b/source/Git/CreativeCoders.Git/GitCommands/FetchTagsCommand.cs index c041bdf..7ce6e94 100644 --- a/source/Git/CreativeCoders.Git/GitCommands/FetchTagsCommand.cs +++ b/source/Git/CreativeCoders.Git/GitCommands/FetchTagsCommand.cs @@ -2,10 +2,15 @@ namespace CreativeCoders.Git.GitCommands; +/// +/// Implements the fetch tags command that fetches all tags from a remote repository. +/// +/// The repository context. internal class FetchTagsCommand(RepositoryContext repositoryContext) : IFetchTagsCommand { private readonly RepositoryContext _repositoryContext = Ensure.NotNull(repositoryContext); + /// public void Execute(FetchTagsCommandOptions commandOptions) { var fetchOptions = new FetchOptions diff --git a/source/Git/CreativeCoders.Git/GitCommands/GitCommands.cs b/source/Git/CreativeCoders.Git/GitCommands/GitCommands.cs index 825fe78..d5d1cf0 100644 --- a/source/Git/CreativeCoders.Git/GitCommands/GitCommands.cs +++ b/source/Git/CreativeCoders.Git/GitCommands/GitCommands.cs @@ -2,25 +2,35 @@ namespace CreativeCoders.Git.GitCommands; +/// +/// Provides a factory for creating Git command instances such as pull, push, and fetch tags. +/// public class GitCommands : IGitCommands { private readonly RepositoryContext _repositoryContext; + /// + /// Initializes a new instance of the class. + /// + /// The repository context. internal GitCommands(RepositoryContext repositoryContext) { _repositoryContext = repositoryContext; } + /// public IPullCommand CreatePullCommand() { return new PullCommand(_repositoryContext); } + /// public IPushCommand CreatePushCommand() { return new PushCommand(_repositoryContext); } + /// public IFetchTagsCommand CreateFetchTagsCommand() { return new FetchTagsCommand(_repositoryContext); diff --git a/source/Git/CreativeCoders.Git/GitCommands/PullCommand.cs b/source/Git/CreativeCoders.Git/GitCommands/PullCommand.cs index 488e61d..60cbc19 100644 --- a/source/Git/CreativeCoders.Git/GitCommands/PullCommand.cs +++ b/source/Git/CreativeCoders.Git/GitCommands/PullCommand.cs @@ -8,6 +8,9 @@ namespace CreativeCoders.Git.GitCommands; +/// +/// Implements the pull command that fetches from a remote and merges into the current branch. +/// internal class PullCommand : IPullCommand { private readonly RepositoryContext _repositoryContext; @@ -20,6 +23,10 @@ internal class PullCommand : IPullCommand private Action? _transferProgress; + /// + /// Initializes a new instance of the class. + /// + /// The repository context. public PullCommand(RepositoryContext repositoryContext) { _repositoryContext = Ensure.NotNull(repositoryContext); @@ -48,11 +55,13 @@ private bool OnGitCheckoutNotify(string path, CheckoutNotifyFlags notifyFlags) return _checkoutNotify == null || _checkoutNotify(path, notifyFlags.ToGitCheckoutNotifyFlags()); } + /// public IPullCommand OnCheckoutNotify(GitSimpleCheckoutNotifyHandler notify) { return OnCheckoutNotify(notify, GitCheckoutNotifyFlags.All); } + /// public IPullCommand OnCheckoutNotify(GitSimpleCheckoutNotifyHandler notify, GitCheckoutNotifyFlags notifyFlags) { return OnCheckoutNotify((path, checkoutNotifyFlag) => @@ -64,11 +73,13 @@ public IPullCommand OnCheckoutNotify(GitSimpleCheckoutNotifyHandler notify, GitC notifyFlags); } + /// public IPullCommand OnCheckoutNotify(GitCheckoutNotifyHandler notify) { return OnCheckoutNotify(notify, GitCheckoutNotifyFlags.All); } + /// public IPullCommand OnCheckoutNotify(GitCheckoutNotifyHandler notify, GitCheckoutNotifyFlags notifyFlags) { Ensure.NotNull(notify); @@ -80,6 +91,7 @@ public IPullCommand OnCheckoutNotify(GitCheckoutNotifyHandler notify, GitCheckou return this; } + /// public IPullCommand OnCheckoutProgress(GitCheckoutProgressHandler progress) { _checkoutProgress = Ensure.NotNull(progress); @@ -87,6 +99,7 @@ public IPullCommand OnCheckoutProgress(GitCheckoutProgressHandler progress) return this; } + /// public IPullCommand OnTransferProgress(Action progress) { _transferProgress = Ensure.NotNull(progress); @@ -94,6 +107,7 @@ public IPullCommand OnTransferProgress(Action progress return this; } + /// public GitMergeResult Run() { var options = new PullOptions diff --git a/source/Git/CreativeCoders.Git/GitCommands/PushCommand.cs b/source/Git/CreativeCoders.Git/GitCommands/PushCommand.cs index 1e8d909..0ff856d 100644 --- a/source/Git/CreativeCoders.Git/GitCommands/PushCommand.cs +++ b/source/Git/CreativeCoders.Git/GitCommands/PushCommand.cs @@ -9,6 +9,9 @@ namespace CreativeCoders.Git.GitCommands; +/// +/// Implements the push command that pushes local commits to a remote repository. +/// internal class PushCommand : IPushCommand { private readonly RepositoryContext _repositoryContext; @@ -31,6 +34,10 @@ internal class PushCommand : IPushCommand private Action>? _unPushedCommits; + /// + /// Initializes a new instance of the class. + /// + /// The repository context. public PushCommand(RepositoryContext repositoryContext) { _repositoryContext = Ensure.NotNull(repositoryContext); @@ -120,9 +127,11 @@ private void PushInternal() _repositoryContext.LibGitRepository.Network.Push(pushBranch, pushOptions); } + /// public IPushCommand CreateRemoteBranchIfNotExists() => CreateRemoteBranchIfNotExists(true); + /// public IPushCommand CreateRemoteBranchIfNotExists(bool createRemoteBranchIfNotExists) { _createRemoteBranchIfNotExists = createRemoteBranchIfNotExists; @@ -130,6 +139,7 @@ public IPushCommand CreateRemoteBranchIfNotExists(bool createRemoteBranchIfNotEx return this; } + /// public IPushCommand Branch(IGitBranch branch) { _branch = branch; @@ -137,11 +147,13 @@ public IPushCommand Branch(IGitBranch branch) return this; } + /// public IPushCommand Confirm() { return Confirm(true); } + /// public IPushCommand Confirm(bool confirm) { _confirm = confirm; @@ -149,6 +161,7 @@ public IPushCommand Confirm(bool confirm) return this; } + /// public IPushCommand OnPushStatusError(Action pushStatusError) { _pushStatusError = pushStatusError; @@ -156,6 +169,7 @@ public IPushCommand OnPushStatusError(Action pushStatusError return this; } + /// public IPushCommand OnPackBuilderProgress(Action packBuilderProgress) { return OnPackBuilderProgress(x => @@ -166,6 +180,7 @@ public IPushCommand OnPackBuilderProgress(Action packBui }); } + /// public IPushCommand OnPackBuilderProgress(Func packBuilderProgress) { _packBuilderProgress = packBuilderProgress; @@ -173,6 +188,7 @@ public IPushCommand OnPackBuilderProgress(Func pac return this; } + /// public IPushCommand OnTransferProgress(Action transferProgress) { return OnTransferProgress(x => @@ -183,6 +199,7 @@ public IPushCommand OnTransferProgress(Action transferP }); } + /// public IPushCommand OnTransferProgress(Func transferProgress) { _transferProgress = transferProgress; @@ -190,6 +207,7 @@ public IPushCommand OnTransferProgress(Func trans return this; } + /// public IPushCommand OnNegotiationCompletedBeforePush( Action> negotiationCompletedBeforePush) { @@ -201,6 +219,7 @@ public IPushCommand OnNegotiationCompletedBeforePush( }); } + /// public IPushCommand OnNegotiationCompletedBeforePush( Func, bool> negotiationCompletedBeforePush) { @@ -209,6 +228,7 @@ public IPushCommand OnNegotiationCompletedBeforePush( return this; } + /// public IPushCommand OnUnPushedCommits(Action> unPushedCommits) { _unPushedCommits = unPushedCommits; @@ -216,6 +236,7 @@ public IPushCommand OnUnPushedCommits(Action> unPushedCo return this; } + /// public IPushCommand OnConfirm(Func doConfirm) { _doConfirm = doConfirm; @@ -223,6 +244,7 @@ public IPushCommand OnConfirm(Func doConfirm) return this; } + /// public void Run() { _repositoryContext.LibGitCaller.Invoke(PushInternal); diff --git a/source/Git/CreativeCoders.Git/GitRepositoryInfo.cs b/source/Git/CreativeCoders.Git/GitRepositoryInfo.cs index c458ea2..7fb580b 100644 --- a/source/Git/CreativeCoders.Git/GitRepositoryInfo.cs +++ b/source/Git/CreativeCoders.Git/GitRepositoryInfo.cs @@ -2,6 +2,10 @@ namespace CreativeCoders.Git; +/// +/// Provides metadata information about a Git repository such as path, main branch, and remote URI. +/// +/// The underlying LibGit2Sharp repository. internal class GitRepositoryInfo(IRepository repository) : IGitRepositoryInfo { private static GitMainBranch GetMainBranch(IRepository repository) @@ -20,9 +24,12 @@ private static GitMainBranch GetMainBranch(IRepository repository) : GitMainBranch.Custom; } + /// public string? Path { get; } = Ensure.NotNull(repository).Info.Path; + /// public GitMainBranch MainBranch { get; } = GetMainBranch(repository); + /// public Uri RemoteUri { get; } = new Uri(Ensure.NotNull(repository).Network.Remotes[GitRemotes.Origin].Url); } diff --git a/source/Git/CreativeCoders.Git/GitRepositoryUtils.cs b/source/Git/CreativeCoders.Git/GitRepositoryUtils.cs index bc5a8cd..003a15c 100644 --- a/source/Git/CreativeCoders.Git/GitRepositoryUtils.cs +++ b/source/Git/CreativeCoders.Git/GitRepositoryUtils.cs @@ -1,12 +1,19 @@ namespace CreativeCoders.Git; +/// +/// Provides the default implementation of for Git path operations. +/// internal class GitRepositoryUtils : IGitRepositoryUtils { + /// public bool IsValidGitPath(string path) => Repository.IsValid(path); + /// public string? DiscoverGitPath(string path) => Repository.Discover(path); + /// public string? InitRepository(string path) => Repository.Init(path); + /// public string? InitRepository(string path, bool isBare) => Repository.Init(path, isBare); } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git/ILibGitCaller.cs b/source/Git/CreativeCoders.Git/ILibGitCaller.cs index 97123a0..b31d40b 100644 --- a/source/Git/CreativeCoders.Git/ILibGitCaller.cs +++ b/source/Git/CreativeCoders.Git/ILibGitCaller.cs @@ -1,8 +1,21 @@ namespace CreativeCoders.Git; +/// +/// Provides a wrapper for invoking LibGit2Sharp operations with unified exception handling. +/// public interface ILibGitCaller { + /// + /// Invokes the specified action, translating LibGit2Sharp exceptions into . + /// + /// The action to invoke. void Invoke(Action action); + /// + /// Invokes the specified function, translating LibGit2Sharp exceptions into . + /// + /// The return type of the function. + /// The function to invoke. + /// The result of the function invocation. T Invoke(Func func); } diff --git a/source/Git/CreativeCoders.Git/LibGitCaller.cs b/source/Git/CreativeCoders.Git/LibGitCaller.cs index a850c5c..eb06285 100644 --- a/source/Git/CreativeCoders.Git/LibGitCaller.cs +++ b/source/Git/CreativeCoders.Git/LibGitCaller.cs @@ -2,8 +2,12 @@ namespace CreativeCoders.Git; +/// +/// Wraps LibGit2Sharp calls and translates into . +/// internal class LibGitCaller : ILibGitCaller { + /// public void Invoke(Action action) { try @@ -16,6 +20,7 @@ public void Invoke(Action action) } } + /// public T Invoke(Func func) { try diff --git a/source/Git/CreativeCoders.Git/Merges/GitCheckoutNotifyFlagsExtensions.cs b/source/Git/CreativeCoders.Git/Merges/GitCheckoutNotifyFlagsExtensions.cs index 030fa72..293fae1 100644 --- a/source/Git/CreativeCoders.Git/Merges/GitCheckoutNotifyFlagsExtensions.cs +++ b/source/Git/CreativeCoders.Git/Merges/GitCheckoutNotifyFlagsExtensions.cs @@ -2,8 +2,16 @@ namespace CreativeCoders.Git.Merges; +/// +/// Provides extension methods for converting between and LibGit2Sharp . +/// public static class GitCheckoutNotifyFlagsExtensions { + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git checkout notify flags. + /// The corresponding value. public static CheckoutNotifyFlags ToCheckoutNotifyFlags(this GitCheckoutNotifyFlags checkoutNotifyFlags) { return new CheckoutNotifyFlags() @@ -14,6 +22,11 @@ public static CheckoutNotifyFlags ToCheckoutNotifyFlags(this GitCheckoutNotifyFl .AddFlagIfSet(CheckoutNotifyFlags.Untracked, checkoutNotifyFlags, GitCheckoutNotifyFlags.Untracked); } + /// + /// Converts a LibGit2Sharp to a . + /// + /// The LibGit2Sharp checkout notify flags. + /// The corresponding value. public static GitCheckoutNotifyFlags ToGitCheckoutNotifyFlags(this CheckoutNotifyFlags checkoutNotifyFlags) { return new GitCheckoutNotifyFlags() diff --git a/source/Git/CreativeCoders.Git/Merges/GitMergeOptions.cs b/source/Git/CreativeCoders.Git/Merges/GitMergeOptions.cs index 0d103cd..b4fb282 100644 --- a/source/Git/CreativeCoders.Git/Merges/GitMergeOptions.cs +++ b/source/Git/CreativeCoders.Git/Merges/GitMergeOptions.cs @@ -1,10 +1,16 @@ namespace CreativeCoders.Git.Merges; +/// +/// Represents configuration options for a Git merge operation. +/// public class GitMergeOptions { + /// + /// Initializes a new instance of the class. + /// public GitMergeOptions() { - + } internal MergeOptions ToMergeOptions() diff --git a/source/Git/CreativeCoders.Git/Objects/GitObject.cs b/source/Git/CreativeCoders.Git/Objects/GitObject.cs index b60b9a1..fffcd2c 100644 --- a/source/Git/CreativeCoders.Git/Objects/GitObject.cs +++ b/source/Git/CreativeCoders.Git/Objects/GitObject.cs @@ -2,8 +2,15 @@ namespace CreativeCoders.Git.Objects; +/// +/// Represents a Git object identified by its SHA hash. +/// public class GitObject : ComparableObject, IGitObject { + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp Git object. internal GitObject(LibGit2Sharp.GitObject gitObject) { Id = new GitObjectId(gitObject.Id); @@ -12,7 +19,9 @@ internal GitObject(LibGit2Sharp.GitObject gitObject) static GitObject() => InitComparableObject(x => x.Id); + /// public IGitObjectId Id { get; } + /// public string Sha { get; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git/Objects/GitObjectId.cs b/source/Git/CreativeCoders.Git/Objects/GitObjectId.cs index a2252ed..41ecfd1 100644 --- a/source/Git/CreativeCoders.Git/Objects/GitObjectId.cs +++ b/source/Git/CreativeCoders.Git/Objects/GitObjectId.cs @@ -2,15 +2,26 @@ namespace CreativeCoders.Git.Objects; +/// +/// Represents a unique identifier for a Git object based on its SHA hash. +/// public class GitObjectId : ComparableObject, IGitObjectId { private readonly ObjectId _objectId; + /// + /// Initializes a new instance of the class from a LibGit2Sharp . + /// + /// The underlying LibGit2Sharp object identifier. internal GitObjectId(ObjectId objectId) { _objectId = Ensure.NotNull(objectId); } + /// + /// Initializes a new instance of the class from a SHA hash string. + /// + /// The SHA hash string. public GitObjectId(string sha) : this(new ObjectId(sha)) { } @@ -20,9 +31,15 @@ static GitObjectId() InitComparableObject(x => x.Sha); } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git object identifier to convert. public static implicit operator ObjectId(GitObjectId objectId) => objectId._objectId; + /// public string Sha => _objectId.Sha; + /// public string ToString(int prefixLength) => _objectId.ToString(prefixLength); } diff --git a/source/Git/CreativeCoders.Git/RefSpecs/GitRefSpec.cs b/source/Git/CreativeCoders.Git/RefSpecs/GitRefSpec.cs index 348ef5f..bc2b933 100644 --- a/source/Git/CreativeCoders.Git/RefSpecs/GitRefSpec.cs +++ b/source/Git/CreativeCoders.Git/RefSpecs/GitRefSpec.cs @@ -3,10 +3,17 @@ namespace CreativeCoders.Git.RefSpecs; +/// +/// Represents a Git reference specification that defines the mapping between remote and local references. +/// public class GitRefSpec : ComparableObject, IGitRefSpec { private readonly RefSpec _refSpec; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp ref spec. internal GitRefSpec(RefSpec refSpec) { _refSpec = Ensure.NotNull(refSpec); @@ -14,15 +21,24 @@ internal GitRefSpec(RefSpec refSpec) static GitRefSpec() => InitComparableObject(x => x.Specification); + /// public string Specification => _refSpec.Specification; + /// public GitRefSpecDirection Direction => _refSpec.Direction.ToGitRefSpecDirection(); + /// public string Source => _refSpec.Source; + /// public string Destination => _refSpec.Destination; + /// public override string ToString() => Specification; + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git ref spec to convert. public static implicit operator RefSpec(GitRefSpec refSpec) => refSpec._refSpec; } diff --git a/source/Git/CreativeCoders.Git/RefSpecs/GitRefSpecCollection.cs b/source/Git/CreativeCoders.Git/RefSpecs/GitRefSpecCollection.cs index bf20a57..f85a249 100644 --- a/source/Git/CreativeCoders.Git/RefSpecs/GitRefSpecCollection.cs +++ b/source/Git/CreativeCoders.Git/RefSpecs/GitRefSpecCollection.cs @@ -2,10 +2,17 @@ namespace CreativeCoders.Git.RefSpecs; +/// +/// Represents a collection of Git ref specs wrapping a LibGit2Sharp . +/// public class GitRefSpecCollection : IGitRefSpecCollection { private readonly RefSpecCollection _refSpecCollection; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp ref spec collection. public GitRefSpecCollection(RefSpecCollection refSpecCollection) { _refSpecCollection = refSpecCollection; diff --git a/source/Git/CreativeCoders.Git/References/GitReference.cs b/source/Git/CreativeCoders.Git/References/GitReference.cs index 5ec2d22..14b0c80 100644 --- a/source/Git/CreativeCoders.Git/References/GitReference.cs +++ b/source/Git/CreativeCoders.Git/References/GitReference.cs @@ -5,10 +5,17 @@ namespace CreativeCoders.Git.References; +/// +/// Represents a Git reference (e.g., branch, tag, or HEAD) pointing to a Git object. +/// public class GitReference : ComparableObject, IGitReference { private readonly Reference _reference; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp reference. internal GitReference(Reference reference) { _reference = Ensure.NotNull(reference); @@ -30,11 +37,18 @@ internal GitReference(Reference reference) : new GitReference(reference); } + /// public ReferenceName Name { get; } + /// public string TargetIdentifier => _reference.TargetIdentifier; + /// public IGitObjectId? ReferenceTargetId { get; } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git reference to convert. public static implicit operator Reference(GitReference reference) => reference._reference; } diff --git a/source/Git/CreativeCoders.Git/References/GitReferenceCollection.cs b/source/Git/CreativeCoders.Git/References/GitReferenceCollection.cs index 8b72f87..436e777 100644 --- a/source/Git/CreativeCoders.Git/References/GitReferenceCollection.cs +++ b/source/Git/CreativeCoders.Git/References/GitReferenceCollection.cs @@ -6,10 +6,17 @@ namespace CreativeCoders.Git.References; +/// +/// Represents a collection of Git references with operations for adding, updating, and querying. +/// public class GitReferenceCollection : IGitReferenceCollection { private readonly ReferenceCollection _referenceCollection; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp reference collection. internal GitReferenceCollection(ReferenceCollection referenceCollection) { _referenceCollection = Ensure.NotNull(referenceCollection); @@ -23,20 +30,25 @@ IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); } + /// public IGitReference? Head => this["HEAD"]; + /// public IGitReference? this[string name] => GitReference.From(_referenceCollection[name]); + /// public void Add(string name, string canonicalRefNameOrObjectish, bool allowOverwrite = false) => _referenceCollection.Add(name, canonicalRefNameOrObjectish, allowOverwrite); + /// public void UpdateTarget(IGitReference directRef, IGitObjectId targetId) => new ActionExceptionWrapper(() => _referenceCollection.UpdateTarget((GitReference)directRef, (GitObjectId)targetId)) .Wrap(x => new GitLockedFileException(x)) .Execute(); + /// public IEnumerable FromGlob(string prefix) => _referenceCollection.FromGlob(prefix).Select(x => new GitReference(x)); } diff --git a/source/Git/CreativeCoders.Git/Remotes/GitRemote.cs b/source/Git/CreativeCoders.Git/Remotes/GitRemote.cs index 900ca39..46ca6d2 100644 --- a/source/Git/CreativeCoders.Git/Remotes/GitRemote.cs +++ b/source/Git/CreativeCoders.Git/Remotes/GitRemote.cs @@ -4,12 +4,19 @@ namespace CreativeCoders.Git.Remotes; +/// +/// Represents a Git remote repository reference. +/// public class GitRemote : ComparableObject, IGitRemote { private readonly Remote _remote; static GitRemote() => InitComparableObject(x => x.Name); + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp remote. internal GitRemote(Remote remote) { _remote = Ensure.NotNull(remote); @@ -22,14 +29,22 @@ internal GitRemote(Remote remote) : new GitRemote(remote); } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git remote to convert. public static implicit operator Remote(GitRemote remote) => remote._remote; + /// public string Name => _remote.Name; + /// public string Url => _remote.Url; + /// public string PushUrl => _remote.PushUrl; + /// public IEnumerable RefSpecs { get @@ -42,7 +57,9 @@ public IEnumerable RefSpecs } } + /// public IEnumerable FetchRefSpecs => _remote.FetchRefSpecs.Select(x => new GitRefSpec(x)); + /// public IEnumerable PushRefSpecs => _remote.PushRefSpecs.Select(x => new GitRefSpec(x)); } diff --git a/source/Git/CreativeCoders.Git/Remotes/GitRemoteCollection.cs b/source/Git/CreativeCoders.Git/Remotes/GitRemoteCollection.cs index 9005141..1f1a945 100644 --- a/source/Git/CreativeCoders.Git/Remotes/GitRemoteCollection.cs +++ b/source/Git/CreativeCoders.Git/Remotes/GitRemoteCollection.cs @@ -2,10 +2,17 @@ namespace CreativeCoders.Git.Remotes; +/// +/// Represents a collection of Git remotes wrapping a LibGit2Sharp . +/// public class GitRemoteCollection : IGitRemoteCollection { private readonly RemoteCollection _remoteCollection; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp remote collection. public GitRemoteCollection(RemoteCollection remoteCollection) { _remoteCollection = Ensure.NotNull(remoteCollection); @@ -19,5 +26,6 @@ IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); } + /// public IGitRemote? this[string name] => GitRemote.From(_remoteCollection[name]); } diff --git a/source/Git/CreativeCoders.Git/RepositoryContext.cs b/source/Git/CreativeCoders.Git/RepositoryContext.cs index 126dce4..cdce3cc 100644 --- a/source/Git/CreativeCoders.Git/RepositoryContext.cs +++ b/source/Git/CreativeCoders.Git/RepositoryContext.cs @@ -2,6 +2,16 @@ namespace CreativeCoders.Git; +/// +/// Holds the shared context for repository operations, providing access to the underlying LibGit2Sharp repository, +/// credentials, signatures, and certificate handlers. +/// +/// The parent instance. +/// The underlying LibGit2Sharp repository. +/// The caller used to invoke LibGit2Sharp operations with exception handling. +/// A factory function that returns the current commit signature. +/// A factory function that returns the credentials handler. +/// A factory function that returns the certificate check handler. internal class RepositoryContext( DefaultGitRepository repository, Repository libGitRepository, @@ -16,24 +26,45 @@ internal class RepositoryContext( private readonly Func _getSignature = Ensure.NotNull(getSignature); + /// + /// Gets the current commit signature. + /// + /// The signature for the current user. public Signature GetSignature() { return _getSignature(); } + /// + /// Gets the credentials handler for authentication. + /// + /// The credentials handler. public CredentialsHandler GetCredentialsHandler() { return _getCredentialsHandler(); } + /// + /// Gets the certificate check handler for SSL/SSH verification. + /// + /// The certificate check handler, or if no custom handler is configured. public CertificateCheckHandler? GetCertificateCheckHandler() { return _certificateCheckHandler(); } + /// + /// Gets the underlying LibGit2Sharp repository. + /// public Repository LibGitRepository { get; } = Ensure.NotNull(libGitRepository); + /// + /// Gets the caller used to invoke LibGit2Sharp operations with exception handling. + /// public ILibGitCaller LibGitCaller { get; } = Ensure.NotNull(libGitCaller); + /// + /// Gets the parent instance. + /// public DefaultGitRepository Repository { get; } = Ensure.NotNull(repository); } diff --git a/source/Git/CreativeCoders.Git/Tags/GitTag.cs b/source/Git/CreativeCoders.Git/Tags/GitTag.cs index 31dd5d6..5ee429b 100644 --- a/source/Git/CreativeCoders.Git/Tags/GitTag.cs +++ b/source/Git/CreativeCoders.Git/Tags/GitTag.cs @@ -5,10 +5,17 @@ namespace CreativeCoders.Git.Tags; +/// +/// Represents a Git tag pointing to a specific Git object. +/// public class GitTag : ComparableObject, IGitTag { private readonly Tag _tag; + /// + /// Initializes a new instance of the class. + /// + /// The underlying LibGit2Sharp tag. internal GitTag(Tag tag) { _tag = Ensure.NotNull(tag); @@ -23,10 +30,13 @@ internal GitTag(Tag tag) static GitTag() => InitComparableObject(x => x.Name.Canonical); + /// public ReferenceName Name { get; } + /// public string TargetSha => _tag.Target.Sha; + /// public IGitCommit? PeeledTargetCommit() { var target = _tag.Target; @@ -39,7 +49,12 @@ internal GitTag(Tag tag) return GitCommit.From(target as Commit); } + /// public IGitCommit? TargetCommit { get; } + /// + /// Converts a to a LibGit2Sharp . + /// + /// The Git tag to convert. public static implicit operator Tag(GitTag tag) => tag._tag; } diff --git a/source/Git/CreativeCoders.Git/Tags/GitTagCollection.cs b/source/Git/CreativeCoders.Git/Tags/GitTagCollection.cs index 5d49ee0..606cfe6 100644 --- a/source/Git/CreativeCoders.Git/Tags/GitTagCollection.cs +++ b/source/Git/CreativeCoders.Git/Tags/GitTagCollection.cs @@ -4,6 +4,9 @@ namespace CreativeCoders.Git.Tags; +/// +/// Represents a collection of Git tags with operations for creating, deleting, and pushing tags. +/// public class GitTagCollection : IGitTagCollection { private readonly RepositoryContext _context; @@ -19,6 +22,7 @@ internal GitTagCollection(RepositoryContext context) _libGitCaller = _context.LibGitCaller; } + /// public IGitTag CreateTag(string tagName, string? objectish = null) { return string.IsNullOrWhiteSpace(objectish) @@ -26,6 +30,7 @@ public IGitTag CreateTag(string tagName, string? objectish = null) : new GitTag(_libGitCaller.Invoke(() => _repository.ApplyTag(tagName, objectish))); } + /// public IGitTag CreateTagWithMessage(string tagName, string message, string? objectish = null) { return string.IsNullOrWhiteSpace(objectish) @@ -34,6 +39,7 @@ public IGitTag CreateTagWithMessage(string tagName, string message, string? obje .Invoke(() => _repository.ApplyTag(tagName, objectish, _context.GetSignature(), message))); } + /// public void DeleteTag(string tagName, bool deleteOnRemote = false) { _libGitCaller.Invoke(() => _repository.Tags.Remove(tagName)); @@ -44,11 +50,13 @@ public void DeleteTag(string tagName, bool deleteOnRemote = false) } } + /// public void DeleteTag(IGitTag tag, bool deleteOnRemote = false) { DeleteTag(tag.Name.Canonical, deleteOnRemote); } + /// public void DeleteRemoteTag(string tagName) { var pushOptions = new PushOptions @@ -61,6 +69,7 @@ public void DeleteRemoteTag(string tagName) pushOptions)); } + /// public void PushTag(string tagName) { var pushOptions = new PushOptions @@ -72,11 +81,13 @@ public void PushTag(string tagName) _repository.Network.Push(_repository.Network.Remotes[GitRemotes.Origin], tagName, pushOptions)); } + /// public void PushTag(IGitTag tag) { PushTag(tag.Name.Canonical); } + /// public void PushAllTags() { this.ForEach(PushTag); From 1f268fa30578f9fb90d4bde86703c628a2aef67a Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sat, 28 Mar 2026 19:50:43 +0100 Subject: [PATCH 05/13] docs: update README with comprehensive usage guide and project details - Added a detailed overview of GitTools, including features and integrations. - Included installation instructions and CLI usage examples. - Documented configuration options, architecture, and steps to build from source. - Added badges for .NET version, NuGet version, and license information. --- README.md | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9cb5147..3123de7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,161 @@ # GitTools -Tools for working with Git + +> A .NET-based CLI tool and Git abstraction library for streamlined Git workflows with GitHub and GitLab integration. + +[![.NET](https://img.shields.io/badge/.NET-10.0-purple)](https://dotnet.microsoft.com/) +[![NuGet](https://img.shields.io/nuget/v/CreativeCoders.GitTool)](https://www.nuget.org/packages/CreativeCoders.GitTool) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) + +## Overview + +GitTools is a collection of .NET libraries and a CLI tool (`gt`) that simplifies everyday Git workflows. It wraps [LibGit2Sharp](https://github.com/libgit2/libgit2sharp) in a clean abstraction layer and adds high-level commands for managing feature branches, releases, tags, and more — with first-class integration for both GitHub and GitLab. + +## Features + +- **Feature workflow** — start and finish feature branches following a GitFlow-style process +- **Branch management** — list, inspect, pull, push, and update all permanent branches at once +- **Release management** — create versioned releases via Git tags with optional auto-increment +- **Tag management** — create, delete, fetch, and list tags locally and remotely +- **GitHub integration** — automatic pull request creation via [Octokit](https://github.com/octokit/octokit.net) +- **GitLab integration** — automatic merge request creation via [GitLabApiClient](https://github.com/nmklotas/GitLabApiClient) +- **Credential support** — seamless authentication through [Git Credential Manager](https://github.com/git-ecosystem/git-credential-manager) +- **Per-repository configuration** — JSON-based configuration with sensible defaults + +## Installation + +Install the `gt` CLI as a global .NET tool: + +```bash +dotnet tool install --global CreativeCoders.GitTool +``` + +Or update an existing installation: + +```bash +dotnet tool update --global CreativeCoders.GitTool +``` + +> [!NOTE] +> Requires [.NET 10 SDK](https://dotnet.microsoft.com/download) or later. + +## Usage + +Run `gt --help` to see all available commands. + +### Feature branches + +```bash +# Start a new feature branch (branches off develop or main) +gt feature start + +# Finish the feature: merge, push, and open a pull/merge request +gt feature finish [] +``` + +### Branch commands + +```bash +gt branch list # List all local and remote branches +gt branch info # Show details about the current branch +gt branch pull # Pull the current branch from remote +gt branch push # Push the current branch to remote +gt branch update # Pull all permanent local branches (main, develop, …) +``` + +### Release commands + +```bash +gt release create 1.2.0 # Create a release tag v1.2.0 +gt release create --increment minor # Auto-increment the minor version +gt release list-versions # List all version tags +``` + +### Tag commands + +```bash +gt tag create # Create a new tag +gt tag delete # Delete a tag locally (and optionally on remote) +gt tag fetch # Fetch all tags from remote +gt tag list # List all tags +``` + +### Other commands + +```bash +gt showconfig # Show the effective configuration for the current repository +``` + +## Configuration + +The tool reads its configuration from a JSON file located at: + +| Platform | Path | +|----------|------| +| Windows | `%LOCALAPPDATA%\CreativeCoders\GitTool\gt.json` | +| macOS / Linux | `~/.local/share/CreativeCoders/GitTool/gt.json` | + +### Example configuration + +```json +{ + "tool": { + "defaultGitServiceProviderName": "github" + }, + "GitServiceProviders": { + "GitHub": { + "Hosts": ["github.com"] + }, + "GitLab": { + "Hosts": ["gitlab.com"] + } + } +} +``` + +Per-repository configuration files (prefix `repo_`) in the same folder allow repository-specific overrides such as a custom develop branch name, feature branch prefix, or disabling TLS certificate validation for self-hosted instances. + +### Repository configuration defaults + +| Setting | Default | +|---------|---------| +| `featureBranchPrefix` | `feature/` | +| `developBranch` | `develop` | +| `hasDevelopBranch` | `true` | +| `gitServiceProviderName` | `github` | +| `disableCertificateValidation` | `false` | + +## Architecture + +The solution is split into focused projects: + +``` +source/ +├── Git/ +│ ├── CreativeCoders.Git.Abstractions # Interfaces & models for Git operations +│ ├── CreativeCoders.Git # LibGit2Sharp-based implementation +│ └── CreativeCoders.Git.Auth.CredentialManagerCore # GCM credential provider +└── GitTool/ + ├── CreativeCoders.GitTool.Base # Shared base types, configuration, return codes + ├── CreativeCoders.GitTool.Cli.Commands # All CLI command implementations + ├── CreativeCoders.GitTool.Cli.GtApp # Entry point / host setup (the `gt` executable) + ├── CreativeCoders.GitTool.GitHub # GitHub service provider (Octokit) + └── CreativeCoders.GitTool.GitLab # GitLab service provider (GitLabApiClient) +``` + +## Building from source + +```bash +# Restore and build +dotnet build GitTools.sln + +# Run all tests +dotnet test GitTools.sln + +# Pack the tool locally +dotnet pack source/GitTool/CreativeCoders.GitTool.Cli.GtApp/CreativeCoders.GitTool.Cli.GtApp.csproj +``` + +## Requirements + +- .NET 10 SDK +- Git (with [Git Credential Manager](https://github.com/git-ecosystem/git-credential-manager) recommended for authentication) From 13b30f7c952695ede32079520c63bea9131f58df Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sat, 28 Mar 2026 19:57:33 +0100 Subject: [PATCH 06/13] docs: update README with separate configuration paths for macOS and Linux - Updated the configuration file paths in the table to provide distinct locations for macOS and Linux. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3123de7..1b60395 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,8 @@ The tool reads its configuration from a JSON file located at: | Platform | Path | |----------|------| | Windows | `%LOCALAPPDATA%\CreativeCoders\GitTool\gt.json` | -| macOS / Linux | `~/.local/share/CreativeCoders/GitTool/gt.json` | +| macOS | `~/Library/Application Support/CreativeCoders/GitTool/gt.json` | +| Linux | `~/.local/share/CreativeCoders/GitTool/gt.json` | ### Example configuration From 7337e62bff93998b6879c6ada625f1d4f4e0e2eb Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 29 Mar 2026 11:14:49 +0200 Subject: [PATCH 07/13] docs: refine README formatting and update license badge - Improved readability by adjusting indentation and spacing in code blocks. - Updated license badge to reflect Apache 2.0. --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1b60395..9879f49 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # GitTools -> A .NET-based CLI tool and Git abstraction library for streamlined Git workflows with GitHub and GitLab integration. +> A .NET CLI tool and Git abstraction library for streamlined Git workflows with GitHub and GitLab integration. [![.NET](https://img.shields.io/badge/.NET-10.0-purple)](https://dotnet.microsoft.com/) [![NuGet](https://img.shields.io/nuget/v/CreativeCoders.GitTool)](https://www.nuget.org/packages/CreativeCoders.GitTool) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) ## Overview -GitTools is a collection of .NET libraries and a CLI tool (`gt`) that simplifies everyday Git workflows. It wraps [LibGit2Sharp](https://github.com/libgit2/libgit2sharp) in a clean abstraction layer and adds high-level commands for managing feature branches, releases, tags, and more — with first-class integration for both GitHub and GitLab. +GitTools provides the `gt` CLI tool and a set of .NET libraries that simplify everyday Git workflows. It wraps [LibGit2Sharp](https://github.com/libgit2/libgit2sharp) in a clean abstraction layer and adds high-level commands for managing feature branches, releases, tags, and more — with first-class support for both **GitHub** and **GitLab**. ## Features @@ -59,15 +59,15 @@ gt branch list # List all local and remote branches gt branch info # Show details about the current branch gt branch pull # Pull the current branch from remote gt branch push # Push the current branch to remote -gt branch update # Pull all permanent local branches (main, develop, …) +gt branch update # Pull all permanent local branches (main, develop, ...) ``` ### Release commands ```bash -gt release create 1.2.0 # Create a release tag v1.2.0 -gt release create --increment minor # Auto-increment the minor version -gt release list-versions # List all version tags +gt release create 1.2.0 # Create a release tag v1.2.0 +gt release create --increment minor # Auto-increment the minor version +gt release list-versions # List all version tags ``` ### Tag commands From 25a21f39e42efacc0e9c0b072cde21cc478d2e75 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 29 Mar 2026 11:23:27 +0200 Subject: [PATCH 08/13] docs: enhance README with additional badges, feature list, and examples - Added a build status badge to highlight CI workflow status. - Expanded the feature list to include Git abstraction layer and usage examples. - Introduced collapsible sections for configuration examples and repository defaults. - Updated "Getting started" section with step-by-step installation and usage guide. - Included a new section documenting the Git abstraction library with examples. --- README.md | 85 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 9879f49..f38e18d 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,13 @@ > A .NET CLI tool and Git abstraction library for streamlined Git workflows with GitHub and GitLab integration. +[![Build](https://github.com/CreativeCodersTeam/GitTools/actions/workflows/main.yml/badge.svg)](https://github.com/CreativeCodersTeam/GitTools/actions/workflows/main.yml) [![.NET](https://img.shields.io/badge/.NET-10.0-purple)](https://dotnet.microsoft.com/) [![NuGet](https://img.shields.io/nuget/v/CreativeCoders.GitTool)](https://www.nuget.org/packages/CreativeCoders.GitTool) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) +[Features](#features) | [Getting started](#getting-started) | [Usage](#usage) | [Configuration](#configuration) | [Architecture](#architecture) | [Building from source](#building-from-source) + ## Overview GitTools provides the `gt` CLI tool and a set of .NET libraries that simplify everyday Git workflows. It wraps [LibGit2Sharp](https://github.com/libgit2/libgit2sharp) in a clean abstraction layer and adds high-level commands for managing feature branches, releases, tags, and more — with first-class support for both **GitHub** and **GitLab**. @@ -19,24 +22,27 @@ GitTools provides the `gt` CLI tool and a set of .NET libraries that simplify ev - **GitHub integration** — automatic pull request creation via [Octokit](https://github.com/octokit/octokit.net) - **GitLab integration** — automatic merge request creation via [GitLabApiClient](https://github.com/nmklotas/GitLabApiClient) - **Credential support** — seamless authentication through [Git Credential Manager](https://github.com/git-ecosystem/git-credential-manager) +- **Git abstraction layer** — clean interfaces (`IGitRepository`, `IGitRepositoryFactory`, ...) for testable Git operations - **Per-repository configuration** — JSON-based configuration with sensible defaults -## Installation - -Install the `gt` CLI as a global .NET tool: - -```bash -dotnet tool install --global CreativeCoders.GitTool -``` - -Or update an existing installation: - -```bash -dotnet tool update --global CreativeCoders.GitTool -``` - -> [!NOTE] -> Requires [.NET 10 SDK](https://dotnet.microsoft.com/download) or later. +## Getting started + +1. Install the tool: + ```bash + dotnet tool install --global CreativeCoders.GitTool + ``` +2. Navigate to any Git repository: + ```bash + cd your-repo + ``` +3. Start your first feature: + ```bash + gt feature start my-feature + ``` + +> [!IMPORTANT] +> Requires [.NET 10 SDK](https://dotnet.microsoft.com/download) or later and Git installed on your machine. +> [Git Credential Manager](https://github.com/git-ecosystem/git-credential-manager) is recommended for authentication. ## Usage @@ -95,7 +101,8 @@ The tool reads its configuration from a JSON file located at: | macOS | `~/Library/Application Support/CreativeCoders/GitTool/gt.json` | | Linux | `~/.local/share/CreativeCoders/GitTool/gt.json` | -### Example configuration +
+Example configuration ```json { @@ -115,7 +122,10 @@ The tool reads its configuration from a JSON file located at: Per-repository configuration files (prefix `repo_`) in the same folder allow repository-specific overrides such as a custom develop branch name, feature branch prefix, or disabling TLS certificate validation for self-hosted instances. -### Repository configuration defaults +
+ +
+Repository configuration defaults | Setting | Default | |---------|---------| @@ -125,9 +135,38 @@ Per-repository configuration files (prefix `repo_`) in the same folder allow rep | `gitServiceProviderName` | `github` | | `disableCertificateValidation` | `false` | +
+ +## Git abstraction library + +Beyond the CLI, GitTools ships a set of libraries that provide a clean, testable abstraction over [LibGit2Sharp](https://github.com/libgit2/libgit2sharp). You can reference these projects directly if you want to build your own Git tooling on top of them. + +Register the services via dependency injection: + +```csharp +services.AddGit(); +``` + +Then inject `IGitRepositoryFactory` to open repositories: + +```csharp +public class MyService(IGitRepositoryFactory repoFactory) +{ + public void DoWork() + { + using var repo = repoFactory.OpenRepository("/path/to/repo"); + var branches = repo.Branches; + // ... + } +} +``` + +The abstraction layer exposes interfaces like `IGitRepository`, `IGitRepositoryFactory`, and `IGitRepositoryUtils` — making it straightforward to mock Git operations in tests. + ## Architecture -The solution is split into focused projects: +
+Project structure ``` source/ @@ -143,6 +182,8 @@ source/ └── CreativeCoders.GitTool.GitLab # GitLab service provider (GitLabApiClient) ``` +
+ ## Building from source ```bash @@ -156,7 +197,5 @@ dotnet test GitTools.sln dotnet pack source/GitTool/CreativeCoders.GitTool.Cli.GtApp/CreativeCoders.GitTool.Cli.GtApp.csproj ``` -## Requirements - -- .NET 10 SDK -- Git (with [Git Credential Manager](https://github.com/git-ecosystem/git-credential-manager) recommended for authentication) +> [!TIP] +> Found a bug or have a question? [Open an issue](https://github.com/CreativeCodersTeam/GitTools/issues). From 5ad207a7ea55bbb305ea775e09799a3abe694295 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 29 Mar 2026 11:34:27 +0200 Subject: [PATCH 09/13] refactor: simplify method with ternary operator and clean up unused imports - Replaced redundant if-else blocks with a ternary operator in `ReferenceName.Parse` for readability. - Removed unused imports in `StartFeatureCommand` and `ListVersionsCommand` to streamline code. --- .../Common/ReferenceName.cs | 9 +++------ .../FeatureGroup/Start/StartFeatureCommand.cs | 1 - .../ReleaseGroup/ListVersions/ListVersionsCommand.cs | 3 ++- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/source/Git/CreativeCoders.Git.Abstractions/Common/ReferenceName.cs b/source/Git/CreativeCoders.Git.Abstractions/Common/ReferenceName.cs index 02070ac..4bd4dfe 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Common/ReferenceName.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Common/ReferenceName.cs @@ -61,12 +61,9 @@ public static bool TryParse(string canonicalName, out ReferenceName? referenceNa /// is not a valid canonical reference name. public static ReferenceName Parse(string canonicalName) { - if (TryParse(canonicalName, out var referenceName)) - { - return referenceName!; - } - - throw new ArgumentException($"'{nameof(canonicalName)}' is not a canonical name"); + return TryParse(canonicalName, out var referenceName) + ? referenceName! + : throw new ArgumentException($"'{nameof(canonicalName)}' is not a canonical name"); } private string ShortenName() diff --git a/source/GitTool/CreativeCoders.GitTool.Cli.Commands/FeatureGroup/Start/StartFeatureCommand.cs b/source/GitTool/CreativeCoders.GitTool.Cli.Commands/FeatureGroup/Start/StartFeatureCommand.cs index fa16bf3..f834f28 100644 --- a/source/GitTool/CreativeCoders.GitTool.Cli.Commands/FeatureGroup/Start/StartFeatureCommand.cs +++ b/source/GitTool/CreativeCoders.GitTool.Cli.Commands/FeatureGroup/Start/StartFeatureCommand.cs @@ -3,7 +3,6 @@ using CreativeCoders.Core; using CreativeCoders.Core.Collections; using CreativeCoders.Git.Abstractions; -using CreativeCoders.Git.Abstractions.Branches; using CreativeCoders.GitTool.Base; using CreativeCoders.GitTool.Base.Configurations; using CreativeCoders.SysConsole.Core; diff --git a/source/GitTool/CreativeCoders.GitTool.Cli.Commands/ReleaseGroup/ListVersions/ListVersionsCommand.cs b/source/GitTool/CreativeCoders.GitTool.Cli.Commands/ReleaseGroup/ListVersions/ListVersionsCommand.cs index d81b06f..e1fca99 100644 --- a/source/GitTool/CreativeCoders.GitTool.Cli.Commands/ReleaseGroup/ListVersions/ListVersionsCommand.cs +++ b/source/GitTool/CreativeCoders.GitTool.Cli.Commands/ReleaseGroup/ListVersions/ListVersionsCommand.cs @@ -1,13 +1,14 @@ using CreativeCoders.Cli.Core; using CreativeCoders.Core; using CreativeCoders.Git.Abstractions; -using CreativeCoders.Git.Abstractions.Tags; using CreativeCoders.GitTool.Base.Versioning; using CreativeCoders.SysConsole.Core; +using JetBrains.Annotations; using Spectre.Console; namespace CreativeCoders.GitTool.Cli.Commands.ReleaseGroup.ListVersions; +[UsedImplicitly] [CliCommand([ReleaseCommandGroup.Name, "list-versions"], Description = "Lists version tags")] public class ListVersionsCommand(IAnsiConsole ansiConsole, IGitRepository gitRepository) : ICliCommand From c99910a75a2661e933de11b68bf70d2fbee48d56 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 29 Mar 2026 11:40:24 +0200 Subject: [PATCH 10/13] docs: add comprehensive XML documentation for GCM Core classes and interfaces - Added detailed XML comments to `DefaultGcmCoreCredentialStore`, `IGcmCoreCredentialStore`, `DefaultGcmCoreCredentialProvider`, and related methods. - Enhanced `ServiceCollectionExtensions` with parameter descriptions and usage remarks. - Improved code clarity with `` tags and exception summaries where applicable. --- .../DefaultGcmCoreCredentialProvider.cs | 16 ++++++++++++++++ .../DefaultGcmCoreCredentialStore.cs | 5 +++++ .../IGcmCoreCredentialStore.cs | 9 +++++++++ .../ServiceCollectionExtensions.cs | 15 +++++++++++++++ 4 files changed, 45 insertions(+) diff --git a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DefaultGcmCoreCredentialProvider.cs b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DefaultGcmCoreCredentialProvider.cs index dec0649..26d6f96 100644 --- a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DefaultGcmCoreCredentialProvider.cs +++ b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DefaultGcmCoreCredentialProvider.cs @@ -4,15 +4,25 @@ namespace CreativeCoders.Git.Auth.CredentialManagerCore; +/// +/// Default implementation of that retrieves Git credentials +/// from the Git Credential Manager Core credential store. +/// internal class DefaultGcmCoreCredentialProvider : IGitCredentialProvider { private readonly IGcmCoreCredentialStore _credentialStore; + /// + /// Initializes a new instance of the class. + /// + /// The credential store used to look up stored Git credentials. public DefaultGcmCoreCredentialProvider(IGcmCoreCredentialStore credentialStore) { _credentialStore = Ensure.Argument(credentialStore).NotNull().Value; } + /// + /// is or empty. public IGitCredential? GetCredentials(string url, string? fromUrl) { Ensure.Argument(url).NotNullOrEmpty(); @@ -26,8 +36,14 @@ public DefaultGcmCoreCredentialProvider(IGcmCoreCredentialStore credentialStore) : new GitCredential(credential.Account, credential.Password); } + /// public string Name => "GcmCore"; + /// + /// Extracts the scheme and host portion of a URL to use as a service name for credential lookup. + /// + /// The full URL from which to extract the service name. + /// A string in the form scheme://host. private static string ExtractServiceName(string url) { var uri = new Uri(url); diff --git a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DefaultGcmCoreCredentialStore.cs b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DefaultGcmCoreCredentialStore.cs index 3ded097..9b28c25 100644 --- a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DefaultGcmCoreCredentialStore.cs +++ b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/DefaultGcmCoreCredentialStore.cs @@ -3,9 +3,14 @@ namespace CreativeCoders.Git.Auth.CredentialManagerCore; +/// +/// Default implementation of that delegates to +/// the Git Credential Manager Core library. +/// [ExcludeFromCodeCoverage] internal class DefaultGcmCoreCredentialStore : IGcmCoreCredentialStore { + /// public ICredentialStore Create(string? credentialsNameSpace = null) { return CredentialManager.Create(credentialsNameSpace); diff --git a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/IGcmCoreCredentialStore.cs b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/IGcmCoreCredentialStore.cs index ef6de1a..cf70055 100644 --- a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/IGcmCoreCredentialStore.cs +++ b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/IGcmCoreCredentialStore.cs @@ -2,7 +2,16 @@ namespace CreativeCoders.Git.Auth.CredentialManagerCore; +/// +/// Provides a factory for creating instances backed by the Git Credential Manager Core. +/// public interface IGcmCoreCredentialStore { + /// + /// Creates a new instance for the specified credential namespace. + /// + /// The namespace used to scope credentials within the credential store. + /// Pass to use the default namespace. + /// An scoped to the given . ICredentialStore Create(string? credentialsNameSpace = default); } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/ServiceCollectionExtensions.cs b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/ServiceCollectionExtensions.cs index ea5dcf3..e07de9e 100644 --- a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/ServiceCollectionExtensions.cs +++ b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/ServiceCollectionExtensions.cs @@ -5,9 +5,24 @@ namespace CreativeCoders.Git.Auth.CredentialManagerCore; +/// +/// Provides extension methods for registering Git Credential Manager Core services +/// with an . +/// [PublicAPI] public static class ServiceCollectionExtensions { + /// + /// Registers the Git Credential Manager Core credential provider and its dependencies + /// as singletons in the service collection. + /// + /// The service collection to add the registrations to. + /// The same instance, allowing further chaining of registrations. + /// + /// Registers with DefaultGcmCoreCredentialStore + /// and with DefaultGcmCoreCredentialProvider. + /// Existing registrations are not overwritten. + /// public static IServiceCollection AddGcmCoreCredentialProvider(this IServiceCollection services) { services.TryAddSingleton(); From 3c05a0977684a9f523035f26571862a22e75a7b1 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 29 Mar 2026 12:09:33 +0200 Subject: [PATCH 11/13] refactor: update default parameter value to `null` in `IGcmCoreCredentialStore.Create` --- .../IGcmCoreCredentialStore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/IGcmCoreCredentialStore.cs b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/IGcmCoreCredentialStore.cs index cf70055..7a9ba25 100644 --- a/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/IGcmCoreCredentialStore.cs +++ b/source/Git/CreativeCoders.Git.Auth.CredentialManagerCore/IGcmCoreCredentialStore.cs @@ -13,5 +13,5 @@ public interface IGcmCoreCredentialStore /// The namespace used to scope credentials within the credential store. /// Pass to use the default namespace. /// An scoped to the given . - ICredentialStore Create(string? credentialsNameSpace = default); + ICredentialStore Create(string? credentialsNameSpace = null); } \ No newline at end of file From 65b6de97c0f3b30e7216b93f49bd5375e173940f Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 29 Mar 2026 12:12:00 +0200 Subject: [PATCH 12/13] refactor: remove redundant folder include and adjust namespace in unit test project - Removed unnecessary "DependencyInjection" folder include in the project file. - Updated `ServiceCollectionExtensionsTests` namespace to align with project conventions. --- ...veCoders.Git.Auth.CredentialManagerCore.UnitTests.csproj | 4 ---- .../ServiceCollectionExtensionsTests.cs | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) rename tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/{DependencyInjection => }/ServiceCollectionExtensionsTests.cs (87%) diff --git a/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests.csproj b/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests.csproj index 03d79e6..7cf9a75 100644 --- a/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests.csproj +++ b/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests.csproj @@ -25,10 +25,6 @@ - - - - diff --git a/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/DependencyInjection/ServiceCollectionExtensionsTests.cs b/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/ServiceCollectionExtensionsTests.cs similarity index 87% rename from tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/DependencyInjection/ServiceCollectionExtensionsTests.cs rename to tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/ServiceCollectionExtensionsTests.cs index 85d7042..d20cdef 100644 --- a/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/DependencyInjection/ServiceCollectionExtensionsTests.cs +++ b/tests/CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests/ServiceCollectionExtensionsTests.cs @@ -1,9 +1,9 @@ -using CreativeCoders.Git.Abstractions.Auth; -using AwesomeAssertions; +using AwesomeAssertions; +using CreativeCoders.Git.Abstractions.Auth; using Microsoft.Extensions.DependencyInjection; using Xunit; -namespace CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests.DependencyInjection; +namespace CreativeCoders.Git.Auth.CredentialManagerCore.UnitTests; public class ServiceCollectionExtensionsTests { From 2d52609f08fa91cd12180f996a47d8920193d836 Mon Sep 17 00:00:00 2001 From: darthsharp <48331467+darthsharp@users.noreply.github.com> Date: Sun, 29 Mar 2026 12:45:31 +0200 Subject: [PATCH 13/13] feat: extend `GitCommitFilter` and implement filtering logic in `GitCommitLog` - Added new properties to `GitCommitFilter` for advanced filtering: - `After`, `Before` for commit date range - `AuthorEmail` and `AuthorEmailExactMatch` for email-based filtering - `MessagePattern` for regex-based message matching - `MaxCount` for limiting results - Implemented corresponding filtering logic in `GitCommitLog.QueryBy`. - Introduced regex support for commit message filtering using `System.Text.RegularExpressions`. --- .../Commits/GitCommitFilter.cs | 46 ++++++++++++++- .../Commits/GitCommitLog.cs | 59 ++++++++++++++++++- source/Git/CreativeCoders.Git/GlobalUsings.cs | 1 + 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitFilter.cs b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitFilter.cs index 98bbe3f..292b60a 100644 --- a/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitFilter.cs +++ b/source/Git/CreativeCoders.Git.Abstractions/Commits/GitCommitFilter.cs @@ -1,4 +1,5 @@ -using JetBrains.Annotations; +using System; +using JetBrains.Annotations; namespace CreativeCoders.Git.Abstractions.Commits; @@ -28,4 +29,47 @@ public class GitCommitFilter /// Gets or sets the sorting strategy for the returned commits. ///
public GitCommitSortStrategies SortBy { get; set; } + + /// + /// Gets or sets the earliest committer date for included commits. + /// Only commits with a committer date greater than or equal to this value are included. + /// + /// A representing the start of the date range, or to apply no lower bound. + public DateTimeOffset? After { get; set; } + + /// + /// Gets or sets the latest committer date for included commits. + /// Only commits with a committer date less than or equal to this value are included. + /// + /// A representing the end of the date range, or to apply no upper bound. + public DateTimeOffset? Before { get; set; } + + /// + /// Gets or sets a filter for the author's email address. + /// The matching behavior depends on . + /// + /// A partial or full email address string, or to apply no author filter. + public string? AuthorEmail { get; set; } + + /// + /// Gets or sets a value indicating whether must match the full email address exactly. + /// + /// + /// to require an exact (case-insensitive) match; + /// (the default) to match when the author email contains the specified value. + /// + public bool AuthorEmailExactMatch { get; set; } + + /// + /// Gets or sets a regular expression pattern applied to the commit message. + /// Only commits whose message matches the pattern are included. + /// + /// A regular expression pattern string, or to apply no message filter. + public string? MessagePattern { get; set; } + + /// + /// Gets or sets the maximum number of commits to return. + /// + /// The maximum number of commits, or 0 (the default) to return all matching commits. + public int MaxCount { get; set; } } \ No newline at end of file diff --git a/source/Git/CreativeCoders.Git/Commits/GitCommitLog.cs b/source/Git/CreativeCoders.Git/Commits/GitCommitLog.cs index 5eb11fe..63a5646 100644 --- a/source/Git/CreativeCoders.Git/Commits/GitCommitLog.cs +++ b/source/Git/CreativeCoders.Git/Commits/GitCommitLog.cs @@ -40,6 +40,63 @@ public IEnumerable GetCommitsPriorTo(DateTimeOffset olderThan) /// public IEnumerable QueryBy(GitCommitFilter commitFilter) { - throw new NotImplementedException(); + Ensure.NotNull(commitFilter); + + if (_commitLog is not IQueryableCommitLog queryableCommitLog) + { + return Enumerable.Empty(); + } + + var filter = new CommitFilter + { + FirstParentOnly = commitFilter.FirstParentOnly, + SortBy = (CommitSortStrategies)(int)commitFilter.SortBy, + IncludeReachableFrom = MapReachableFrom(commitFilter.IncludeReachableFrom), + ExcludeReachableFrom = MapReachableFrom(commitFilter.ExcludeReachableFrom) + }; + + IEnumerable results = queryableCommitLog.QueryBy(filter).Select(x => new GitCommit(x)); + + if (commitFilter.After.HasValue) + { + results = results.Where(c => c.Committer.When >= commitFilter.After.Value); + } + + if (commitFilter.Before.HasValue) + { + results = results.Where(c => c.Committer.When <= commitFilter.Before.Value); + } + + if (commitFilter.AuthorEmail is not null) + { + results = commitFilter.AuthorEmailExactMatch + ? results.Where(c => + c.Author.Email.Equals(commitFilter.AuthorEmail, StringComparison.OrdinalIgnoreCase)) + : results.Where(c => + c.Author.Email.Contains(commitFilter.AuthorEmail, StringComparison.OrdinalIgnoreCase)); + } + + if (commitFilter.MessagePattern is not null) + { + var regex = new Regex(commitFilter.MessagePattern, RegexOptions.IgnoreCase); + results = results.Where(c => regex.IsMatch(c.Message)); + } + + if (commitFilter.MaxCount > 0) + { + results = results.Take(commitFilter.MaxCount); + } + + return results; + } + + private static object? MapReachableFrom(object? value) + { + return value switch + { + GitCommit gitCommit => (Commit)gitCommit, + IEnumerable commits => commits.OfType().Select(c => (Commit)c).ToList(), + _ => value + }; } } diff --git a/source/Git/CreativeCoders.Git/GlobalUsings.cs b/source/Git/CreativeCoders.Git/GlobalUsings.cs index 97439a5..800340d 100644 --- a/source/Git/CreativeCoders.Git/GlobalUsings.cs +++ b/source/Git/CreativeCoders.Git/GlobalUsings.cs @@ -1,5 +1,6 @@ global using System; global using System.Linq; +global using System.Text.RegularExpressions; global using System.Collections; global using System.Collections.Generic; global using CreativeCoders.Core;