Skip to content

Commit cf893ff

Browse files
committed
Merge pull request #456 from JakeGinnivan/FailingInheritance
Failing inheritance fixes
2 parents c032ef3 + 6a5d0e1 commit cf893ff

File tree

11 files changed

+117
-39
lines changed

11 files changed

+117
-39
lines changed

GitVersionCore.Tests/Fixtures/EmptyRepositoryFixture.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ public EmptyRepositoryFixture(Config configuration) :
99
{
1010
}
1111

12-
public void DumpGraph()
13-
{
14-
Repository.DumpGraph();
15-
}
16-
1712
static IRepository CreateNewRepository(string path)
1813
{
1914
LibGit2Sharp.Repository.Init(path);

GitVersionCore.Tests/Fixtures/RepositoryFixtureBase.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics;
23
using GitVersion;
34
using LibGit2Sharp;
45
using Shouldly;
@@ -30,7 +31,16 @@ public void AssertFullSemver(string fullSemver, IRepository repository = null, s
3031
gitVersionContext.Configuration.VersioningMode,
3132
gitVersionContext.Configuration.ContinuousDeploymentFallbackTag,
3233
gitVersionContext.IsCurrentCommitTagged);
33-
variables.FullSemVer.ShouldBe(fullSemver);
34+
try
35+
{
36+
variables.FullSemVer.ShouldBe(fullSemver);
37+
}
38+
catch (Exception)
39+
{
40+
Trace.WriteLine("Test failing, dumping repository graph");
41+
repository.DumpGraph();
42+
throw;
43+
}
3444
}
3545

3646
private SemanticVersion ExecuteGitVersion(GitVersionContext context)

GitVersionCore.Tests/Helpers/GitTestExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static void DumpGraph(this IRepository repository)
2020
e => output.AppendLineFormat("ERROR: {0}", e),
2121
null,
2222
"git",
23-
@"log --graph --abbrev-commit --decorate --date=relative --all",
23+
@"log --graph --abbrev-commit --decorate --date=relative --all --remotes=*",
2424
repository.Info.Path);
2525

2626
Trace.Write(output.ToString());

GitVersionCore.Tests/IntegrationTests/FeatureBranchScenarios.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,63 @@
55
[TestFixture]
66
public class FeatureBranchScenarios
77
{
8+
[Test]
9+
public void ShouldInheritIncrementCorrectlyWithMultiplePossibleParentsAndWeirdlyNamedDevelopBranch()
10+
{
11+
using (var fixture = new EmptyRepositoryFixture(new Config()))
12+
{
13+
fixture.Repository.MakeATaggedCommit("1.0.0");
14+
fixture.Repository.CreateBranch("development");
15+
fixture.Repository.Checkout("development");
16+
17+
//Create an initial feature branch
18+
var feature123 = fixture.Repository.CreateBranch("feature/JIRA-123");
19+
fixture.Repository.Checkout("feature/JIRA-123");
20+
fixture.Repository.MakeCommits(1);
21+
22+
//Merge it
23+
fixture.Repository.Checkout("development");
24+
fixture.Repository.Merge(feature123, SignatureBuilder.SignatureNow());
25+
26+
//Create a second feature branch
27+
fixture.Repository.CreateBranch("feature/JIRA-124");
28+
fixture.Repository.Checkout("feature/JIRA-124");
29+
fixture.Repository.MakeCommits(1);
30+
31+
fixture.AssertFullSemver("1.1.0-JIRA-124.1+2");
32+
}
33+
}
34+
35+
[Test]
36+
public void BranchCreatedAfterFastForwardMergeShouldInheritCorrectly()
37+
{
38+
var config = new Config();
39+
config.Branches.Add("unstable", config.Branches["develop"]);
40+
41+
using (var fixture = new EmptyRepositoryFixture(config))
42+
{
43+
fixture.Repository.MakeATaggedCommit("1.0.0");
44+
fixture.Repository.CreateBranch("unstable");
45+
fixture.Repository.Checkout("unstable");
46+
47+
//Create an initial feature branch
48+
var feature123 = fixture.Repository.CreateBranch("feature/JIRA-123");
49+
fixture.Repository.Checkout("feature/JIRA-123");
50+
fixture.Repository.MakeCommits(1);
51+
52+
//Merge it
53+
fixture.Repository.Checkout("unstable");
54+
fixture.Repository.Merge(feature123, SignatureBuilder.SignatureNow());
55+
56+
//Create a second feature branch
57+
fixture.Repository.CreateBranch("feature/JIRA-124");
58+
fixture.Repository.Checkout("feature/JIRA-124");
59+
fixture.Repository.MakeCommits(1);
60+
61+
fixture.AssertFullSemver("1.1.0-JIRA-124.1+2");
62+
}
63+
}
64+
865
[Test]
966
public void ShouldNotUseNumberInFeatureBranchAsPreReleaseNumberOffDevelop()
1067
{

GitVersionCore.Tests/IntegrationTests/PullRequestScenarios.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void CanCalculatePullRequestChanges()
1616

1717
fixture.Repository.CreatePullRequest("feature/Foo", "master");
1818

19-
fixture.DumpGraph();
19+
fixture.Repository.DumpGraph();
2020
fixture.AssertFullSemver("0.1.1-PullRequest.2+2");
2121
}
2222
}
@@ -34,7 +34,7 @@ public void CanCalculatePullRequestChangesInheritingConfig()
3434

3535
fixture.Repository.CreatePullRequest("feature/Foo", "develop", 44);
3636

37-
fixture.DumpGraph();
37+
fixture.Repository.DumpGraph();
3838
fixture.AssertFullSemver("0.2.0-PullRequest.44+3");
3939
}
4040
}
@@ -51,7 +51,7 @@ public void CanCalculatePullRequestChangesFromRemoteRepo()
5151

5252
fixture.Repository.CreatePullRequest("feature/Foo", "master");
5353

54-
fixture.DumpGraph();
54+
fixture.Repository.DumpGraph();
5555
fixture.AssertFullSemver("0.1.1-PullRequest.2+2");
5656
}
5757
}

GitVersionCore.Tests/IntegrationTests/ReleaseBranchScenarios.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,7 @@ public void WhenMergingReleaseBackToDevShouldNotResetBetaVersion()
238238

239239
//but keep working on the release
240240
fixture.Repository.Checkout("release-2.0.0");
241-
242-
fixture.AssertFullSemver("2.0.0-beta.2+3");
241+
fixture.AssertFullSemver("2.0.0-beta.2+2");
243242
}
244243
}
245244
}

GitVersionCore/BranchConfigurationCalculator.cs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class BranchConfigurationCalculator
1010
{
1111
public static KeyValuePair<string, BranchConfig> GetBranchConfiguration(Commit currentCommit, IRepository repository, bool onlyEvaluateTrackedBranches, Config config, Branch currentBranch, IList<Branch> excludedInheritBranches = null)
1212
{
13-
var matchingBranches = config.Branches.Where(b => Regex.IsMatch(currentBranch.Name, "^" + b.Key, RegexOptions.IgnoreCase)).ToArray();
13+
var matchingBranches = LookupBranchConfiguration(config, currentBranch);
1414

1515
if (matchingBranches.Length == 0)
1616
{
@@ -33,6 +33,11 @@ public static KeyValuePair<string, BranchConfig> GetBranchConfiguration(Commit c
3333
throw new Exception(string.Format(format, currentBranch.Name, string.Join(", ", matchingBranches.Select(b => b.Key))));
3434
}
3535

36+
static KeyValuePair<string, BranchConfig>[] LookupBranchConfiguration(Config config, Branch currentBranch)
37+
{
38+
return config.Branches.Where(b => Regex.IsMatch(currentBranch.Name, "^" + b.Key, RegexOptions.IgnoreCase)).ToArray();
39+
}
40+
3641
static KeyValuePair<string, BranchConfig> InheritBranchConfiguration(bool onlyEvaluateTrackedBranches, IRepository repository, Commit currentCommit, Branch currentBranch, KeyValuePair<string, BranchConfig> keyValuePair, BranchConfig branchConfiguration, Config config, IList<Branch> excludedInheritBranches)
3742
{
3843
Logger.WriteInfo("Attempting to inherit branch configuration from parent branch");
@@ -69,34 +74,37 @@ static KeyValuePair<string, BranchConfig> InheritBranchConfiguration(bool onlyEv
6974
}
7075
if (excludedInheritBranches == null)
7176
{
72-
excludedInheritBranches = new List<Branch>();
77+
excludedInheritBranches = repository.Branches.Where(b =>
78+
{
79+
var branchConfig = LookupBranchConfiguration(config, b);
80+
return branchConfig.Length == 1 && branchConfig[0].Value.Increment == IncrementStrategy.Inherit;
81+
}).ToList();
7382
}
7483
excludedBranches.ToList().ForEach(excludedInheritBranches.Add);
7584

76-
var branchPoint = currentBranch.FindCommitBranchWasBranchedFrom(repository, onlyEvaluateTrackedBranches, excludedInheritBranches.ToArray());
85+
var branchPoint = currentBranch.FindCommitBranchWasBranchedFrom(repository, excludedInheritBranches.ToArray());
7786

7887
List<Branch> possibleParents;
79-
if (branchPoint.Sha == currentCommit.Sha)
88+
if (branchPoint == null)
8089
{
8190
possibleParents = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList();
8291
}
8392
else
8493
{
8594
var branches = branchPoint.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList();
86-
var currentTipBranches = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList();
87-
possibleParents = branches
88-
.Except(currentTipBranches)
89-
.ToList();
95+
if (branches.Count > 1)
96+
{
97+
var currentTipBranches = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList();
98+
possibleParents = branches.Except(currentTipBranches).ToList();
99+
}
100+
else
101+
{
102+
possibleParents = branches;
103+
}
90104
}
91105

92106
Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.Name)));
93107

94-
// If it comes down to master and something, master is always first so we pick other branch
95-
if (possibleParents.Count == 2 && possibleParents.Any(p => p.Name == "master"))
96-
{
97-
possibleParents.Remove(possibleParents.Single(p => p.Name == "master"));
98-
}
99-
100108
if (possibleParents.Count == 1)
101109
{
102110
var branchConfig = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, possibleParents[0], excludedInheritBranches).Value;
@@ -117,8 +125,8 @@ static KeyValuePair<string, BranchConfig> InheritBranchConfiguration(bool onlyEv
117125
else
118126
errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.Name));
119127

120-
var hasDevelop = repository.Branches["develop"] != null;
121-
var branchName = hasDevelop ? "develop" : "master";
128+
var developBranch = repository.Branches.FirstOrDefault(b => Regex.IsMatch(b.Name, "^develop", RegexOptions.IgnoreCase));
129+
var branchName = developBranch != null ? developBranch.Name : "master";
122130

123131
Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config");
124132
var value = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, repository.Branches[branchName]).Value;

GitVersionCore/LibGitExtensions.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,25 @@ public static Branch FindBranch(this IRepository repository, string branchName)
2424
return repository.Branches.FirstOrDefault(x => x.Name == "origin/" + branchName);
2525
}
2626

27-
public static Commit FindCommitBranchWasBranchedFrom(this Branch branch, IRepository repository, bool onlyTrackedBranches, params Branch[] excludedBranches)
27+
public static Commit FindCommitBranchWasBranchedFrom(this Branch branch, IRepository repository, params Branch[] excludedBranches)
2828
{
29-
var currentBranches = branch.Tip.GetBranchesContainingCommit(repository, onlyTrackedBranches).ToList();
30-
var tips = repository.Branches.Except(excludedBranches).Where(b => b != branch && !b.IsRemote).Select(b => b.Tip).ToList();
31-
var branchPoint = branch.Commits.FirstOrDefault(c =>
29+
var otherBranches = repository.Branches.Except(excludedBranches).Where(b => IsSameBranch(branch, b)).ToList();
30+
var mergeBases = otherBranches.Select(b =>
3231
{
33-
if (tips.Contains(c)) return true;
34-
var branchesContainingCommit = c.GetBranchesContainingCommit(repository, onlyTrackedBranches).ToList();
35-
return branchesContainingCommit.Count > currentBranches.Count;
36-
});
37-
return branchPoint ?? branch.Tip;
32+
var otherCommit = b.Tip;
33+
if (b.Tip.Parents.Contains(branch.Tip))
34+
{
35+
otherCommit = b.Tip.Parents.First();
36+
}
37+
var mergeBase = repository.Commits.FindMergeBase(otherCommit, branch.Tip);
38+
return mergeBase;
39+
}).Where(b => b != null).ToList();
40+
return mergeBases.OrderByDescending(b => b.Committer.When).FirstOrDefault();
41+
}
42+
43+
static bool IsSameBranch(Branch branch, Branch b)
44+
{
45+
return (b.IsRemote ? b.Name.Replace(b.Remote.Name + "/", string.Empty) : b.Name) != branch.Name;
3846
}
3947

4048
public static IEnumerable<Branch> GetBranchesContainingCommit(this Commit commit, IRepository repository, bool onlyTrackedBranches)

GitVersionCore/VersionCalculation/BaseVersionCalculators/VersionInBranchBaseVersionStrategy.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public override BaseVersion GetVersion(GitVersionContext context)
99
var versionInBranch = GetVersionInBranch(context);
1010
if (versionInBranch != null)
1111
{
12-
var commitBranchWasBranchedFrom = context.CurrentBranch.FindCommitBranchWasBranchedFrom(context.Repository, context.OnlyEvaluateTrackedBranches);
12+
var commitBranchWasBranchedFrom = context.CurrentBranch.FindCommitBranchWasBranchedFrom(context.Repository);
1313
var branchNameOverride = context.CurrentBranch.Name.RegexReplace("[-/]" + versionInBranch.Item1, string.Empty);
1414
return new BaseVersion("Version in branch name", false, versionInBranch.Item2, commitBranchWasBranchedFrom, branchNameOverride);
1515
}

GitVersionCore/VersionCalculation/MetaDataCalculator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public SemanticVersionBuildMetaData Create(Commit baseVersionSource, GitVersionC
1616

1717
var commitLog = context.Repository.Commits.QueryBy(qf);
1818
var commitsSinceTag = commitLog.Count();
19+
Logger.WriteInfo(string.Format("{0} commits found between {1} and {2}", commitsSinceTag, baseVersionSource.Sha, context.CurrentCommit.Sha));
1920

2021
return new SemanticVersionBuildMetaData(
2122
commitsSinceTag,

GitVersionExe.Tests/GitPreparerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public void UpdatesExistingDynamicRepository()
109109

110110
using (var repository = new Repository(dynamicRepositoryPath))
111111
{
112-
mainRepositoryFixture.DumpGraph();
112+
mainRepositoryFixture.Repository.DumpGraph();
113113
repository.DumpGraph();
114114
repository.Commits.ShouldContain(c => c.Sha == newCommit.Sha);
115115
}

0 commit comments

Comments
 (0)