scripts: harden tag-release.sh ref resolution - #11047
Open
ziggie1984 wants to merge 1 commit into
Open
Conversation
🟢 PR Severity: LOW
🟢 Low (1 files)
AnalysisThis PR only modifies To override, add a |
ziggie1984
force-pushed
the
tag-release-upstream-branch
branch
from
August 10, 2026 01:07
6210575 to
f5f542a
Compare
ziggie1984
marked this pull request as ready for review
August 10, 2026 02:11
Fully qualifies the fetch refspec and peels FETCH_HEAD to a commit before comparing it against HEAD. `git fetch <remote> <name>` resolves a tag named <name> ahead of a branch of the same name, so a tag shadowing a release branch would leave FETCH_HEAD pointing at unrelated history. Fetching `refs/heads/<name>` removes the ambiguity. The two changes belong together. Today the SHA comparison happens to fail closed under such a collision, because `git rev-parse FETCH_HEAD` yields the annotated tag object and that can never equal a commit id. Peeling on its own would turn that into a silent success on the tag's target commit, so it is only safe once the refspec pins refs/heads. Also passes --no-tags, which keeps a remote.<name>.tagOpt=--tags setting from pulling remote tags into the local repo as a side effect of what should be a read-only verification step, and rejects an empty --branch= value rather than silently falling back to the current branch.
ziggie1984
force-pushed
the
tag-release-upstream-branch
branch
from
August 10, 2026 02:12
f5f542a to
fc06ecc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hardens ref resolution in
scripts/tag-release.sh. The helper's behavior andCLI surface are unchanged: it still verifies that
HEADmatches the upstreambranch tip and tags
HEAD, and--branchstill selects the upstream branch toverify against.
refs/heads/<branch>refspecFETCH_HEADto a commit before comparing it againstHEAD--no-tags--branch=value instead of silently falling back to thecurrent branch
Motivation
git fetch <remote> <name>resolves a tag named<name>ahead of a branch ofthe same name. A tag shadowing a release branch would therefore leave
FETCH_HEADon unrelated history. Fetchingrefs/heads/<name>removes theambiguity.
The refspec and the peel belong in the same change. Today the SHA comparison
happens to fail closed under such a collision, because
git rev-parse FETCH_HEADyields the annotated tag object and that can never equal a commitid. Peeling on its own would convert that into a silent success on the tag's
target commit, so peeling is only safe once the refspec pins
refs/heads.--no-tagsis hygiene rather than a fix. With an explicit refspec, tagauto-following does not happen by default; it happens only when
remote.<name>.tagOpt=--tagsis configured, in which case a verification stepthat should be read-only silently mutates the local tag namespace. It cannot
affect any decision the script makes, since the duplicate-tag check is a
git ls-remotequery against the remote.Note that no such collision exists today — lnd release tags look like
v0.21.2-betaand would not shadowv0.21.x-branch. This closes the shaperather than a live bug.
Note on the previous revision of this PR
An earlier version of this branch changed
--branchto fetch and tag theupstream branch tip directly, so that a release could be cut without checking
the branch out. That has been dropped.
The motivating problem was that
scripts/tag-release.shdid not exist onv0.20.x-branch, which has since been addressed by backporting the script.Retargeting also gave up a property worth keeping: because the existing check
hard-fails on a
HEAD/upstream mismatch rather than merely reporting it, bothdesigns guarantee equally that the signed commit is the upstream branch tip, but
only the original guarantees that the maintainer had that tree checked out when
signing it.
Validation
bash -n scripts/tag-release.shpasses; no added line exceeds 80 characters--branch=and--branchwith no value both exit 1 with usagelive run against
origin masterwith a deliberately mismatched tag:FETCH_HEADresolved tobranch 'master'rather than a tag, peeled to acommit object, local tag count unchanged (412), and no tag was created
Exercised end to end on git 2.50.1 against a throwaway upstream carrying the
collision this change is about: a branch
v9.9.x-branchat commit Y(
build/version.go= 9.9.1) and an annotated tag of the same name at anunrelated commit X (9.9.0).
this branch, HEAD at Y: verification passes and targets Y, the branch tip,
rather than X (the run then stops at
gpgfor want of a key in the sandbox,which is past every check)
master's script, same situation: aborts, reporting anUpstream:SHA thatis neither X nor Y but the annotated tag object, since that can never equal a
commit id
peel applied without the qualified refspec, HEAD at X: passes verification and
would tag X rather than the branch tip, which is why the two changes are in
one commit
under
remote.origin.tagOpt=--tags, this branch leaves the local tag listempty where
master's script pulls in the remote tag