Skip to content

feat(git): fully managed Git backend selectable via GITVERSION_GIT_BACKEND#5075

Open
arturcic wants to merge 14 commits into
next/v7from
feature/managed-git
Open

feat(git): fully managed Git backend selectable via GITVERSION_GIT_BACKEND#5075
arturcic wants to merge 14 commits into
next/v7from
feature/managed-git

Conversation

@arturcic

Copy link
Copy Markdown
Member

Implements the managed Git backend for the v7.0 dual-backend window (#5031, design: docs/design/managed-git-migration.md): a vendored, fully managed reader for all read/history operations paired with the git CLI for mutations and network, selectable at runtime alongside the existing libgit2 backend.

What's in the branch

Layered bottom-up, one commit per layer, each with its tests:

  • Object database — hash-agnostic GitObjectId, zlib/random-access streams, pack + idx v2 readers with delta application, bounded pack memory cache, multi-pack-index, loose objects, SHA-256 detection with a clear failure message (NOTICE attribution for code ported from Nerdbank.GitVersioning ManagedGit, MIT).
  • Parsers — commit (signatures, encoding with Latin-1 fallback), tree (streaming reads), annotated tags.
  • Refs & repository layout — loose/packed refs (peeled, symrefs, .lock skipping), walk-up discovery with .git-file indirection, worktrees/commondir, shallow detection, config parsing, reftable rejection.
  • Revision walker — libgit2-parity time/topo ordering with exact tie-break mechanics, mark-uninteresting limiting, paint-down-to-common merge-base, .git/shallow boundaries grafted parentless.
  • Diff & status — changed-paths tree diff in raw byte order, index v2–v4 reader, gitignore matching, working-tree status matching the libgit2 adapter's uncommitted-changes expression.
  • CLI mutator — plumbing-only parsing, ArgumentList invocation (LC_ALL=C, no terminal prompts), per-invocation auth headers, stderr classification mapped to the existing exceptions (Polly LockedFileException retry preserved).
  • Adapters & selectionManaged* implementations of the Core git abstractions over an immutable session snapshot (invalidated after mutations); GITVERSION_GIT_BACKEND=libgit2|managed resolved once in GitBackendSelector (unset ⇒ libgit2 in v7.0; unknown values fail fast); the resolved backend is logged at startup.

Behavior

  • v7.0 default is unchanged (libgit2) — the managed backend is opt-in for validation; v7.1 flips the default per the release plan.
  • With managed, git on PATH is required only for normalization/dynamic-repo scenarios; plain version calculation on a prepared checkout needs no git binary.

Validation

  • CI unit-test matrix runs every leg against both backends (git_backend dimension) on three OSes — the full integration suites assert exact SemVer strings over complex histories.
  • DualBackendParityTests: deep-equality on ref enumeration, order-sensitive walks, merge-base over commit pairs (criss-cross, equal timestamps), DiffPaths, UncommittedChangesCount.
  • build/parity-corpus.ps1 diffs gitversion /nocache /output json across backends on real-world repositories.

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the new managed Git backend (managed reads + git CLI for mutations/network) to the src/ solution tree and wires runtime backend selection via GITVERSION_GIT_BACKEND (defaulting to libgit2 in v7.0), including parity-focused tests, CI matrix expansion, and migration/breaking-change documentation.

Changes:

  • Introduces GitVersion.Git.Managed + GitVersion.Git.Managed.Tests implementing the managed object store reader, revwalk/diff/status helpers, and an adapter implementing GitVersion’s git abstractions.
  • Adds GitBackendSelector and updates composition roots (App + tests) to choose libgit2 vs managed at startup, logging the resolved backend.
  • Expands CI unit-test matrix to run against both backends and adds docs/tooling to validate parity.

Reviewed changes

Copilot reviewed 112 out of 112 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/GitVersion.slnx Adds managed backend projects to solution.
src/GitVersion.MsBuild.Tests/GitVersion.MsBuild.Tests.csproj References managed backend in MSBuild tests.
src/GitVersion.Git.Managed/StreamExtensions.cs Adds stream helpers for managed object reading.
src/GitVersion.Git.Managed/Status/GitIgnoreRules.cs Implements gitignore parsing/matching for status.
src/GitVersion.Git.Managed/SafeFileHandleExtensions.cs Adds random-access file read helper.
src/GitVersion.Git.Managed/Refs/GitReference.cs Defines reference model for ref store.
src/GitVersion.Git.Managed/RandomAccessStream.cs Read-only seekable stream over shared file handle.
src/GitVersion.Git.Managed/PublicAPI.Unshipped.txt Public API tracking for new module surface.
src/GitVersion.Git.Managed/PublicAPI.Shipped.txt Public API shipped baseline for new project.
src/GitVersion.Git.Managed/NOTICE.md Third-party attribution for vendored portions.
src/GitVersion.Git.Managed/History/GitRevisionWalkOptions.cs Walk options for revision walker.
src/GitVersion.Git.Managed/History/GitRevisionSortStrategies.cs Sort strategy flags for managed revwalk.
src/GitVersion.Git.Managed/GitZLibStream.cs Zlib decompression stream for git objects.
src/GitVersion.Git.Managed/GitVersionManagedGitModule.cs DI module registering managed backend services.
src/GitVersion.Git.Managed/GitVersion.Git.Managed.csproj New managed backend project.
src/GitVersion.Git.Managed/GitTreeStreamingReader.cs Tree scanning helper used for lookups.
src/GitVersion.Git.Managed/GitTreeReader.cs Tree object parser/reader.
src/GitVersion.Git.Managed/GitTree.cs Tree + entry model.
src/GitVersion.Git.Managed/GitTextDecoder.cs UTF-8/Latin-1 decoding matching git behavior.
src/GitVersion.Git.Managed/GitTagReader.cs Annotated tag parser.
src/GitVersion.Git.Managed/GitTag.cs Tag model.
src/GitVersion.Git.Managed/GitSignature.cs Signature parser for commit/tag metadata.
src/GitVersion.Git.Managed/GitPackReader.cs Pack object reader (incl. deltas).
src/GitVersion.Git.Managed/GitPackObjectType.cs Pack object type enum.
src/GitVersion.Git.Managed/GitPackMemoryCacheViewStream.cs View stream over shared pack cache entry.
src/GitVersion.Git.Managed/GitPackMemoryCacheStream.cs In-memory caching wrapper for non-seekable streams.
src/GitVersion.Git.Managed/GitPackMemoryCache.cs Bounded LRU cache for pack object streams.
src/GitVersion.Git.Managed/GitPackIndexReader.cs .idx v2 reader for pack lookups.
src/GitVersion.Git.Managed/GitPackDeltafiedStream.cs Applies delta instructions to base streams.
src/GitVersion.Git.Managed/GitPackCache.cs Pack cache abstraction.
src/GitVersion.Git.Managed/GitPack.cs Pack + index integration and object retrieval.
src/GitVersion.Git.Managed/GitObjectTypes.cs Canonical object type names and mapping.
src/GitVersion.Git.Managed/GitObjectStream.cs Loose-object stream reader (type+len header).
src/GitVersion.Git.Managed/GitObjectStoreException.cs Internal exception type for managed store.
src/GitVersion.Git.Managed/GitCommitReader.cs Commit object parser.
src/GitVersion.Git.Managed/GitCommit.cs Commit model with lazy decoding.
src/GitVersion.Git.Managed/FileHelpers.cs File open helper for repo IO.
src/GitVersion.Git.Managed/Diff/GitTreeDiff.cs Tree diff implementation for DiffPaths parity.
src/GitVersion.Git.Managed/DeltaStreamReader.cs Delta instruction decoder.
src/GitVersion.Git.Managed/DeltaInstruction.cs Delta instruction representation.
src/GitVersion.Git.Managed/CommandLine/PullRequestBranchOperations.cs PR-ref to local-branch operations logic.
src/GitVersion.Git.Managed/CommandLine/GitRemoteReference.cs Remote reference record for ls-remote results.
src/GitVersion.Git.Managed/CommandLine/GitCliExecutor.cs Executes git with controlled env/args.
src/GitVersion.Git.Managed/Adapter/RepositoryPathResolution.cs Resolves repo paths for managed backend.
src/GitVersion.Git.Managed/Adapter/ManagedTagCollection.cs Adapter tag enumeration implementation.
src/GitVersion.Git.Managed/Adapter/ManagedTag.cs Adapter tag implementation.
src/GitVersion.Git.Managed/Adapter/ManagedRemoteCollection.cs Adapter remote collection implementation.
src/GitVersion.Git.Managed/Adapter/ManagedRemote.cs Adapter remote implementation.
src/GitVersion.Git.Managed/Adapter/ManagedRefSpecCollection.cs Adapter refspec collection implementation.
src/GitVersion.Git.Managed/Adapter/ManagedRefSpec.cs Adapter refspec parsing/representation.
src/GitVersion.Git.Managed/Adapter/ManagedReferenceCollection.cs Adapter reference collection implementation.
src/GitVersion.Git.Managed/Adapter/ManagedReference.cs Adapter reference implementation.
src/GitVersion.Git.Managed/Adapter/ManagedObjectId.cs Adapter object id implementation.
src/GitVersion.Git.Managed/Adapter/ManagedGitRepositoryInfo.cs Managed IGitRepositoryInfo implementation.
src/GitVersion.Git.Managed/Adapter/ManagedGitRepository.mutating.cs CLI-backed mutating operations + invalidation.
src/GitVersion.Git.Managed/Adapter/ManagedGitRepository.cs Managed repository session + read operations.
src/GitVersion.Git.Managed/Adapter/ManagedCommitCollection.cs Commit enumeration/querying via managed revwalk.
src/GitVersion.Git.Managed/Adapter/ManagedCommit.cs Adapter commit implementation.
src/GitVersion.Git.Managed/Adapter/ManagedBranchCollection.cs Adapter branch collection implementation.
src/GitVersion.Git.Managed/Adapter/ManagedBranch.cs Adapter branch implementation.
src/GitVersion.Git.Managed/Adapter/DynamicRepositoryPath.cs Dynamic repo path selection logic for managed backend.
src/GitVersion.Git.Managed.Tests/TreeTests.cs Tests for tree reading/streaming lookup.
src/GitVersion.Git.Managed.Tests/TempDirectory.cs Test temp directory helper.
src/GitVersion.Git.Managed.Tests/TagTests.cs Tests for annotated/nested/packed tags.
src/GitVersion.Git.Managed.Tests/PullRequestBranchOperationsTests.cs Tests for PR-ref candidate selection.
src/GitVersion.Git.Managed.Tests/PackedObjectTests.cs Pack reading + delta chain tests.
src/GitVersion.Git.Managed.Tests/MultiPackIndexTests.cs Multi-pack-index parity tests.
src/GitVersion.Git.Managed.Tests/LooseObjectTests.cs Loose object reading + encoding tests.
src/GitVersion.Git.Managed.Tests/GitVersion.Git.Managed.Tests.csproj New managed backend test project.
src/GitVersion.Git.Managed.Tests/GitTreeDiffTests.cs Validates diff-path parity with libgit2.
src/GitVersion.Git.Managed.Tests/GitTestRepository.cs Git CLI test repo fixture helper.
src/GitVersion.Git.Managed.Tests/GitRepositoryLayoutTests.cs Repo discovery/worktree/shallow/reftable tests.
src/GitVersion.Git.Managed.Tests/GitObjectIdTests.cs Tests for hash-agnostic object id parsing/format.
src/GitVersion.Git.Managed.Tests/GitIndexTests.cs Index reader parity tests for v2–v4.
src/GitVersion.Git.Managed.Tests/GitConfigurationFileTests.cs Git config parsing tests.
src/GitVersion.Git.Managed.Tests/DeltaStreamReaderTests.cs Delta decoder tests.
src/GitVersion.Git.Managed.Tests/AssemblyParallelizable.cs Enables fixture-level parallelization.
src/GitVersion.Core/GitVersion.Core.csproj Adds InternalsVisibleTo for managed backend/tests.
src/GitVersion.Core/Git/GitBackend.cs Adds backend enum + env var selector.
src/GitVersion.Core.Tests/Helpers/GitVersionCoreTestModule.cs Test DI chooses backend via selector.
src/GitVersion.Core.Tests/GitVersion.Core.Tests.csproj References managed backend from Core tests.
src/GitVersion.Core.Tests/Core/GitCliMutatorTests.cs Tests for CLI mutator and env scrubbing.
src/GitVersion.Core.Tests/Core/GitBackendSelectorTests.cs Tests for env var backend selection behavior.
src/GitVersion.App/GitVersionExecutor.cs Logs selected backend at startup.
src/GitVersion.App/GitVersion.App.csproj References managed backend assembly.
src/GitVersion.App/CliHost.cs Composition chooses backend via selector.
src/.run/cli (version).run.xml Adds IDE run config for version command.
src/.run/cli (managed).run.xml Adds IDE run config with managed backend env var.
src/.run/cli (libgit2sharp).run.xml Adds IDE run config with libgit2 backend env var.
new-cli/GitVersion.Common/GitVersion.Common.csproj Adds Microsoft.Extensions.Logging using for source-linked code.
docs/input/docs/migration/v6-to-v7.md Documents backend selection + migration notes.
build/parity-corpus.md Documents real-world parity corpus script usage.
BREAKING_CHANGES.md Documents selectable backend and default flip plan.
.github/workflows/ci.yml Adds push branch gate for managed-git feature branch.
.github/workflows/_unit_tests.yml Adds git_backend matrix dimension and env var.

Comment thread src/GitVersion.Git.Managed/StreamExtensions.cs
Comment thread src/GitVersion.Git.Managed/CommandLine/PullRequestBranchOperations.cs Outdated
Comment thread src/GitVersion.Git.Managed/GitPackDeltafiedStream.cs
Comment thread src/GitVersion.Git.Managed/GitTreeStreamingReader.cs
Comment thread src/GitVersion.Git.Managed/CommandLine/GitCliExecutor.cs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 112 out of 112 changed files in this pull request and generated 3 comments.

Comment thread src/GitVersion.Git.Managed/StreamExtensions.cs
Comment thread src/GitVersion.Git.Managed/RandomAccessStream.cs Outdated
Comment thread src/GitVersion.Git.Managed/Adapter/RepositoryPathResolution.cs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 112 out of 112 changed files in this pull request and generated 2 comments.

Comment thread src/GitVersion.Git.Managed/GitPackMemoryCache.cs Outdated
Comment thread src/GitVersion.Git.Managed/CommandLine/GitCliExecutor.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 112 out of 112 changed files in this pull request and generated 1 comment.

Comment thread src/GitVersion.Git.Managed/Adapter/ManagedRemote.cs
arturcic and others added 14 commits July 17, 2026 18:48
Research and phased plan for replacing LibGit2Sharp with a vendored
managed reader plus git CLI writes (#5031).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…primitives

New project (with NOTICE attribution for code ported from Nerdbank.GitVersioning
ManagedGit) and the raw building blocks: hash-agnostic GitObjectId, zlib and
random-access streams, text decoding with Latin-1 fallback, and file helpers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Packfile access with idx v2 lookup, ofs/ref delta stream application, a
bounded pack memory cache with refcounted views, and multi-pack-index support.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author/committer signatures with commit-encoding handling, streaming tree
reads for diff traversal, and annotated-tag target resolution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Single lookup facade across loose objects, packs, and the multi-pack index,
with SHA-256 repository detection failing fast with a clear message.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Loose and packed refs (peeled entries, symrefs, HEAD, lock-file skipping),
walk-up discovery with .git-file indirection, worktree and commondir
resolution, shallow detection, git config parsing, and reftable/objectformat
rejection with clear messages.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Time/topological sorts with exact tie-break mechanics, first-parent walks,
mark-uninteresting limiting, paint-down-to-common merge-base selection, and
shallow boundaries grafted parentless from .git/shallow; unexplained missing
parents fail the walk.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Changed-paths tree diff aligned by raw byte order, .git/index v2-v4 reader
(v4 prefix compression), gitignore matching, and the working-tree status
walk matching the libgit2 adapter's uncommitted-changes expression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Plumbing-only parsing, ArgumentList invocation with LC_ALL=C and terminal
prompts disabled, per-invocation auth headers, stderr classification mapped
to existing exceptions (LockedFileException retry preserved), and shared
pull-request tip matching with peeled-entry folding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Managed* adapters implement IGitRepository/IMutatingGitRepository and the
collection interfaces directly over the managed reader and CLI mutator, with
an immutable session snapshot invalidated after mutations. Backend selection
is centralized in GitBackendSelector: GITVERSION_GIT_BACKEND picks libgit2
(default when unset) or managed at every composition root, failing fast on
unrecognized values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deep-equality parity assertions across both backends on adversarial fixtures,
plus a real-world corpus script diffing gitversion JSON output across
repositories and backends.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds the git_backend dimension so every leg runs with libgit2 and managed,
publishing per-backend test summaries and coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
GITVERSION_GIT_BACKEND usage, the v7.0 libgit2 default and v7.1 managed flip,
and the git-on-PATH requirement scoped to normalization scenarios.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add shared IntelliJ/Rider run configurations to facilitate debugging the CLI using both libgit2sharp and managed git backends.
@arturcic
arturcic force-pushed the feature/managed-git branch from 352d609 to 3fe5212 Compare July 17, 2026 15:50
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants