Skip to content

Commit de6ca29

Browse files
committed
Match commits based on versions that used either endian to calculate
1 parent 6668ac9 commit de6ca29

File tree

4 files changed

+28
-8
lines changed

4 files changed

+28
-8
lines changed

src/NerdBank.GitVersioning.Tests/LibGit2GitExtensionsTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Buffers.Binary;
23
using System.Collections.Generic;
34
using System.Diagnostics;
45
using System.IO;
@@ -368,6 +369,19 @@ public void GetIdAsVersion_Roundtrip_UnstableOffset(int startingOffset, int offs
368369
}
369370
}
370371

372+
[Fact]
373+
public void GetCommitsFromVersion_MatchesOnEitherEndian()
374+
{
375+
this.InitializeSourceControl();
376+
Commit commit = this.WriteVersionFile(new VersionOptions { Version = SemanticVersion.Parse("1.2"), GitCommitIdShortAutoMinimum = 4 });
377+
378+
Version originalVersion = new VersionOracle(this.Context).Version;
379+
Version swappedEndian = new Version(originalVersion.Major, originalVersion.Minor, originalVersion.Build, BinaryPrimitives.ReverseEndianness((ushort)originalVersion.Revision));
380+
ushort twoBytesFromCommitId = checked((ushort)originalVersion.Revision);
381+
Assert.Contains(commit, LibGit2GitExtensions.GetCommitsFromVersion(this.Context, originalVersion));
382+
Assert.Contains(commit, LibGit2GitExtensions.GetCommitsFromVersion(this.Context, swappedEndian));
383+
}
384+
371385
[Fact]
372386
public void GetIdAsVersion_Roundtrip_WithSubdirectoryVersionFiles()
373387
{

src/NerdBank.GitVersioning.Tests/TestUtilities.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ internal static ExpandedRepo ExtractRepoArchive(string repoArchiveName)
7979
}
8080
}
8181

82+
internal static string ToHex(ushort number) => number.ToString("X");
83+
84+
internal static ushort FromHex(string hex) => ushort.Parse(hex, System.Globalization.NumberStyles.HexNumber);
85+
8286
internal class ExpandedRepo : IDisposable
8387
{
8488
internal ExpandedRepo(string repoPath)

src/NerdBank.GitVersioning.Tests/VersionOracleTests.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -854,15 +854,12 @@ public void GitCommidIdLeading16BitsDecodedWithBigEndian()
854854
var oracle = new VersionOracle(this.Context);
855855

856856
string leadingFourChars = this.Context.GitCommitId.Substring(0, 4);
857-
ushort expectedNumber = FromHex(leadingFourChars);
857+
ushort expectedNumber = TestUtilities.FromHex(leadingFourChars);
858858
ushort actualNumber = checked((ushort)oracle.Version.Revision);
859859
this.Logger.WriteLine("First two characters from commit ID in hex is {0}", leadingFourChars);
860860
this.Logger.WriteLine("First two characters, converted to a number is {0}", expectedNumber);
861-
this.Logger.WriteLine("Generated 16-bit ushort from commit ID is {0}, whose hex representation is {1}", actualNumber, ToHex(actualNumber));
861+
this.Logger.WriteLine("Generated 16-bit ushort from commit ID is {0}, whose hex representation is {1}", actualNumber, TestUtilities.ToHex(actualNumber));
862862
Assert.Equal(expectedNumber, actualNumber);
863-
864-
static string ToHex(ushort number) => number.ToString("X");
865-
static ushort FromHex(string hex) => ushort.Parse(hex, System.Globalization.NumberStyles.HexNumber);
866863
}
867864

868865
[Fact(Skip = "Slow test")]

src/NerdBank.GitVersioning/LibGit2/LibGit2GitExtensions.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,11 @@ private static bool IsCommitIdMismatch(Version version, VersionOptions versionOp
284284
ushort objectIdLeadingValue = (ushort)expectedCommitIdLeadingValue;
285285
ushort objectIdMask = (ushort)(objectIdLeadingValue == MaximumBuildNumberOrRevisionComponent ? 0xfffe : 0xffff);
286286

287-
return !commit.Id.StartsWith(objectIdLeadingValue, objectIdMask);
287+
// Accept a big endian match or a little endian match.
288+
// Nerdbank.GitVersioning up to v3.4 would produce versions based on the endianness of the CPU it ran on (typically little endian).
289+
// Starting with v3.5, it deterministically used big endian. In order for `nbgv get-commits` to match on versions computed before and after the change,
290+
// we match on either endian setting.
291+
return !(commit.Id.StartsWith(objectIdLeadingValue, bigEndian: true, objectIdMask) || commit.Id.StartsWith(objectIdLeadingValue, bigEndian: false, objectIdMask));
288292
}
289293
}
290294

@@ -298,10 +302,11 @@ private static bool IsCommitIdMismatch(Version version, VersionOptions versionOp
298302
/// <param name="object">The object whose ID is to be tested.</param>
299303
/// <param name="leadingBytes">The leading 16-bits to be tested.</param>
300304
/// <param name="bitMask">The mask that indicates which bits should be compared.</param>
305+
/// <param name="bigEndian"><see langword="true"/> to read the first two bytes as big endian (v3.5+ behavior); <see langword="false"/> to use little endian (v3.4 and earlier behavior).</param>
301306
/// <returns><c>True</c> if the object's ID starts with <paramref name="leadingBytes"/> after applying the <paramref name="bitMask"/>.</returns>
302-
private static bool StartsWith(this ObjectId @object, ushort leadingBytes, ushort bitMask = 0xffff)
307+
private static bool StartsWith(this ObjectId @object, ushort leadingBytes, bool bigEndian, ushort bitMask = 0xffff)
303308
{
304-
ushort truncatedObjectId = BinaryPrimitives.ReadUInt16BigEndian(@object.RawId);
309+
ushort truncatedObjectId = bigEndian ? BinaryPrimitives.ReadUInt16BigEndian(@object.RawId) : BinaryPrimitives.ReadUInt16LittleEndian(@object.RawId);
305310
return (truncatedObjectId & bitMask) == leadingBytes;
306311
}
307312

0 commit comments

Comments
 (0)