Skip to content

Fix corrupted ThisAssembly.Git.Branch when stripping 'ref:' from refs - #526

Open
dajiaohuang wants to merge 1 commit into
devlooped:mainfrom
dajiaohuang:fix/git-branch-ref-strip
Open

dajiaohuang wants to merge 1 commit into
devlooped:mainfrom
dajiaohuang:fix/git-branch-ref-strip

Conversation

@dajiaohuang

Copy link
Copy Markdown

Describe the bug

ThisAssembly.Git produces a corrupted ThisAssembly.Git.Branch/RepositoryBranch in local (non-CI) builds, because the 'ref:' prefix intended for raw git HEAD file contents is removed with TrimStart("ref:"), which strips the characters r, e, f, : repeatedly from the start of the value:

  • On .NET SDK 9+, @(_ThisAssemblyGitSourceRoot -> '%(BranchName)') is populated by the SDK as a full ref (refs/heads/main, with no ref: prefix). TrimStart("ref:") eats the leading ref, producing s/heads/main, so the subsequent Replace('refs/heads/', '')/Replace('refs/tags/', '') never match again. In CI this is masked because the branch typically comes from GITHUB_REF-style environment variables first.
  • When the .git/HEAD fallback runs (e.g. .NET SDK 8, see also ThisAssembly.Git.targets fails to resolve branch name when working with worktrees #506) and the repo is on a detached HEAD, the value is the raw commit sha; a sha starting with e or f loses its leading character (f0fa678… becomes 0fa678…).

Repro

Minimal SDK-style project referencing ThisAssembly.Git 2.1.6, built locally (no CI env vars), printing ThisAssembly.Git.Branch:

git init probe && cd probe && dotnet new console -n Probe
dotnet add Probe package ThisAssembly.Git
cd Probe && dotnet build && dotnet run

Actual

Scenario Resulting ThisAssembly.Git.Branch
SDK 10.0.100, regular checkout of branch main s/heads/main
SDK 10.0.100, linked worktree on wt/feature-probe s/heads/wt/feature-probe
SDK 8.0.426, detached HEAD at f0fa6785… 0fa6785… (leading f lost)

Expected

main; wt/feature-probe; an unmangled value for the detached-HEAD case (git rev-parse --abbrev-ref HEAD yields HEAD, but at minimum the sha must not be silently truncated).

Fix

Strip the ref: prefix used by git HEAD files with an exact StartsWith/Substring match before the refs/heads//refs/tags/ replacements, so full refs and raw shas are left intact:

<_ThisAssemblyGitBranchName Condition="'$(_ThisAssemblyGitBranchName)' != '' and $(_ThisAssemblyGitBranchName.StartsWith('ref: '))">$(_ThisAssemblyGitBranchName.Substring(5))</_ThisAssemblyGitBranchName>

Validation

Reproduced the failure with the released 2.1.6 package, then re-ran the same scenarios against a locally-built package with this fix (net8.0, Windows):

Scenario 2.1.6 with fix
SDK 10.0.100, regular checkout, branch main s/heads/main ❌ main ✅
SDK 10.0.100, linked worktree (absolute gitdir: pointer), wt/feature-probe s/heads/wt/feature-probe ❌ wt/feature-probe ✅
SDK 8.0.426, regular checkout, branch main main ✅ (path designed for) main ✅
SDK 8.0.426, linked worktree (absolute pointer) wt/feature-probe ✅ wt/feature-probe ✅
SDK 8.0.426, linked worktree (relative gitdir: pointer), wt/relbranch wt/relbranch ✅ wt/relbranch ✅
SDK 8.0.426, detached HEAD at f0fa6785… (worktree) 0fa6785… ❌ f0fa6785… ✅

Also ran the repo test suite locally with .NET SDK 9.0.312 (ThisAssembly.Tests): 45/45 passed.

Not validated locally: the repository CI matrix-related SDK pinned via the repo DOTNET custom property (not readable); note that building the solution with the currently-installed SDK 10.0.100 already fails on pristine main (pre-existing CS8336 clash between PolySharp 1.16.0's generated Microsoft.CodeAnalysis.EmbeddedAttribute and that compiler), so CI will be the authority for the full suite.

Scope

Single-file change to src/ThisAssembly.Git/ThisAssembly.Git.targets; no generator, package layout or behavior changes beyond the corrected RepositoryBranch computation.

TrimStart("ref:") strips the characters r/e/f/: repeatedly, so:

- The .NET SDK 9+ SourceRoot BranchName metadata, which is a full ref
  ('refs/heads/main', no 'ref: ' prefix), gets corrupted to 's/heads/main',
  making the subsequent Replace('refs/heads/', ...) ineffective. Local
  (non-CI) builds therefore get a wrong ThisAssembly.Git.Branch.
- A detached HEAD fallback sha starting with 'e' or 'f' loses its leading
  character, e.g. 'f0fa678...' becomes '0fa678...'.

Now the 'ref: ' prefix used by git HEAD files is removed with an exact
prefix match before the refs/tags replacements, leaving both bare refs
and raw shas intact.
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

This branch has not been deployed

No deployments
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