c# · .net 8 · sync + async
Per-file git metadata for .NET.
A C#/.NET port of gitmeta — one batch scan, then constant-time per-path lookups for last commit, author, churn, and tracked/ignored — with full synchronous and asynchronous (CancellationToken) APIs.
MIT licensed · zero third-party dependencies · .NET 8.0+
using GitMeta; var cache = GitMetaCache.Create("/path/to/repo"); if (cache is null) return; // not a git working tree if (cache.Lookup("Program.cs") is { } info) Console.WriteLine($"{info.LastCommitTime:yyyy-MM-dd} " + $"{info.LastCommitAuthor} — {info.CommitCount} commits");
what you get
Git history, one scan at a time.
A single batch scan up front, then every per-path question answers in constant time — the same design as the Go original, ported to idiomatic C#.
One scan, then O(1)
The same batch design as the Go original: one git ls-files + git log pass up front, then constant-time per-path lookups instead of a git log call per file.
FileGitInfo
Last-commit time, author and subject, first-seen time, and commit count (a churn proxy) — everything about a path in one readonly record struct.
Sync + async
Every I/O entry point comes in both flavors — Create / CreateAsync and Get / GetAsync — with each async variant taking a CancellationToken.
GitMetaPool
Keeps one cache per repo, re-validated on HEAD change so an unchanging tree isn't re-scanned. Safe for concurrent use — ideal for a long-running server or watcher.
Zero dependencies
Shells out to the system git binary — no third-party imports. A null return is the clean "no git data" signal; GitCommandException fires only on a broken git.
Modern C#
DateTimeOffset in UTC, nullable reference types, and a readonly record struct for results. Targets .NET 8.0+.
usage
Sync or async — same result.
Build a cache once, then read metadata per path. Use the synchronous form for scripts and one-shots; the async form when you have a CancellationToken to honor.
// Synchronous — scripts, one-shots var cache = GitMetaCache.Create("/path/to/repo"); if (cache is null) return; // no git data if (cache.Lookup("Program.cs") is { } info) Console.WriteLine(info.LastCommitAuthor);
// Asynchronous — honors a CancellationToken var cache = await GitMetaCache.CreateAsync(path, ct); if (cache is null) return; var info = await cache.GetAsync(path, ct); Console.WriteLine(info?.CommitCount);
- GitMetaCache.Create
- CreateAsync
- Lookup
- GetAsync
- GitMetaPool.Get
- IsTracked
- IsIgnored
install
Add it to your project.
One package, no transitive dependencies. Requires .NET 8.0+ and the system git binary on PATH.
dotnet add package GitMeta
using GitMeta;
The C#/.NET port of gitmeta. Source, issues, and the full API live on the GitHub repository.