diff --git a/src/GitVersionCore.Tests/GitToolsTestingExtensions.cs b/src/GitVersionCore.Tests/GitToolsTestingExtensions.cs index c556e0d7ab..930f71d9c9 100644 --- a/src/GitVersionCore.Tests/GitToolsTestingExtensions.cs +++ b/src/GitVersionCore.Tests/GitToolsTestingExtensions.cs @@ -15,14 +15,14 @@ public static Config ApplyDefaults(this Config config) return config; } - public static VersionVariables GetVersion(this RepositoryFixtureBase fixture, Config configuration = null, IRepository repository = null, string commitId = null, bool isForTrackedBranchOnly = true) + public static VersionVariables GetVersion(this RepositoryFixtureBase fixture, Config configuration = null, IRepository repository = null, string commitId = null, bool isForTrackedBranchOnly = true, string targetBranch = null) { if (configuration == null) { configuration = new Config(); ConfigurationProvider.ApplyDefaultsTo(configuration); } - var gitVersionContext = new GitVersionContext(repository ?? fixture.Repository, configuration, isForTrackedBranchOnly, commitId); + var gitVersionContext = new GitVersionContext(repository ?? fixture.Repository, targetBranch, configuration, isForTrackedBranchOnly, commitId); var executeGitVersion = ExecuteGitVersion(gitVersionContext); var variables = VariableProvider.GetVariablesFor(executeGitVersion, gitVersionContext.Configuration, gitVersionContext.IsCurrentCommitTagged); try @@ -37,19 +37,19 @@ public static VersionVariables GetVersion(this RepositoryFixtureBase fixture, Co } } - public static void AssertFullSemver(this RepositoryFixtureBase fixture, string fullSemver, IRepository repository = null, string commitId = null, bool isForTrackedBranchOnly = true) + public static void AssertFullSemver(this RepositoryFixtureBase fixture, string fullSemver, IRepository repository = null, string commitId = null, bool isForTrackedBranchOnly = true, string targetBranch = null) { - fixture.AssertFullSemver(new Config(), fullSemver, repository, commitId, isForTrackedBranchOnly); + fixture.AssertFullSemver(new Config(), fullSemver, repository, commitId, isForTrackedBranchOnly, targetBranch); } - public static void AssertFullSemver(this RepositoryFixtureBase fixture, Config configuration, string fullSemver, IRepository repository = null, string commitId = null, bool isForTrackedBranchOnly = true) + public static void AssertFullSemver(this RepositoryFixtureBase fixture, Config configuration, string fullSemver, IRepository repository = null, string commitId = null, bool isForTrackedBranchOnly = true, string targetBranch = null) { ConfigurationProvider.ApplyDefaultsTo(configuration); Console.WriteLine("---------"); try { - var variables = fixture.GetVersion(configuration, repository, commitId, isForTrackedBranchOnly); + var variables = fixture.GetVersion(configuration, repository, commitId, isForTrackedBranchOnly, targetBranch); variables.FullSemVer.ShouldBe(fullSemver); } catch (Exception) diff --git a/src/GitVersionCore.Tests/GitVersionContextBuilder.cs b/src/GitVersionCore.Tests/GitVersionContextBuilder.cs index 85bd100906..35e22fa0c1 100644 --- a/src/GitVersionCore.Tests/GitVersionContextBuilder.cs +++ b/src/GitVersionCore.Tests/GitVersionContextBuilder.cs @@ -61,7 +61,8 @@ public GitVersionContext Build() { var configuration = config ?? new Config(); ConfigurationProvider.ApplyDefaultsTo(configuration); - return new GitVersionContext(repository ?? CreateRepository(), configuration); + var repo = repository ?? CreateRepository(); + return new GitVersionContext(repo, repo.Head, configuration); } IRepository CreateRepository() diff --git a/src/GitVersionCore.Tests/GitVersionContextTests.cs b/src/GitVersionCore.Tests/GitVersionContextTests.cs index d095ae6208..21dcbd4d22 100644 --- a/src/GitVersionCore.Tests/GitVersionContextTests.cs +++ b/src/GitVersionCore.Tests/GitVersionContextTests.cs @@ -144,7 +144,7 @@ public void CanFindParentBranchForInheritingIncrementStrategy() Commands.Checkout(repo.Repository, featureBranch); repo.Repository.MakeACommit(); - var context = new GitVersionContext(repo.Repository, config); + var context = new GitVersionContext(repo.Repository, repo.Repository.Head, config); context.Configuration.Increment.ShouldBe(IncrementStrategy.Major); } } diff --git a/src/GitVersionCore.Tests/IntegrationTests/BranchWithoutCommitScenario.cs b/src/GitVersionCore.Tests/IntegrationTests/BranchWithoutCommitScenario.cs new file mode 100644 index 0000000000..e7b3793ca9 --- /dev/null +++ b/src/GitVersionCore.Tests/IntegrationTests/BranchWithoutCommitScenario.cs @@ -0,0 +1,22 @@ +using GitTools.Testing; +using GitVersionCore.Tests; +using LibGit2Sharp; +using NUnit.Framework; + +[TestFixture] +public class BranchWithoutCommitScenario +{ + [Test] + public void CanTakeVersionFromReleaseBranch() + { + using (var fixture = new EmptyRepositoryFixture()) + { + fixture.Repository.MakeATaggedCommit("1.0.3"); + var commit = fixture.Repository.MakeACommit(); + fixture.Repository.CreateBranch("release-4.0.123"); + fixture.Checkout(commit.Sha); + + fixture.AssertFullSemver("4.0.123-beta.1+0", fixture.Repository, commit.Sha, false, "release-4.0.123"); + } + } +} \ No newline at end of file diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index ddab02ea5a..edb5de640f 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -108,7 +108,7 @@ VersionVariables ExecuteInternal(string targetBranch, string commitId, GitPrepar return gitPreparer.WithRepository(repo => { - var gitVersionContext = new GitVersionContext(repo, configuration, commitId: commitId); + var gitVersionContext = new GitVersionContext(repo, targetBranch, configuration, commitId: commitId); var semanticVersion = versionFinder.FindVersion(gitVersionContext); return VariableProvider.GetVariablesFor(semanticVersion, gitVersionContext.Configuration, gitVersionContext.IsCurrentCommitTagged); diff --git a/src/GitVersionCore/GitVersionContext.cs b/src/GitVersionCore/GitVersionContext.cs index 27cd14f527..08eeccb7c9 100644 --- a/src/GitVersionCore/GitVersionContext.cs +++ b/src/GitVersionCore/GitVersionContext.cs @@ -9,8 +9,8 @@ /// public class GitVersionContext { - public GitVersionContext(IRepository repository, Config configuration, bool isForTrackingBranchOnly = true, string commitId = null) - : this(repository, repository.Head, configuration, isForTrackingBranchOnly, commitId) + public GitVersionContext(IRepository repository, string targetBranch, Config configuration, bool onlyEvaluateTrackedBranches = true, string commitId = null) + : this(repository, GitVersionContext.GetTargetBranch(repository, targetBranch), configuration, onlyEvaluateTrackedBranches, commitId) { } @@ -146,5 +146,31 @@ void CalculateEffectiveConfiguration() currentBranchConfig.TracksReleaseBranches.Value, currentBranchConfig.IsReleaseBranch.Value); } + + private static Branch GetTargetBranch(IRepository repository, string targetBranch) + { + // By default, we assume HEAD is pointing to the desired branch + var desiredBranch = repository.Head; + + // Make sure the desired branch has been specified + if (!string.IsNullOrEmpty(targetBranch)) + { + // 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) + { + // In the case where HEAD is not the desired branch, try to find the branch with matching name + desiredBranch = repository?.Branches? + .SingleOrDefault(b => + b.CanonicalName == targetBranch || + b.FriendlyName == targetBranch); + + // Failsafe in case the specified branch is invalid + desiredBranch = desiredBranch ?? repository.Head; + } + } + + return desiredBranch; + } } }