diff --git a/src/GitVersionCore.Tests/Extensions/ExtensionMethodsTests.cs b/src/GitVersionCore.Tests/Extensions/ExtensionMethodsTests.cs new file mode 100644 index 0000000000..35945715f4 --- /dev/null +++ b/src/GitVersionCore.Tests/Extensions/ExtensionMethodsTests.cs @@ -0,0 +1,22 @@ +using GitVersion; +using NUnit.Framework; + +namespace GitVersionCore.Tests +{ + [TestFixture] + public class ExtensionMethodsTests + { + [TestCase("develop", "develop", true)] + [TestCase("develop", "master", false)] + [TestCase("/refs/head/develop", "develop", true)] + [TestCase("/refs/head/master", "develop", false)] + [TestCase("superdevelop", "develop", false)] + [TestCase("/refs/head/superdevelop", "develop", false)] + public void TheIsBranchMethod(string input1, string input2, bool expectedOutput) + { + var actualOutput = input1.IsBranch(input2); + + Assert.AreEqual(expectedOutput, actualOutput); + } + } +} diff --git a/src/GitVersionCore/Extensions/ExtensionMethods.cs b/src/GitVersionCore/Extensions/ExtensionMethods.cs index db4d4942e8..21b4c0314e 100644 --- a/src/GitVersionCore/Extensions/ExtensionMethods.cs +++ b/src/GitVersionCore/Extensions/ExtensionMethods.cs @@ -7,6 +7,23 @@ namespace GitVersion static class ExtensionMethods { + public static bool IsBranch(this string branchName, string branchNameToCompareAgainst) + { + // "develop" == "develop" + if (string.Equals(branchName, branchNameToCompareAgainst, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + // "refs/head/develop" == "develop" + if (branchName.EndsWith($"/{branchNameToCompareAgainst}", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + return false; + } + public static void AppendLineFormat(this StringBuilder stringBuilder, string format, params object[] args) { stringBuilder.AppendFormat(format, args); diff --git a/src/GitVersionCore/GitVersionContext.cs b/src/GitVersionCore/GitVersionContext.cs index c3d8abee24..87baed7141 100644 --- a/src/GitVersionCore/GitVersionContext.cs +++ b/src/GitVersionCore/GitVersionContext.cs @@ -1,4 +1,4 @@ -namespace GitVersion +namespace GitVersion { using LibGit2Sharp; using System; @@ -163,7 +163,9 @@ private static Branch GetTargetBranch(IRepository repository, string targetBranc { // There are some edge cases where HEAD is not pointing to the desired branch. // Therefore it's important to verify if 'currentBranch' is indeed the desired branch. - if (desiredBranch.CanonicalName != targetBranch) + + // CanonicalName can be "refs/heads/develop", so we need to check for "/{TargetBranch}" as well + if (!desiredBranch.CanonicalName.IsBranch(targetBranch)) { // In the case where HEAD is not the desired branch, try to find the branch with matching name desiredBranch = repository?.Branches? diff --git a/src/GitVersionCore/Helpers/GitRepositoryHelper.cs b/src/GitVersionCore/Helpers/GitRepositoryHelper.cs index 137a767bde..d5f6e5772a 100644 --- a/src/GitVersionCore/Helpers/GitRepositoryHelper.cs +++ b/src/GitVersionCore/Helpers/GitRepositoryHelper.cs @@ -15,8 +15,10 @@ public static void NormalizeGitDirectory(string gitDirectory, AuthenticationInfo { using (var repo = new Repository(gitDirectory)) { - // Need to unsure the HEAD does not move, this is essentially a BugCheck + // Need to ensure the HEAD does not move, this is essentially a BugCheck var expectedSha = repo.Head.Tip.Sha; + var expectedBranchName = repo.Head.CanonicalName; + try { var remote = EnsureOnlyOneRemoteIsDefined(repo); @@ -36,6 +38,20 @@ public static void NormalizeGitDirectory(string gitDirectory, AuthenticationInfo EnsureLocalBranchExistsForCurrentBranch(repo, remote, currentBranch); CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(repo, remote.Name); + // Bug fix for https://github.com/GitTools/GitVersion/issues/1754, head maybe have been changed + // if this is a dynamic repository. But only allow this in case the branches are different (branch switch) + if (expectedSha != repo.Head.Tip.Sha && + !expectedBranchName.IsBranch(currentBranch)) + { + var newExpectedSha = repo.Head.Tip.Sha; + var newExpectedBranchName = repo.Head.CanonicalName; + + Logger.WriteInfo($"Head has moved from '{expectedBranchName} | {expectedSha}' => '{newExpectedBranchName} | {newExpectedSha}', allowed since this is a dynamic repository"); + + expectedSha = newExpectedSha; + expectedBranchName = newExpectedBranchName; + } + var headSha = repo.Refs.Head.TargetIdentifier; if (!repo.Info.IsHeadDetached)