Skip to content

Commit ae26b81

Browse files
authored
Merge pull request #1006 from JakeGinnivan/FixDuplicateKeyException
Fixing exception when forward merging support branches into master wi…
2 parents 2ed1ad7 + e1d7467 commit ae26b81

File tree

3 files changed

+67
-16
lines changed

3 files changed

+67
-16
lines changed

src/GitVersionCore.Tests/IntegrationTests/MainlineDevelopmentMode.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,36 @@ public void VerifyForwardMerge()
160160
fixture.AssertFullSemver(config, "1.0.4-foo.3");
161161
}
162162
}
163+
164+
[Test]
165+
public void VerifySupportForwardMerge()
166+
{
167+
using (var fixture = new EmptyRepositoryFixture())
168+
{
169+
fixture.Repository.MakeACommit("1");
170+
fixture.MakeATaggedCommit("1.0.0");
171+
fixture.MakeACommit(); // 1.0.1
172+
173+
fixture.BranchTo("support/1.0", "support10");
174+
fixture.MakeACommit();
175+
fixture.MakeACommit();
176+
177+
fixture.Checkout("master");
178+
fixture.MakeACommit("+semver: minor");
179+
fixture.AssertFullSemver(config, "1.1.0");
180+
fixture.MergeNoFF("support/1.0");
181+
fixture.AssertFullSemver(config, "1.1.2");
182+
fixture.MakeACommit();
183+
fixture.AssertFullSemver(config, "1.1.3");
184+
fixture.Checkout("support/1.0");
185+
fixture.AssertFullSemver(config, "1.0.4");
186+
187+
fixture.BranchTo("feature/foo", "foo");
188+
fixture.MakeACommit();
189+
fixture.MakeACommit();
190+
fixture.AssertFullSemver(config, "1.0.4-foo.2"); // TODO This probably should be 1.0.5
191+
}
192+
}
163193
}
164194

165195
static class CommitExtensions

src/GitVersionCore/BranchConfigurationCalculator.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,11 @@ static KeyValuePair<string, BranchConfig> InheritBranchConfiguration(bool onlyEv
131131
var chosenBranch = repository.Branches.FirstOrDefault(b => Regex.IsMatch(b.FriendlyName, "^develop", RegexOptions.IgnoreCase)
132132
|| Regex.IsMatch(b.FriendlyName, "master$", RegexOptions.IgnoreCase));
133133
if (chosenBranch == null)
134+
{
135+
// TODO We should call the build server to generate this exception, each build server works differently
136+
// for fetch issues and we could give better warnings.
134137
throw new InvalidOperationException("Could not find a 'develop' or 'master' branch, neither locally nor remotely.");
138+
}
135139

136140
var branchName = chosenBranch.FriendlyName;
137141
Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config");

src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -166,27 +166,44 @@ static Commit GetMainlineTip(GitVersionContext context)
166166
{
167167
var mainlineBranchConfigs = context.FullConfiguration.Branches.Where(b => b.Value.IsMainline == true).ToList();
168168
var seenMainlineTips = new List<string>();
169-
var mainlineBranches = context.Repository.Branches.Where(b =>
170-
{
171-
return mainlineBranchConfigs.Any(c => Regex.IsMatch(b.FriendlyName, c.Key));
172-
}).Where(b =>
173-
{
174-
if (seenMainlineTips.Contains(b.Tip.Sha))
169+
var mainlineBranches = context.Repository.Branches
170+
.Where(b =>
175171
{
176-
Logger.WriteInfo("Multiple possible mainlines pointing at the same commit, dropping " + b.FriendlyName);
177-
return false;
178-
}
179-
seenMainlineTips.Add(b.Tip.Sha);
180-
return true;
181-
}).ToDictionary(b => context.Repository.ObjectDatabase.FindMergeBase(b.Tip, context.CurrentCommit).Sha, b => b);
182-
Logger.WriteInfo("Found possible mainline branches: " + string.Join(", ", mainlineBranches.Values.Select(b => b.FriendlyName)));
172+
return mainlineBranchConfigs.Any(c => Regex.IsMatch(b.FriendlyName, c.Key));
173+
})
174+
.Where(b =>
175+
{
176+
if (seenMainlineTips.Contains(b.Tip.Sha))
177+
{
178+
Logger.WriteInfo("Multiple possible mainlines pointing at the same commit, dropping " + b.FriendlyName);
179+
return false;
180+
}
181+
seenMainlineTips.Add(b.Tip.Sha);
182+
return true;
183+
})
184+
.GroupBy(b => context.Repository.ObjectDatabase.FindMergeBase(b.Tip, context.CurrentCommit).Sha)
185+
.ToDictionary(b => b.Key, b => b.ToList());
186+
187+
var allMainlines = mainlineBranches.Values.SelectMany(branches => branches.Select(b => b.FriendlyName));
188+
Logger.WriteInfo("Found possible mainline branches: " + string.Join(", ", allMainlines));
183189

184190
// Find closest mainline branch
185191
var firstMatchingCommit = context.CurrentBranch.Commits.First(c => mainlineBranches.ContainsKey(c.Sha));
186-
var mainlineBranch = mainlineBranches[firstMatchingCommit.Sha];
187-
Logger.WriteInfo("Mainline for current branch is " + mainlineBranch.FriendlyName);
192+
var possibleMainlineBranches = mainlineBranches[firstMatchingCommit.Sha];
193+
194+
if (possibleMainlineBranches.Count == 1)
195+
{
196+
var mainlineBranch = possibleMainlineBranches[0];
197+
Logger.WriteInfo("Mainline for current branch is " + mainlineBranch.FriendlyName);
198+
return mainlineBranch.Tip;
199+
}
188200

189-
return mainlineBranch.Tip;
201+
var chosenMainline = possibleMainlineBranches[0];
202+
Logger.WriteInfo(string.Format(
203+
"Multiple mainlines ({0}) have the same merge base for the current branch, choosing {1} because we found that branch first...",
204+
string.Join(", ", possibleMainlineBranches.Select(b => b.FriendlyName)),
205+
chosenMainline.FriendlyName));
206+
return chosenMainline.Tip;
190207
}
191208

192209
private static SemanticVersion IncrementForEachCommit(GitVersionContext context, List<Commit> directCommits, SemanticVersion mainlineVersion)

0 commit comments

Comments
 (0)