Pmad.Git.LocalRepositories
0.1.112
dotnet add package Pmad.Git.LocalRepositories --version 0.1.112
NuGet\Install-Package Pmad.Git.LocalRepositories -Version 0.1.112
<PackageReference Include="Pmad.Git.LocalRepositories" Version="0.1.112" />
<PackageVersion Include="Pmad.Git.LocalRepositories" Version="0.1.112" />
<PackageReference Include="Pmad.Git.LocalRepositories" />
paket add Pmad.Git.LocalRepositories --version 0.1.112
#r "nuget: Pmad.Git.LocalRepositories, 0.1.112"
#:package Pmad.Git.LocalRepositories@0.1.112
#addin nuget:?package=Pmad.Git.LocalRepositories&version=0.1.112
#tool nuget:?package=Pmad.Git.LocalRepositories&version=0.1.112
Pmad.Git.LocalRepositories
Pmad.Git.LocalRepositories is a lightweight .NET 8 library that lets you inspect local Git repositories, and do basic commit operations, without shelling out to the git executable. It can open a repository, resolve commits, enumerate trees, read blobs, and inspect file history directly from the .git directory. Both SHA-1 and SHA-256 object formats are supported.
Installation
Add a project reference to Pmad.Git.LocalRepositories or publish it as a package and reference it like any other NuGet dependency. The library targets .NET 8 and uses C# 12 features.
Quick Start
using System.Text;
using Pmad.Git.LocalRepositories;
// Create a new repository
var repository = GitRepository.Init("/path/to/new-repo");
// Or open an existing repository
var repository = GitRepository.Open("/path/to/repo");
var head = await repository.GetCommitAsync();
Console.WriteLine($"HEAD: {head.Id} -> {head.Message}");
await foreach (var item in repository.EnumerateCommitTreeAsync(path: "src"))
{
Console.WriteLine($"{item.Path} ({item.Entry.Kind})");
}
var fileContent = await repository.ReadFileAsync("src/Program.cs");
Console.WriteLine(Encoding.UTF8.GetString(fileContent));
await foreach (var commit in repository.EnumerateCommitsAsync())
{
Console.WriteLine($"{commit.Id} {commit.Message}");
}
var metadata = new GitCommitMetadata(
message: "Automated change",
author: new GitCommitSignature(
name: "CI Bot",
email: "ci@example.com",
timestamp: DateTimeOffset.UtcNow));
var commitId = await repository.CreateCommitAsync(
branchName: "main",
operations: [
new AddFileOperation("src/NewFile.txt", Encoding.UTF8.GetBytes("payload"))
],
metadata);
Console.WriteLine($"Created commit {commitId.Value}");
Creating a new repository
GitRepository.Init(path, bare, initialBranch)creates a new empty git repository at the specified location.- Set
baretotrueto create a bare repository (no working directory). - The
initialBranchparameter defaults to "main" but can be customized.
Opening a repository
GitRepository.Open(path)accepts either the working directory or the.gitdirectory path.- The repository must be local and fully cloned (no sparse checkout support yet).
Reading commits and trees
GetCommitAsync()resolvesHEADor any reference/commit hash without blocking threads.EnumerateCommitsAsync()yields commits reachable from the starting reference in reverse chronological (newest-first) order as an async stream.EnumerateCommitTreeAsync(reference, path, searchOption)iterates the full tree or a subtree, exposingGitTreeItementries asynchronously.
Checking path existence
PathExistsAsync(path, reference)returnstrueif a path (file or directory) exists in the given commit.FileExistsAsync(filePath, reference)returnstrueif a blob exists at the path.DirectoryExistsAsync(directoryPath, reference)returnstrueif a tree exists at the path.GetPathTypeAsync(path, reference)returns theGitTreeEntryKind(BloborTree) of the path, ornullif it does not exist.
Reading file contents
ReadFileAsync(path, reference)returns the blob content at a path for a given commit/reference.ReadFileAndHashAsync(path, reference)returns both the blob content and itsGitHashas aGitFileContentAndHash.ReadFileStreamAsync(path, reference)returns aGitObjectStreamthat exposes the blob as aStreamwithout buffering the full content for loose objects. Dispose the stream after use (supports bothusingandawait using).EnumerateFileHistoryAsync(path, reference)yields commits where the blob hash changes.
Querying last changes
GetFilesWithLastChangeAsync(reference, path, predicate, searchOption)traverses the commit graph once and returns a sorted list ofGitFileLastChangeentries, each pairing a file path with the most recent commit that changed it. More efficient than callingEnumerateFileHistoryAsyncper file.
Creating commits
CreateCommitAsync(branch, operations, metadata)applies operations directly to the Git object store and updates the branch reference without invoking the CLI. The method is thread-safe against concurrent commits to the same branch.- Available operations derive from
GitCommitOperation:AddFileOperation(path, byte[])� adds a new file from a byte array.AddFileStreamOperation(path, Stream)� adds a new file from a stream.UpdateFileOperation(path, byte[], expectedPreviousHash?)� updates an existing file from a byte array.UpdateFileStreamOperation(path, Stream, expectedPreviousHash?)� updates an existing file from a stream.RemoveFileOperation(path)� removes an existing file.MoveFileOperation(sourcePath, destinationPath)� moves or renames an existing file.
GitCommitMetadatacaptures the commit message plus author/committer identity and timestamps used to build the commit object.
Cache management
InvalidateCaches(clearAllData)clears cached references and loose-object metadata so subsequent operations reflect the current on-disk state. Passtrueto also clear structural metadata such as the pack index.
Reachability
IsCommitReachableAsync(from, to)returnstrueif thetocommit is an ancestor of (or equal to)from; useful for fast-forward validation.
Testing
The solution includes an xUnit test project (tests/Pmad.Git.LocalRepositories.Test). Tests create temporary repositories through the real git CLI to cover end-to-end scenarios.
Run all tests:
dotnet test
Ensure the git executable is available on the PATH when running tests.
Limitations & roadmap
- Pack files are supported for reading; writing is not implemented.
- SHA-256 repositories are supported for reading, but mixed-hash scenarios are not tested.
Contributions and issues are welcome!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- SharpZipLib (>= 1.4.2)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Pmad.Git.LocalRepositories:
| Package | Downloads |
|---|---|
|
Pmad.Git.HttpServer
ASP.NET Core library that lets git synchronize with a server side stored repository. |
GitHub repositories
This package is not used by any popular GitHub repositories.