Skip to content

Commit 889b13d

Browse files
committed
Allow inheriting of the parent branches increment strategy. Allows feature branches off develop or master to increment based off the develop or master increment strategy
1 parent 513004a commit 889b13d

File tree

7 files changed

+105
-8
lines changed

7 files changed

+105
-8
lines changed

GitVersionCore.Tests/GitVersionContextTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace GitVersionCore.Tests
22
{
33
using GitVersion;
4+
using LibGit2Sharp;
45
using NUnit.Framework;
56
using Shouldly;
67

@@ -50,5 +51,26 @@ public void UsesBranchSpecificConfigOverTopLevelDefaults()
5051
context.Configuration.VersioningMode.ShouldBe(VersioningMode.ContinuousDeployment);
5152
context.Configuration.Tag.ShouldBe("alpha");
5253
}
54+
55+
[Test]
56+
public void CanFindParentBranchForInheritingIncrementStrategy()
57+
{
58+
var config = new Config();
59+
config.Branches["develop"].Increment = IncrementStrategy.Major;
60+
config.Branches["feature[/-]"].Increment = IncrementStrategy.Inherit;
61+
62+
using (var repo = new EmptyRepositoryFixture(config))
63+
{
64+
repo.Repository.MakeACommit();
65+
repo.Repository.CreateBranch("develop").Checkout();
66+
repo.Repository.MakeACommit();
67+
var featureBranch = repo.Repository.CreateBranch("feature/foo");
68+
featureBranch.Checkout();
69+
repo.Repository.MakeACommit();
70+
71+
var context = new GitVersionContext(repo.Repository, featureBranch, config);
72+
context.Configuration.Increment.ShouldBe(IncrementStrategy.Major);
73+
}
74+
}
5375
}
5476
}

GitVersionCore/BranchNameComparer.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace GitVersion
2+
{
3+
using System.Collections.Generic;
4+
using LibGit2Sharp;
5+
6+
class BranchNameComparer : IEqualityComparer<Branch>
7+
{
8+
public bool Equals(Branch x, Branch y)
9+
{
10+
return x.Name == y.Name;
11+
}
12+
13+
public int GetHashCode(Branch obj)
14+
{
15+
return obj.Name.GetHashCode();
16+
}
17+
}
18+
}

GitVersionCore/Configuration/BranchConfig.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44

55
public class BranchConfig
66
{
7+
public BranchConfig()
8+
{
9+
}
10+
11+
public BranchConfig(BranchConfig branchConfiguration)
12+
{
13+
VersioningMode = branchConfiguration.VersioningMode;
14+
Tag = branchConfiguration.Tag;
15+
Increment = branchConfiguration.Increment;
16+
}
17+
718
[YamlAlias("mode")]
819
public VersioningMode? VersioningMode { get; set; }
920

GitVersionCore/Configuration/Config.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ public Config()
1414
TagPrefix = "[vV]";
1515
VersioningMode = GitVersion.VersioningMode.ContinuousDelivery;
1616
Branches["release[/-]"] = new BranchConfig { Tag = "beta" };
17+
Branches["feature[/-]"] = new BranchConfig
18+
{
19+
Increment = IncrementStrategy.Inherit,
20+
};
1721
Branches["hotfix[/-]"] = new BranchConfig { Tag = "beta" };
1822
Branches["develop"] = new BranchConfig
1923
{

GitVersionCore/Configuration/IncrementStrategy.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ public enum IncrementStrategy
55
None,
66
Major,
77
Minor,
8-
Patch
8+
Patch,
9+
/// <summary>
10+
/// Uses the increment strategy from the branch the current branch was branched from
11+
/// </summary>
12+
Inherit
913
}
1014
}

GitVersionCore/GitVersionContext.cs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,7 @@ IEnumerable<Branch> GetBranchesContainingCommit(string commitSha)
8181

8282
void CalculateEffectiveConfiguration()
8383
{
84-
var matchingBranches = configuration.Branches.Where(b => Regex.IsMatch("^" + CurrentBranch.Name, b.Key)).ToArray();
85-
86-
var currentBranchConfig = GetBranchConfiguration(matchingBranches);
84+
var currentBranchConfig = GetBranchConfiguration(CurrentBranch);
8785

8886
var versioningMode = currentBranchConfig.VersioningMode ?? configuration.VersioningMode ?? VersioningMode.ContinuousDelivery;
8987
var tag = currentBranchConfig.Tag;
@@ -93,19 +91,58 @@ void CalculateEffectiveConfiguration()
9391
Configuration = new EffectiveConfiguration(configuration.AssemblyVersioningScheme, versioningMode, configuration.TagPrefix, tag, nextVersion, incrementStrategy);
9492
}
9593

96-
BranchConfig GetBranchConfiguration(KeyValuePair<string, BranchConfig>[] matchingBranches)
94+
BranchConfig GetBranchConfiguration(Branch currentBranch)
9795
{
96+
KeyValuePair<string, BranchConfig>[] matchingBranches = configuration.Branches.Where(b => Regex.IsMatch("^" + currentBranch.Name, b.Key)).ToArray();
97+
9898
if (matchingBranches.Length == 0)
9999
{
100100
return new BranchConfig();
101101
}
102102
if (matchingBranches.Length == 1)
103103
{
104-
return matchingBranches[0].Value;
104+
var branchConfiguration = matchingBranches[0].Value;
105+
106+
if (branchConfiguration.Increment == IncrementStrategy.Inherit)
107+
{
108+
var firstCommitOfBranch = currentBranch.Commits.Last();
109+
var parentCommit = Repository.Commits.QueryBy(new CommitFilter
110+
{
111+
Until = firstCommitOfBranch
112+
}).First().Parents.First();
113+
var branchesContainingFirstCommit = ListBranchesContaininingCommit(Repository, firstCommitOfBranch.Sha);
114+
var branchesContainingParentCommit = ListBranchesContaininingCommit(Repository, parentCommit.Sha);
115+
116+
var branchNameComparer = new BranchNameComparer();
117+
var possibleParents = branchesContainingFirstCommit
118+
.Intersect(branchesContainingParentCommit, branchNameComparer)
119+
.Except(new[] { currentBranch }, branchNameComparer)
120+
.ToArray();
121+
122+
if (possibleParents.Length == 1)
123+
{
124+
return new BranchConfig(branchConfiguration)
125+
{
126+
Increment = GetBranchConfiguration(possibleParents[0]).Increment
127+
};
128+
}
129+
130+
throw new Exception("Failed to inherit Increment branch configuration");
131+
}
132+
133+
return branchConfiguration;
105134
}
106135

107-
const string format = "Multiple branch configurations match the current branch name of '{0}'. Matching configurations: '{1}'";
108-
throw new Exception(string.Format(format, CurrentBranch.Name, string.Join(", ", matchingBranches.Select(b => b.Key))));
136+
const string format = "Multiple branch configurations match the current branch branchName of '{0}'. Matching configurations: '{1}'";
137+
throw new Exception(string.Format(format, currentBranch.Name, string.Join(", ", matchingBranches.Select(b => b.Key))));
138+
}
139+
140+
static IEnumerable<Branch> ListBranchesContaininingCommit(IRepository repo, string commitSha)
141+
{
142+
return from branch in repo.Branches
143+
let commits = repo.Commits.QueryBy(new CommitFilter { Since = branch }).Where(c => c.Sha == commitSha)
144+
where commits.Any()
145+
select branch;
109146
}
110147
}
111148
}

GitVersionCore/GitVersionCore.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
<Compile Include="AssemblyVersioningScheme.cs" />
6363
<Compile Include="AssemblyVersionsGenerator.cs" />
6464
<Compile Include="Authentication.cs" />
65+
<Compile Include="BranchNameComparer.cs" />
6566
<Compile Include="BuildServers\AppVeyor.cs" />
6667
<Compile Include="BuildServers\BuildServerBase.cs" />
6768
<Compile Include="BuildServers\BuildServerList.cs" />

0 commit comments

Comments
 (0)