diff --git a/GitVersionCore.Tests/IntegrationTests/ReleaseBranchScenarios.cs b/GitVersionCore.Tests/IntegrationTests/ReleaseBranchScenarios.cs index f555e4fd63..cf56d90017 100644 --- a/GitVersionCore.Tests/IntegrationTests/ReleaseBranchScenarios.cs +++ b/GitVersionCore.Tests/IntegrationTests/ReleaseBranchScenarios.cs @@ -5,6 +5,56 @@ [TestFixture] public class ReleaseBranchScenarios { + [Test] + public void NoMergeBacksToDevelopInCaseThereAreNoChangesInReleaseBranch() + { + using (var fixture = new EmptyRepositoryFixture(new Config())) + { + fixture.Repository.MakeACommit(); + fixture.Repository.CreateBranch("develop").Checkout(); + fixture.Repository.MakeCommits(3); + var releaseBranch = fixture.Repository.CreateBranch("release/1.0.0"); + releaseBranch.Checkout(); + fixture.Repository.Checkout("master"); + fixture.Repository.MergeNoFF("release/1.0.0"); + fixture.Repository.ApplyTag("1.0.0"); + fixture.Repository.Checkout("develop"); + fixture.Repository.MakeACommit(); + + fixture.Repository.Branches.Remove(releaseBranch); + + fixture.AssertFullSemver("1.1.0-unstable.1"); + } + } + + [Test] + public void NoMergeBacksToDevelopInCaseThereAreChangesInReleaseBranch() + { + using (var fixture = new EmptyRepositoryFixture(new Config())) + { + fixture.Repository.MakeACommit(); + fixture.Repository.CreateBranch("develop").Checkout(); + fixture.Repository.MakeCommits(3); + var releaseBranch = fixture.Repository.CreateBranch("release/1.0.0"); + releaseBranch.Checkout(); + fixture.Repository.MakeACommit(); + + // Merge to master + fixture.Repository.Checkout("master"); + fixture.Repository.MergeNoFF("release/1.0.0"); + fixture.Repository.ApplyTag("1.0.0"); + + // Merge to develop + fixture.Repository.Checkout("develop"); + fixture.Repository.MergeNoFF("release/1.0.0"); + + fixture.Repository.MakeACommit(); + fixture.Repository.Branches.Remove(releaseBranch); + + fixture.AssertFullSemver("1.1.0-unstable.1"); + } + } + [Test] public void CanTakeVersionFromReleaseBranch() { diff --git a/GitVersionCore/GitVersionCore.csproj b/GitVersionCore/GitVersionCore.csproj index 844bfd5872..cb6a8fba04 100644 --- a/GitVersionCore/GitVersionCore.csproj +++ b/GitVersionCore/GitVersionCore.csproj @@ -90,6 +90,7 @@ + diff --git a/GitVersionCore/LibGitExtensions.cs b/GitVersionCore/LibGitExtensions.cs index 12b6175153..aab2c562b4 100644 --- a/GitVersionCore/LibGitExtensions.cs +++ b/GitVersionCore/LibGitExtensions.cs @@ -69,6 +69,30 @@ public static IEnumerable GetBranchesContainingCommit(this Commit commit } } + public static bool IsDirectMergeFromCommit(this Tag tag, Commit commit) + { + var targetCommit = tag.Target as Commit; + if (targetCommit != null) + { + var parents = targetCommit.Parents; + if (parents != null) + { + foreach (var parent in parents) + { + if (parent != null) + { + if (string.Equals(parent.Id.Sha, commit.Id.Sha, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + } + } + } + + return false; + } + public static GitObject PeeledTarget(this Tag tag) { var target = tag.Target; diff --git a/GitVersionCore/VersionCalculation/BaseVersionCalculators/GitFlowDevelopBranchBaseVersionStrategy.cs b/GitVersionCore/VersionCalculation/BaseVersionCalculators/GitFlowDevelopBranchBaseVersionStrategy.cs new file mode 100644 index 0000000000..3caa58300c --- /dev/null +++ b/GitVersionCore/VersionCalculation/BaseVersionCalculators/GitFlowDevelopBranchBaseVersionStrategy.cs @@ -0,0 +1,20 @@ +namespace GitVersion.VersionCalculation.BaseVersionCalculators +{ + using LibGit2Sharp; + + public class GitFlowDevelopBranchBaseVersionStrategy : HighestTagBaseVersionStrategy + { + protected override bool IsValidTag(string branchName, Tag tag, Commit commit) + { + if (!string.IsNullOrWhiteSpace(branchName)) + { + if (branchName.ToLower().EndsWith("/develop")) + { + return tag.IsDirectMergeFromCommit(commit); + } + } + + return base.IsValidTag(branchName, tag, commit); + } + } +} diff --git a/GitVersionCore/VersionCalculation/BaseVersionCalculators/HighestTagBaseVersionStrategy.cs b/GitVersionCore/VersionCalculation/BaseVersionCalculators/HighestTagBaseVersionStrategy.cs index 0bdbaab665..31e39567f5 100644 --- a/GitVersionCore/VersionCalculation/BaseVersionCalculators/HighestTagBaseVersionStrategy.cs +++ b/GitVersionCore/VersionCalculation/BaseVersionCalculators/HighestTagBaseVersionStrategy.cs @@ -1,5 +1,6 @@ namespace GitVersion.VersionCalculation.BaseVersionCalculators { + using System; using System.Linq; using LibGit2Sharp; @@ -17,17 +18,29 @@ public override BaseVersion GetVersion(GitVersionContext context) return null; } + protected virtual bool IsValidTag(string branchName, Tag tag, Commit commit) + { + return tag.PeeledTarget() == commit; + } + bool GetVersion(GitVersionContext context, out VersionTaggedCommit versionTaggedCommit) { + string currentBranchName = null; + var head = context.Repository.Head; + if (head != null) + { + currentBranchName = head.CanonicalName; + } + var olderThan = context.CurrentCommit.When(); var allTags = context.Repository.Tags - .Where(tag => ((Commit) tag.PeeledTarget()).When() <= olderThan) + .Where(tag => ((Commit)tag.PeeledTarget()).When() <= olderThan) .ToList(); var tagsOnBranch = context.CurrentBranch .Commits .SelectMany(commit => { - return allTags.Where(t => t.PeeledTarget() == commit); + return allTags.Where(t => IsValidTag(currentBranchName, t, commit)); }) .Select(t => { diff --git a/GitVersionCore/VersionCalculation/NextVersionCalculator.cs b/GitVersionCore/VersionCalculation/NextVersionCalculator.cs index 27c193fc88..161acd247e 100644 --- a/GitVersionCore/VersionCalculation/NextVersionCalculator.cs +++ b/GitVersionCore/VersionCalculation/NextVersionCalculator.cs @@ -17,10 +17,11 @@ public NextVersionCalculator(IBaseVersionCalculator baseVersionCalculator = null baseVersionFinder = baseVersionCalculator ?? new BaseVersionCalculator( new FallbackBaseVersionStrategy(), - new ConfigNextVersionBaseVersionStrategy(), - highestTagBaseVersionStrategy, - new MergeMessageBaseVersionStrategy(), - new VersionInBranchBaseVersionStrategy()); + new ConfigNextVersionBaseVersionStrategy(), + highestTagBaseVersionStrategy, + new GitFlowDevelopBranchBaseVersionStrategy(), + new MergeMessageBaseVersionStrategy(), + new VersionInBranchBaseVersionStrategy()); } public SemanticVersion FindVersion(GitVersionContext context)