Skip to content

Commit 41c0671

Browse files
committed
Improved version calculation for feature branches in mainline mode - fixes #1154
In short when calculating the direct commits to master we need to remove any commits which are not on master. Otherwise we bump the mainline version on feature branches way too much. We also need to increment feature branches at the end of feature calculation unless the HEAD is a merge commit into the mainline branch (to cater for pull requests).
1 parent d46ee06 commit 41c0671

File tree

4 files changed

+50
-8
lines changed

4 files changed

+50
-8
lines changed

src/GitVersionCore.Tests/IntegrationTests/MainlineDevelopmentMode.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public void VerifyPullRequestsActLikeContinuousDelivery()
9696
fixture.AssertFullSemver(config, "1.0.1");
9797

9898
fixture.BranchTo("feature/foo", "foo");
99+
fixture.AssertFullSemver(config, "1.0.2-foo.0");
99100
fixture.MakeACommit();
100101
fixture.MakeACommit();
101102
fixture.Repository.CreatePullRequestRef("feature/foo", "master", normalise: true, prNumber: 8);
@@ -149,15 +150,20 @@ public void VerifyForwardMerge()
149150

150151
fixture.BranchTo("feature/foo", "foo");
151152
fixture.MakeACommit();
153+
fixture.AssertFullSemver(config, "1.0.2-foo.1");
152154
fixture.MakeACommit();
153155
fixture.AssertFullSemver(config, "1.0.2-foo.2");
154156

155157
fixture.Checkout("master");
156158
fixture.MakeACommit();
157159
fixture.AssertFullSemver(config, "1.0.2");
158160
fixture.Checkout("feature/foo");
161+
// This may seem surprising, but this happens because we branched off mainline
162+
// and incremented. Mainline has then moved on. We do not follow mainline
163+
// in feature branches, you need to merge mainline in to get the mainline version
164+
fixture.AssertFullSemver(config, "1.0.2-foo.2");
159165
fixture.MergeNoFF("master");
160-
fixture.AssertFullSemver(config, "1.0.4-foo.3");
166+
fixture.AssertFullSemver(config, "1.0.3-foo.3");
161167
}
162168
}
163169

@@ -240,6 +246,31 @@ public void VerifyMergingMasterToFeatureDoesNotStopMasterCommitsIncrementingVers
240246
}
241247
}
242248

249+
[Test]
250+
public void VerifyIssue1154_CanForwardMergeMasterToFeatureBranch()
251+
{
252+
using (var fixture = new EmptyRepositoryFixture())
253+
{
254+
fixture.MakeACommit();
255+
fixture.BranchTo("feature/branch2");
256+
fixture.BranchTo("feature/branch1");
257+
fixture.MakeACommit();
258+
fixture.MakeACommit();
259+
260+
fixture.Checkout("master");
261+
fixture.MergeNoFF("feature/branch1");
262+
fixture.AssertFullSemver(config, "0.1.1");
263+
264+
fixture.Checkout("feature/branch2");
265+
fixture.MakeACommit();
266+
fixture.MakeACommit();
267+
fixture.MakeACommit();
268+
fixture.MergeNoFF("master");
269+
270+
fixture.AssertFullSemver(config, "0.1.2-branch2.4");
271+
}
272+
}
273+
243274
[Test]
244275
public void VerifyMergingMasterIntoAFeatureBranchWorksWithMultipleBranches()
245276
{

src/GitVersionCore.Tests/IntegrationTests/RemoteRepositoryScenarios.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ public void GivenARemoteGitRepositoryAheadOfLocalRepository_ThenChangesShouldPul
6565
[Test]
6666
public void GivenARemoteGitRepositoryWhenCheckingOutDetachedhead_UsingExistingImplementationThrowsException()
6767
{
68-
6968
using (var fixture = new RemoteRepositoryFixture())
7069
{
7170
Commands.Checkout(

src/GitVersionCore/BranchConfigurationCalculator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ static IEnumerable<BranchConfig> LookupBranchConfiguration([NotNull] Config conf
4949
{
5050
if (config == null)
5151
{
52-
throw new ArgumentNullException("config");
52+
throw new ArgumentNullException(nameof(config));
5353
}
5454

5555
if (currentBranch == null)
5656
{
57-
throw new ArgumentNullException("currentBranch");
57+
throw new ArgumentNullException(nameof(currentBranch));
5858
}
5959

6060
return config.Branches.Where(b => Regex.IsMatch(currentBranch.FriendlyName, "^" + b.Value.Regex, RegexOptions.IgnoreCase)).Select(kvp => kvp.Value);

src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,25 @@ SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion, GitVersionConte
9595
// / |
9696
// master * *
9797
//
98+
99+
var mainlineTip = GetMainlineTip(context);
100+
var commitsNotOnMainline = context.Repository.Commits.QueryBy(new CommitFilter
101+
{
102+
IncludeReachableFrom = context.CurrentBranch,
103+
ExcludeReachableFrom = mainlineTip,
104+
SortBy = CommitSortStrategies.Reverse,
105+
FirstParentOnly = true
106+
}).Where(c => c.Sha != baseVersion.BaseVersionSource.Sha && c.Parents.Count() == 1).ToList();
98107
var commitLog = context.Repository.Commits.QueryBy(new CommitFilter
99108
{
100109
IncludeReachableFrom = context.CurrentBranch,
101110
ExcludeReachableFrom = baseVersion.BaseVersionSource,
102111
SortBy = CommitSortStrategies.Reverse,
103112
FirstParentOnly = true
104-
}).Where(c => c.Sha != baseVersion.BaseVersionSource.Sha).ToList();
113+
})
114+
.Where(c => c.Sha != baseVersion.BaseVersionSource.Sha)
115+
.Except(commitsNotOnMainline)
116+
.ToList();
105117

106118
var directCommits = new List<Commit>();
107119

@@ -118,16 +130,16 @@ SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion, GitVersionConte
118130
if (context.CurrentBranch.FriendlyName != "master")
119131
{
120132
var mergedHead = context.CurrentCommit;
121-
var mainlineTip = GetMainlineTip(context);
122133
var findMergeBase = context.Repository.ObjectDatabase.FindMergeBase(context.CurrentCommit, mainlineTip);
123134
Logger.WriteInfo(string.Format("Current branch ({0}) was branch from {1}", context.CurrentBranch.FriendlyName, findMergeBase));
124135

125136
var branchIncrement = FindMessageIncrement(context, null, mergedHead, findMergeBase, directCommits);
126137
// This will increment for any direct commits on master
127138
mainlineVersion = IncrementForEachCommit(context, directCommits, mainlineVersion);
128139
mainlineVersion.BuildMetaData = metaDataCalculator.Create(findMergeBase, context);
129-
// Only increment if head is not a merge commit, ensures PR's and forward merges end up correct.
130-
if (mergedHead.Parents.Count() == 1)
140+
// Don't increment if the merge commit is a merge into mainline
141+
// this ensures PR's and forward merges end up correct.
142+
if (mergedHead.Parents.Count() == 1 || mergedHead.Parents.First() != mainlineTip)
131143
{
132144
Logger.WriteInfo(string.Format("Performing {0} increment for current branch ", branchIncrement));
133145
mainlineVersion = mainlineVersion.IncrementVersion(branchIncrement);

0 commit comments

Comments
 (0)