GitCore 0.2.6

dotnet add package GitCore --version 0.2.6
                    
NuGet\Install-Package GitCore -Version 0.2.6
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GitCore" Version="0.2.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GitCore" Version="0.2.6" />
                    
Directory.Packages.props
<PackageReference Include="GitCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GitCore --version 0.2.6
                    
#r "nuget: GitCore, 0.2.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GitCore@0.2.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GitCore&version=0.2.6
                    
Install as a Cake Addin
#tool nuget:?package=GitCore&version=0.2.6
                    
Install as a Cake Tool

GitCore

Pure managed C# implementation for reading from Git repositories.

Features

  • Portable and simple
    • No dependencies on native code.
  • Reading from local Git repositories
    • Resolve HEAD and other references to commit SHAs.
    • Load all files from any commit's tree.
    • Load files from a specific subdirectory within a commit's tree.
    • Supports both loose objects and pack files.
    • Reads indexed packs with 64-bit offsets without loading complete packs.
    • Supports worktrees, bare repositories, linked worktrees, and alternate object stores.
    • Incremental tree traversal with early file and subtree pruning.
  • Working-tree file selection for formatters and similar tools
    • Query tracked files using the staging-area index, independently of HEAD.
    • Parse and cache immutable gitignore rules, or query all applicable ignore files.
    • Substitute filesystem and environment access for testing or virtual filesystems.
  • Cloning via Git Smart HTTP
    • Efficient partial cloning of subdirectories.
    • Configurable API for caching git objects to make cloning more efficient.

Usage

NuGet: https://www.nuget.org/packages/GitCore/

dotnet  add  package  GitCore

Load files from a local Git repository

var gitDir = Path.Combine(repoRootDir, ".git");

// Load all files from the current HEAD commit
var filesAtHead = GitCore.LoadFromLocalFiles.LoadTreeContentsFromHead(gitDir);

// Or resolve HEAD and load from a specific commit
var commitSha = GitCore.LoadFromLocalFiles.ResolveHead(gitDir);
var filesAtCommit = GitCore.LoadFromLocalFiles.LoadTreeContentsFromCommit(gitDir, commitSha);

// Load only files under a specific subdirectory (paths relative to subdirectory)
var subdirFiles =
    GitCore.LoadFromLocalFiles.LoadSubdirectoryContentsFromHead(
        gitDir,
        ["implement", "Pine.Core"]);

// Or from a specific commit
var subdirFilesAtCommit =
    GitCore.LoadFromLocalFiles.LoadSubdirectoryContentsFromCommit(
        gitDir,
        commitSha,
        ["implement", "Pine.Core"]);

// Resolve any reference (branch, tag, etc.)
var branchSha = GitCore.LoadFromLocalFiles.ResolveReference(gitDir, "refs/heads/main");

// Load the full in-memory object store
var repository = GitCore.LoadFromLocalFiles.LoadRepository(gitDir);

Incrementally traverse a local repository

LocalGitRepository owns pack handles and bounded caches, so keep it open while resolving related objects and dispose it afterward. Selection runs before a subtree or blob is loaded.

using var repository =
    GitCore.LocalGitRepository.Open(
        repoRootDir,
        new GitCore.LocalRepositoryOptions
        {
            MaximumCachedObjectBytes = 128 * 1024 * 1024,
            MaximumMaterializedObjectSize = 64 * 1024 * 1024
        });

var commitId =
    repository.ResolveHead()
    ?? throw new InvalidOperationException("HEAD cannot be resolved.");

await foreach (
    var file in repository.EnumerateTreeAsync(
        commitId,
        new GitCore.TreeTraversalOptions
        {
            SelectFile =
                file =>
                    file.Name is ".order" ||
                    file.Name.EndsWith(".md", StringComparison.OrdinalIgnoreCase)
                        ? GitCore.TreeFileSelection.Include
                        : GitCore.TreeFileSelection.Skip,
            SelectSubtree =
                subtree =>
                    subtree.Path.Contains(".attachments", StringComparer.OrdinalIgnoreCase)
                        ? GitCore.TreeSubtreeSelection.Skip
                        : GitCore.TreeSubtreeSelection.Descend
        }))
{
    await using var destination = CreateDestination(file.Path);
    await file.CopyContentToAsync(destination);
}

LookupObject returns Found, Missing, or MissingPromised together with a typed, context-rich error. GitCore never fetches a missing object implicitly. Applications can opt into FetchMissing or Custom and supply a MissingObjectProvider, retaining control of networking, credentials, cancellation, and persistence. Storage and limit failures use typed exceptions such as GitObjectNotFoundException, InvalidPackIndexException, InvalidPackObjectException, GitObjectSizeLimitException, and GitResourceLimitException; each exposes a GitErrorContext.

Select working-tree files for formatting

Use GitWorkingTree when processing files on disk rather than committed tree contents:

var workingTree = GitCore.GitWorkingTree.Discover(filePath);

if (workingTree is not null && workingTree.ShouldIncludeFile(filePath))
{
    // Apply the formatter to this existing regular file.
}

Open(repoRootDir) opens a known working-tree root; Discover(path) searches upward for the nearest repository and returns null outside one. Both support .git directories and gitdir files, including linked worktrees. Queries accept absolute native paths or paths relative to RootDirectory; paths outside that tree throw.

The APIs deliberately separate three questions:

API Meaning Corresponding Git command
IsTracked(path) An entry exists in the current index, including staged additions, conflict stages and files deleted only on disk. git ls-files --error-unmatch -- path
IsIgnored(path) Applicable ignore rules exclude this path, regardless of tracking. git check-ignore --no-index -- path
ShouldIncludeFile(path) An existing regular file is tracked or is untracked and not ignored. File membership in git ls-files --cached --others --exclude-standard

An ignored file that is already tracked remains a formatting candidate. Directories, missing files, symbolic links, Git metadata, and files inside nested repositories or submodules are not candidates. This predicate does not test whether content has changed, or reproduce all git status behavior (for example, assume-unchanged flags). The caller still decides which extensions to format and enumerates the files.

Ignore evaluation supports .gitignore files at each directory level, the shared info/exclude file, and user-wide excludes (core.excludesFile, or $XDG_CONFIG_HOME/git/ignore, defaulting to ~/.config/git/ignore). Later rules override earlier rules; deeper .gitignore files take precedence over parent files and repository/user excludes. An excluded parent directory must itself be re-included before any child can be re-included. Symlinked .gitignore files are not followed. IsIgnored(path, isDirectory: true) also supports hypothetical directories. Git does follow symlinks for user-wide excludes and info/exclude; these sources retain that behavior.

Repository configuration determines case sensitivity through core.ignoreCase. Case-insensitive index and ignore matching fold ASCII only; distinct non-ASCII names are not conflated. System, user, repository and enabled worktree configuration are read, including regular includes and includeIf conditions for gitdir, gitdir/i, and onbranch. Other conditional include kinds throw NotSupportedException rather than silently returning an incorrect result. Options can override IgnoreCase and GlobalExcludesFilePath (an empty path disables user-wide excludes).

An instance snapshots configuration and lazily snapshots the index. Call RefreshIndex() after staging changes, or open a new instance. Ignore files are read on each query, and unchanged contents reuse their parsed form. Instances are not intended for concurrent use. Bare repositories are not working trees.

Parse and cache individual gitignore files

var parsed = GitCore.GitIgnoreFile.Parse(rawGitignoreContent);
var ignored = parsed.IsIgnored("obj/Generated.cs");

GitIgnoreFile and its exposed rules are immutable, so applications can cache parsed files by their complete raw content, independent of a file's location. Paths in this API are slash-separated and relative to the directory containing that gitignore file. It supports comments, escaping, negation, directory-only and anchored patterns, *, ?, character classes, and Git's special ** patterns. IsIgnored also checks excluded ancestors. MatchPath matches only the supplied entry and returns true (excluded), false (re-included), or null (no matching rule), which allows applications to compose multiple ignore sources themselves.

Supply an application-wide parsing cache to working-tree queries:

var cache = new Dictionary<string, GitCore.GitIgnoreFile>();
var options = new GitCore.GitWorkingTreeOptions
{
    ParseIgnoreFile = content =>
    {
        if (!cache.TryGetValue(content, out var parsed))
            cache[content] = parsed = GitCore.GitIgnoreFile.Parse(content);
        return parsed;
    }
};
var workingTree = GitCore.GitWorkingTree.Open(repoRootDir, options: options);

ReadIndex() exposes the immutable staging-area snapshot and entry metadata. GitIndex.Parse(bytes) also parses an index without a repository or filesystem. The index reader validates checksums and accepts versions 2, 3 and 4; unsupported mandatory extensions fail explicitly rather than treating tracked files as untracked. Split indexes are resolved through the injected filesystem (GitIndex.Parse accepts a shared-index resolver). SHA-1 and SHA-256 indexes are supported. Sparse-directory entries are exposed, but queries beneath an unexpanded sparse-index directory throw NotSupportedException; use a full index for those paths. String APIs use UTF-8 Git paths and ignore/config files; malformed UTF-8 input fails explicitly. Ignore-pattern case folding and POSIX character classes follow Git's ASCII byte semantics rather than culture-sensitive text matching.

All working-tree filesystem and environment access goes through IGitFileSystem. Pass a custom implementation to Open or Discover for in-memory tests; the default is PhysicalGitFileSystem.Instance. Parsing and matching individual ignore files and indexes require no filesystem access. No API here starts a Git process.

Load files from a remote Git repository

var subdirectoryContents =
    await GitCore.LoadFromUrl.LoadSubdirectoryContentsFromGitUrlAsync(
        gitUrl: "https://github.com/pine-vm/pine.git",
        commitSha: "c837c8199f38aab839c40019a50055e16d100c74",
        subdirectoryPath: ["guide"]);
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on GitCore:

Package Downloads
Pine-Integration

Elm DevTools and runtime

Magpie.Extensions.Cardigann

Package Description

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on GitCore:

Repository Stars
pine-vm/pine
DevTools and runtime environment for the Elm programming language
Version Downloads Last Updated
0.2.6 140 10/14/2026
0.2.5 3,347 8/7/2026
0.2.4 5,220 3/28/2026
0.2.3 436 3/15/2026
0.2.2 5,897 11/10/2025
0.2.1 162 11/7/2025
0.2.0 196 11/6/2025
0.1.0 212 10/28/2025
0.0.1 199 10/27/2025