Skip to content

Ability to merge release back to develop #291

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion GitVersionCore.Tests/GitFlow/UncycloScenarios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void MinorReleaseExample()

// Make a commit after a tag should bump up the beta
fixture.Repository.MakeACommit();
fixture.AssertFullSemver("1.3.0-beta.2+2");
fixture.AssertFullSemver("1.3.0-beta.2+0");

// Merge release branch to master
fixture.Repository.Checkout("master");
Expand Down
36 changes: 36 additions & 0 deletions GitVersionCore.Tests/GitHubFlow/ReleaseBranchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,40 @@ public void WhenReleaseBranchIsMergedIntoMasterHighestVersionIsTakenWithIt()
fixture.AssertFullSemver("2.0.0+11");
}
}

[Test]
public void WhenMergingReleaseBackToDevShouldNotResetBetaVersion()
{
using (var fixture = new EmptyRepositoryFixture())
{
const string TaggedVersion = "1.0.3";
fixture.Repository.MakeATaggedCommit(TaggedVersion);
fixture.Repository.CreateBranch("develop");
fixture.Repository.Checkout("develop");

fixture.Repository.MakeCommits(1);

fixture.Repository.CreateBranch("release-2.0.0");
fixture.Repository.Checkout("release-2.0.0");
fixture.Repository.MakeCommits(1);

fixture.AssertFullSemver("2.0.0-beta.1+1");

//tag it to bump to beta 2
fixture.Repository.ApplyTag("2.0.0-beta1");

fixture.Repository.MakeCommits(1);

fixture.AssertFullSemver("2.0.0-beta.2+0");

//merge down to develop
fixture.Repository.Checkout("develop");
fixture.Repository.MergeNoFF("release-2.0.0", Constants.SignatureNow());

//but keep working on the release
fixture.Repository.Checkout("release-2.0.0");

fixture.AssertFullSemver("2.0.0-beta.2+0");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace GitVersion
{
using System.Collections.Generic;
using System.Linq;
using LibGit2Sharp;

Expand Down Expand Up @@ -34,5 +35,38 @@ public static int NumberOfCommitsInBranchNotKnownFromBaseBranch(IRepository repo
return repo.Commits.QueryBy(filter)
.Count();
}

public static int NumberOfCommitsSinceLastTagOrBranchPoint(GitVersionContext context, List<Tag> tagsInDescendingOrder, BranchType branchType, string baseBranchName)
{
if (!tagsInDescendingOrder.Any())
{
return NumberOfCommitsInBranchNotKnownFromBaseBranch(context.Repository, context.CurrentBranch, branchType, baseBranchName);
}

var mostRecentTag = tagsInDescendingOrder.First();
var ancestor = mostRecentTag;
if (mostRecentTag.Target == context.CurrentCommit)
{
var previousTag = tagsInDescendingOrder.Skip(1).FirstOrDefault();
if (previousTag != null)
{
ancestor = previousTag;
}
else
{
return NumberOfCommitsInBranchNotKnownFromBaseBranch(context.Repository, context.CurrentBranch, BranchType.Release, baseBranchName);
}

}

var filter = new CommitFilter
{
Since = context.CurrentCommit,
Until = ancestor.Target,
SortBy = CommitSortStrategies.Topological | CommitSortStrategies.Time
};

return context.Repository.Commits.QueryBy(filter).Count() - 1;
}
}
}
3 changes: 1 addition & 2 deletions GitVersionCore/GitFlow/BranchFinders/HotfixVersionFinder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
namespace GitVersion
{
using System.Linq;
using LibGit2Sharp;

class HotfixVersionFinder
Expand Down Expand Up @@ -28,7 +27,7 @@ public SemanticVersion FindVersion(GitVersionContext context)
static string GetSemanticVersionPreReleaseTag(GitVersionContext context, ShortVersion shortVersion, int nbHotfixCommits)
{
var semanticVersionPreReleaseTag = "beta.1";
var tagVersion = RecentTagVersionExtractor.RetrieveMostRecentOptionalTagVersion(context.Repository, shortVersion, context.CurrentBranch.Commits.Take(nbHotfixCommits + 1));
var tagVersion = RecentTagVersionExtractor.RetrieveMostRecentOptionalTagVersion(context, shortVersion);
if (tagVersion != null)
{
semanticVersionPreReleaseTag = tagVersion;
Expand Down
43 changes: 15 additions & 28 deletions GitVersionCore/GitFlow/BranchFinders/RecentTagVersionExtractor.cs
Original file line number Diff line number Diff line change
@@ -1,46 +1,33 @@
namespace GitVersion
{
using System.Collections.Generic;
using System.Linq;
using LibGit2Sharp;

class RecentTagVersionExtractor
{
internal static SemanticVersionPreReleaseTag RetrieveMostRecentOptionalTagVersion(IRepository repository, ShortVersion matchVersion, IEnumerable<Commit> take)
internal static SemanticVersionPreReleaseTag RetrieveMostRecentOptionalTagVersion(GitVersionContext context, ShortVersion matchVersion)
{
Commit first = null;
foreach (var commit in take)
var tagsInDescendingOrder = context.Repository.SemVerTagsRelatedToVersion(matchVersion).OrderByDescending(tag => SemanticVersion.Parse(tag.Name));
return RetrieveMostRecentOptionalTagVersion(context, tagsInDescendingOrder.ToList());
}

internal static SemanticVersionPreReleaseTag RetrieveMostRecentOptionalTagVersion(GitVersionContext context, List<Tag> applicableTagsInDescendingOrder)
{
if (applicableTagsInDescendingOrder.Any())
{
if (first == null)
var taggedCommit = applicableTagsInDescendingOrder.First().Target;
var preReleaseVersion = applicableTagsInDescendingOrder.Select(tag => SemanticVersion.Parse(tag.Name)).FirstOrDefault();
if (preReleaseVersion != null)
{
first = commit;
}
foreach (var tag in repository.TagsByDate(commit))
{
SemanticVersion version;
if (!SemanticVersion.TryParse(tag.Name, out version))
{
continue;
}

if (matchVersion.Major == version.Major &&
matchVersion.Minor == version.Minor &&
matchVersion.Patch == version.Patch)
if (taggedCommit != context.CurrentCommit)
{
var preReleaseTag = version.PreReleaseTag;

//If the tag is on the eact commit then dont bump the PreReleaseTag
if (first != commit)
{
preReleaseTag.Number++;
}
return preReleaseTag;
preReleaseVersion.PreReleaseTag.Number++;
}
return preReleaseVersion.PreReleaseTag;
}
}

return null;
}


}
}
16 changes: 6 additions & 10 deletions GitVersionCore/GitFlow/BranchFinders/ReleaseVersionFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,22 @@ public SemanticVersion FindVersion(GitVersionContext context)
var shortVersion = ShortVersionParser.Parse(versionString);

EnsureVersionIsValid(shortVersion, context.CurrentBranch);
var semanticVersionPreReleaseTag = "beta.1";

var nbHotfixCommits = BranchCommitDifferenceFinder.NumberOfCommitsInBranchNotKnownFromBaseBranch(context.Repository, context.CurrentBranch, BranchType.Release, "develop");

var tagVersion = RecentTagVersionExtractor.RetrieveMostRecentOptionalTagVersion(context.Repository, shortVersion, context.CurrentBranch.Commits.Take(nbHotfixCommits + 1));
if (tagVersion != null)
{
semanticVersionPreReleaseTag = tagVersion;
}
var applicableTagsInDescendingOrder = context.Repository.SemVerTagsRelatedToVersion(shortVersion).OrderByDescending(tag => SemanticVersion.Parse(tag.Name)).ToList();
var numberOfCommitsSinceLastTagOrBranchPoint = BranchCommitDifferenceFinder.NumberOfCommitsSinceLastTagOrBranchPoint(context, applicableTagsInDescendingOrder, BranchType.Release, "develop");
var semanticVersionPreReleaseTag = RecentTagVersionExtractor.RetrieveMostRecentOptionalTagVersion(context, applicableTagsInDescendingOrder) ?? "beta.1";

return new SemanticVersion
{
Major = shortVersion.Major,
Minor = shortVersion.Minor,
Patch = shortVersion.Patch,
PreReleaseTag = semanticVersionPreReleaseTag,
BuildMetaData = new SemanticVersionBuildMetaData(nbHotfixCommits, context.CurrentBranch.Name, context.CurrentCommit.Sha, context.CurrentCommit.When())
BuildMetaData = new SemanticVersionBuildMetaData(numberOfCommitsSinceLastTagOrBranchPoint, context.CurrentBranch.Name, context.CurrentCommit.Sha, context.CurrentCommit.When())
};
}

void EnsureVersionIsValid(ShortVersion version, Branch branch)
static void EnsureVersionIsValid(ShortVersion version, Branch branch)
{
if (version.Patch != 0)
{
Expand Down
15 changes: 8 additions & 7 deletions GitVersionCore/GitHubFlow/OtherBranchVersionFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ public bool FindVersion(GitVersionContext context, out SemanticVersion semanticV
}
var shortVersion = ShortVersionParser.Parse(versionString);

SemanticVersionPreReleaseTag semanticVersionPreReleaseTag = context.CurrentBranch.Name.Replace("-" + versionString, string.Empty) + ".1";

var nbHotfixCommits = BranchCommitDifferenceFinder.NumberOfCommitsInBranchNotKnownFromBaseBranch(context.Repository, context.CurrentBranch, BranchType.Unknown, "master");
var applicableTagsInDescendingOrder = context.Repository.SemVerTagsRelatedToVersion(shortVersion).OrderByDescending(tag => SemanticVersion.Parse(tag.Name)).ToList();
var nbHotfixCommits = BranchCommitDifferenceFinder.NumberOfCommitsSinceLastTagOrBranchPoint(context, applicableTagsInDescendingOrder, BranchType.Unknown, "master");
var semanticVersionPreReleaseTag = RecentTagVersionExtractor.RetrieveMostRecentOptionalTagVersion(context, applicableTagsInDescendingOrder) ?? CreateDefaultPreReleaseTag(context, versionString);

var tagVersion = RecentTagVersionExtractor.RetrieveMostRecentOptionalTagVersion(context.Repository, shortVersion, context.CurrentBranch.Commits.Take(nbHotfixCommits + 1));
if (tagVersion != null)
{
semanticVersionPreReleaseTag = tagVersion;
}

if (semanticVersionPreReleaseTag.Name == "release")
{
Expand All @@ -41,6 +37,11 @@ public bool FindVersion(GitVersionContext context, out SemanticVersion semanticV
return true;
}

SemanticVersionPreReleaseTag CreateDefaultPreReleaseTag(GitVersionContext context, string versionString)
{
return context.CurrentBranch.Name.Replace("-" + versionString, string.Empty) + ".1";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be - or /

Thinking about it, our tests should verify both. I might do that in a separate PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm not sure. I kept the existing behavior, just extracted it to a method.

}

static string GetUnknownBranchSuffix(Branch branch)
{
var unknownBranchSuffix = branch.Name.Split('-', '/');
Expand Down
17 changes: 17 additions & 0 deletions GitVersionCore/LibGitExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ public static IEnumerable<Tag> TagsByDate(this IRepository repository, Commit co
});
}

public static IEnumerable<Tag> SemVerTagsRelatedToVersion(this IRepository repository, ShortVersion version)
{
foreach (var tag in repository.Tags)
{
SemanticVersion tagVersion;
if (SemanticVersion.TryParse(tag.Name, out tagVersion))
{
if (version.Major == tagVersion.Major &&
version.Minor == tagVersion.Minor &&
version.Patch == tagVersion.Patch)
{
yield return tag;
}
}
}
}

public static GitObject PeeledTarget(this Tag tag)
{
var target = tag.Target;
Expand Down