From 72ca3d5f64bbd508b6081820e907a137fafa6628 Mon Sep 17 00:00:00 2001 From: AuroraAeon <77328339+AuroraAeon@users.noreply.github.com> Date: Tue, 22 Sep 2026 18:58:18 +0800 Subject: [PATCH] compare an explicit patch of zero against the minimum version GitVersion.checkMinimum guarded the patch comparison with a truthiness check on `this.patch`, so a version whose patch component was explicitly zero was treated as if the patch were unspecified and the comparison was skipped entirely. That made `new GitVersion('4.5.0').checkMinimum(new GitVersion('4.5.1'))` return true. Compare the patch only when it was actually specified, distinguishing an explicit zero from an unspecified one. A two-part version such as "2.28" still leaves patch as NaN and continues to satisfy any patch of that minor version, which is the behavior the existing tests rely on. * compare an explicit patch of zero against the minimum version * add regression coverage for an explicit patch of zero * rebuild dist --- __test__/git-version.test.ts | 25 +++++++++++++++++++++++++ dist/index.js | 8 ++++++-- src/git-version.ts | 8 ++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/__test__/git-version.test.ts b/__test__/git-version.test.ts index 740d46e7..daf9f416 100644 --- a/__test__/git-version.test.ts +++ b/__test__/git-version.test.ts @@ -45,6 +45,31 @@ describe('git-version tests', () => { expect(version.checkMinimum(new GitVersion('5.1.2'))).toBeFalsy() }) + it('compares an explicit patch of zero', async () => { + // A patch component of zero must be compared, not treated as unspecified + // (0 is falsy). A patch left unspecified by a two-part version such as + // "2.28" is treated as satisfying any patch of that minor version. + expect( + new GitVersion('4.5.0').checkMinimum(new GitVersion('4.5.1')) + ).toBeFalsy() + expect( + new GitVersion('2.28.0').checkMinimum(new GitVersion('2.28.1')) + ).toBeFalsy() + expect( + new GitVersion('4.5.0').checkMinimum(new GitVersion('4.5.0')) + ).toBeTruthy() + expect( + new GitVersion('4.5.0').checkMinimum(new GitVersion('4.5')) + ).toBeTruthy() + expect( + new GitVersion('4.5.1').checkMinimum(new GitVersion('4.5.0')) + ).toBeTruthy() + // Unspecified patch satisfies any patch of the same minor version + expect( + new GitVersion('4.5').checkMinimum(new GitVersion('4.5.0')) + ).toBeTruthy() + }) + it('sparse checkout', async () => { const minSparseVer = MinimumGitSparseCheckoutVersion expect(new GitVersion('1.0').checkMinimum(minSparseVer)).toBeFalsy() diff --git a/dist/index.js b/dist/index.js index 06ae5d22..0d56dda7 100644 --- a/dist/index.js +++ b/dist/index.js @@ -35553,8 +35553,12 @@ class GitVersion { } // Minor is equal if (this.minor === minimum.minor) { - // Patch is insufficient - if (this.patch && this.patch < (minimum.patch || 0)) { + // Patch is insufficient. The patch component is only compared when it + // was explicitly specified: an instance built from a two-part version + // (e.g. "2.28") leaves patch as NaN, which is treated as satisfying any + // patch of that minor version. An explicit zero must not be mistaken for + // an unspecified value, because 0 is falsy. + if (!Number.isNaN(this.patch) && this.patch < (minimum.patch || 0)) { return false; } } diff --git a/src/git-version.ts b/src/git-version.ts index 44bee1ae..ef02243c 100644 --- a/src/git-version.ts +++ b/src/git-version.ts @@ -43,8 +43,12 @@ export class GitVersion { // Minor is equal if (this.minor === minimum.minor) { - // Patch is insufficient - if (this.patch && this.patch < (minimum.patch || 0)) { + // Patch is insufficient. The patch component is only compared when it + // was explicitly specified: an instance built from a two-part version + // (e.g. "2.28") leaves patch as NaN, which is treated as satisfying any + // patch of that minor version. An explicit zero must not be mistaken for + // an unspecified value, because 0 is falsy. + if (!Number.isNaN(this.patch) && this.patch < (minimum.patch || 0)) { return false } }