diff --git a/src/GitVersionCore.Tests/GitRepoInformation/QueryRequirements.cs b/src/GitVersionCore.Tests/GitRepoInformation/QueryRequirements.cs
new file mode 100644
index 0000000000..1665237d10
--- /dev/null
+++ b/src/GitVersionCore.Tests/GitRepoInformation/QueryRequirements.cs
@@ -0,0 +1,33 @@
+using GitTools;
+using GitTools.Testing;
+using GitVersion;
+using GitVersion.GitRepoInformation;
+using NUnit.Framework;
+using Shouldly;
+using System;
+
+[TestFixture]
+public class QueryRequirements
+{
+ [Test]
+ public void ListsAllMergeCommits()
+ {
+ var config = new Config();
+ ConfigurationProvider.ApplyDefaultsTo(config);
+ using (var fixture = new EmptyRepositoryFixture())
+ {
+ fixture.MakeACommit();
+ fixture.MakeACommit();
+ fixture.BranchTo("feature/foo");
+ fixture.MakeACommit();
+ fixture.Checkout("master");
+ fixture.MergeNoFF("feature/foo");
+
+ fixture.Repository.DumpGraph();
+
+ var metadata = Libgit2RepoMetadataProvider.ReadMetadata(new GitVersionContext(fixture.Repository, config));
+
+ metadata.CurrentBranch.MergeMessages.Count.ShouldBe(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/GitVersionCore.Tests/GitVersionContextBuilder.cs b/src/GitVersionCore.Tests/GitVersionContextBuilder.cs
index 85bd100906..7d60b9a993 100644
--- a/src/GitVersionCore.Tests/GitVersionContextBuilder.cs
+++ b/src/GitVersionCore.Tests/GitVersionContextBuilder.cs
@@ -74,7 +74,8 @@ IRepository CreateRepository()
mockBranch
},
Tags = new MockTagCollection(),
- Head = mockBranch
+ Head = mockBranch,
+ ObjectDatabase = new MockObjectDatabase()
};
return mockRepository;
diff --git a/src/GitVersionCore.Tests/GitVersionContextTests.cs b/src/GitVersionCore.Tests/GitVersionContextTests.cs
index d095ae6208..965a754cf3 100644
--- a/src/GitVersionCore.Tests/GitVersionContextTests.cs
+++ b/src/GitVersionCore.Tests/GitVersionContextTests.cs
@@ -22,6 +22,7 @@ public void CanInheritVersioningMode(VersioningMode mode)
var mockBranch = new MockBranch("master") { new MockCommit { CommitterEx = Generate.SignatureNow() } };
var mockRepository = new MockRepository
{
+ Head = mockBranch,
Branches = new MockBranchCollection
{
mockBranch
@@ -81,6 +82,7 @@ public void UsesBranchSpecificConfigOverTopLevelDefaults()
var develop = new MockBranch("develop") { new MockCommit { CommitterEx = Generate.SignatureNow() } };
var mockRepository = new MockRepository
{
+ Head = develop,
Branches = new MockBranchCollection
{
new MockBranch("master") { new MockCommit { CommitterEx = Generate.SignatureNow() } },
@@ -109,6 +111,7 @@ public void UsesFirstBranchConfigWhenMultipleMatch()
var mockRepository = new MockRepository
{
+ Head = releaseLatestBranch,
Branches = new MockBranchCollection
{
releaseLatestBranch,
diff --git a/src/GitVersionCore.Tests/GitVersionCore.Tests.csproj b/src/GitVersionCore.Tests/GitVersionCore.Tests.csproj
index a3c44e6cc2..c5e1406560 100644
--- a/src/GitVersionCore.Tests/GitVersionCore.Tests.csproj
+++ b/src/GitVersionCore.Tests/GitVersionCore.Tests.csproj
@@ -1,5 +1,6 @@
+
@@ -58,9 +59,8 @@
..\packages\NSubstitute.1.10.0.0\lib\net45\NSubstitute.dll
True
-
- ..\packages\NUnit.3.6.0\lib\net45\nunit.framework.dll
- True
+
+ ..\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll
..\packages\Shouldly.2.7.0\lib\net40\Shouldly.dll
@@ -94,6 +94,7 @@
+
@@ -103,6 +104,7 @@
+
@@ -190,6 +192,7 @@
+
\ No newline at end of file
diff --git a/src/GitVersionCore.Tests/IntegrationTests/OtherScenarios.cs b/src/GitVersionCore.Tests/IntegrationTests/OtherScenarios.cs
index 4ebda3317b..4d39544131 100644
--- a/src/GitVersionCore.Tests/IntegrationTests/OtherScenarios.cs
+++ b/src/GitVersionCore.Tests/IntegrationTests/OtherScenarios.cs
@@ -6,6 +6,7 @@
using LibGit2Sharp;
using NUnit.Framework;
using System.Collections.Generic;
+ using System;
[TestFixture]
public class OtherScenarios
@@ -91,5 +92,28 @@ public void DoNotBlowUpWhenDevelopAndFeatureBranchPointAtSameCommit()
fixture.AssertFullSemver("1.1.0-alpha.1");
}
}
+
+ [Test]
+ public void AllowUnrelatedBranchesInRepo()
+ {
+ // This test unsures we handle when GitVersion cannot find mergebases etc
+ using (var fixture = new EmptyRepositoryFixture())
+ {
+ fixture.Repository.MakeACommit();
+ fixture.Repository.MakeACommit();
+
+ // Create a new root commit and then a branch pointing at that commit
+ var treeDefinition = new TreeDefinition();
+ var tree = fixture.Repository.ObjectDatabase.CreateTree(treeDefinition);
+ var commit = fixture.Repository.ObjectDatabase.CreateCommit(
+ new Signature("name", "mail", DateTimeOffset.Now),
+ new Signature("name", "mail", DateTimeOffset.Now),
+ "Create new empty branch",
+ tree, new Commit[0], false);
+ fixture.Repository.Branches.Add("gh-pages", commit);
+
+ fixture.AssertFullSemver("0.1.0+1");
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/GitVersionCore.Tests/MockObjectDatabase.cs b/src/GitVersionCore.Tests/MockObjectDatabase.cs
new file mode 100644
index 0000000000..416cf7503f
--- /dev/null
+++ b/src/GitVersionCore.Tests/MockObjectDatabase.cs
@@ -0,0 +1,9 @@
+using LibGit2Sharp;
+
+public class MockObjectDatabase : ObjectDatabase
+{
+ public override Commit FindMergeBase(Commit first, Commit second)
+ {
+ return second;
+ }
+}
\ No newline at end of file
diff --git a/src/GitVersionCore.Tests/Mocks/MockRepository.cs b/src/GitVersionCore.Tests/Mocks/MockRepository.cs
index 33e8709a4d..4f21deacf9 100644
--- a/src/GitVersionCore.Tests/Mocks/MockRepository.cs
+++ b/src/GitVersionCore.Tests/Mocks/MockRepository.cs
@@ -10,6 +10,7 @@ public MockRepository()
{
Tags = new MockTagCollection();
Refs = new MockReferenceCollection();
+ ObjectDatabase = new MockObjectDatabase();
}
public void Dispose()
diff --git a/src/GitVersionCore.Tests/VersionCalculation/Strategies/MergeMessageBaseVersionStrategyTests.cs b/src/GitVersionCore.Tests/VersionCalculation/Strategies/MergeMessageBaseVersionStrategyTests.cs
index 6890b1080f..cc7f2b50be 100644
--- a/src/GitVersionCore.Tests/VersionCalculation/Strategies/MergeMessageBaseVersionStrategyTests.cs
+++ b/src/GitVersionCore.Tests/VersionCalculation/Strategies/MergeMessageBaseVersionStrategyTests.cs
@@ -17,11 +17,15 @@ public void ShouldNotAllowIncrementOfVersion()
// So we shouldn't bump the version
var context = new GitVersionContextBuilder().WithRepository(new MockRepository
{
- Head = new MockBranch("master") { new MockCommit
+ Head = new MockBranch("master")
{
- MessageEx = "Merge branch 'hotfix-0.1.5'",
- ParentsEx = GetParents(true)
- } }
+ new MockCommit
+ {
+ MessageEx = "Merge branch 'hotfix-0.1.5'",
+ ParentsEx = GetParents(true)
+ }
+ },
+ Branches = new MockBranchCollection()
}).Build();
var sut = new MergeMessageBaseVersionStrategy();
@@ -108,7 +112,8 @@ static void AssertMergeMessage(string message, string expectedVersion, List
-
-
+
+
diff --git a/src/GitVersionCore/GitRepoInformation/GitRepoMetadata.cs b/src/GitVersionCore/GitRepoInformation/GitRepoMetadata.cs
new file mode 100644
index 0000000000..aa1708920b
--- /dev/null
+++ b/src/GitVersionCore/GitRepoInformation/GitRepoMetadata.cs
@@ -0,0 +1,76 @@
+using System.Collections.Generic;
+
+namespace GitVersion.GitRepoInformation
+{
+ public class GitRepoMetadata
+ {
+ public GitRepoMetadata(
+ List tags, MBranch currentBranch, MBranch master,
+ List releaseBranches)
+ {
+ Tags = tags;
+ MasterBranch = master;
+ CurrentBranch = currentBranch;
+ ReleaseBranches = releaseBranches;
+ }
+
+ // Wonder if this can be 'mainline'
+ public MBranch MasterBranch { get; }
+ public List ReleaseBranches { get; }
+ public MBranch CurrentBranch { get; }
+ public List Tags { get; private set; }
+ }
+
+ public class MTag
+ {
+ public MTag(string sha, string friendlyName, Config config, bool createdAfterHead)
+ {
+ Sha = sha;
+ Name = friendlyName;
+ CreatedAfterHead = createdAfterHead;
+ SemanticVersion version;
+ if (SemanticVersion.TryParse(friendlyName, config.TagPrefix, out version))
+ {
+ Version = version;
+ }
+ }
+
+ public string Sha { get; }
+ public string Name { get; }
+ public bool CreatedAfterHead { get; }
+ public SemanticVersion Version { get; }
+ }
+
+ public class MBranch
+ {
+ public MBranch(
+ string name,
+ string tipSha,
+ MParent parent,
+ List tags,
+ List mergeMessages)
+ {
+ Name = name;
+ TipSha = tipSha;
+ Parent = parent;
+ MergeMessages = mergeMessages;
+ Tags = tags;
+ }
+
+ public string Name { get; }
+ public string TipSha { get; }
+ public MParent Parent { get; }
+ public List MergeMessages { get; }
+ public List Tags { get; }
+ }
+
+ public class MParent
+ {
+ public MParent(string mergeBase)
+ {
+ MergeBase = mergeBase;
+ }
+
+ public string MergeBase { get; }
+ }
+}
diff --git a/src/GitVersionCore/GitRepoMetadataProvider.cs b/src/GitVersionCore/GitRepoInformation/GitRepoMetadataProvider.cs
similarity index 84%
rename from src/GitVersionCore/GitRepoMetadataProvider.cs
rename to src/GitVersionCore/GitRepoInformation/GitRepoMetadataProvider.cs
index 9927ed899d..b3096ae49b 100644
--- a/src/GitVersionCore/GitRepoMetadataProvider.cs
+++ b/src/GitVersionCore/GitRepoInformation/GitRepoMetadataProvider.cs
@@ -9,7 +9,7 @@ namespace GitVersion
public class GitRepoMetadataProvider
{
private Dictionary> mergeBaseCommitsCache;
- private Dictionary, MergeBaseData> mergeBaseCache;
+ private Dictionary, MergeBaseData> mergeBaseCache;
private Dictionary> semanticVersionTagsOnBranchCache;
private IRepository Repository { get; set; }
const string missingTipFormat = "{0} has no tip. Please see http://example.com/docs for information on how to fix this.";
@@ -17,7 +17,7 @@ public class GitRepoMetadataProvider
public GitRepoMetadataProvider(IRepository repository, Config configuration)
{
- mergeBaseCache = new Dictionary, MergeBaseData>();
+ mergeBaseCache = new Dictionary, MergeBaseData>();
mergeBaseCommitsCache = new Dictionary>();
semanticVersionTagsOnBranchCache = new Dictionary>();
Repository = repository;
@@ -110,22 +110,36 @@ public IEnumerable GetBranchesContainingCommit(Commit commit, IList
public Commit FindMergeBase(Branch branch, Branch otherBranch)
{
- var key = Tuple.Create(branch, otherBranch);
+ return FindMergeBase(branch.Tip.Sha, otherBranch.Tip.Sha, branch.FriendlyName, otherBranch.FriendlyName);
+ }
+
+ ///
+ /// Find the merge base of the two branches, i.e. the best common ancestor of the two branches' tips.
+ ///
+ public Commit FindMergeBase(string sha1, string sha2, string sha1Desc = null, string sha2Desc = null)
+ {
+ var key = Tuple.Create(sha1, sha2);
+ var source1 = Repository.Lookup(sha1);
+ var source2 = Repository.Lookup(sha2);
+ var sha1Name = sha1Desc ?? sha1;
+ var sha2Name = sha2Desc ?? sha2;
if (mergeBaseCache.ContainsKey(key))
{
- Logger.WriteDebug($"Cache hit for merge base between '{branch.FriendlyName}' and '{otherBranch.FriendlyName}'.");
- return mergeBaseCache[key].MergeBase;
+ Logger.WriteDebug($"Cache hit for merge base between '{sha1Name}' and '{sha2Name}'.");
+ var mergeBase = mergeBaseCache[key].MergeBase;
+ if (mergeBase == null) { return null; }
+ return Repository.Lookup(mergeBase);
}
- using (Logger.IndentLog($"Finding merge base between '{branch.FriendlyName}' and '{otherBranch.FriendlyName}'."))
+ using (Logger.IndentLog($"Finding merge base between '{sha1Name}' and '{sha2Name}'."))
{
- // Otherbranch tip is a forward merge
- var commitToFindCommonBase = otherBranch.Tip;
- var commit = branch.Tip;
- if (otherBranch.Tip.Parents.Contains(commit))
+ // source2 is a forward merge (Jake: I have no idea what this means right now....)
+ var commitToFindCommonBase = source2;
+ var commit = source1;
+ if (source2.Parents.Contains(commit))
{
- commitToFindCommonBase = otherBranch.Tip.Parents.First();
+ commitToFindCommonBase = source2.Parents.First();
}
var findMergeBase = Repository.ObjectDatabase.FindMergeBase(commit, commitToFindCommonBase);
@@ -172,9 +186,9 @@ public Commit FindMergeBase(Branch branch, Branch otherBranch)
}
// Store in cache.
- mergeBaseCache.Add(key, new MergeBaseData(branch, otherBranch, Repository, findMergeBase));
+ mergeBaseCache.Add(key, new MergeBaseData(sha1, sha2, findMergeBase == null ? null : findMergeBase.Sha));
- Logger.WriteInfo($"Merge base of {branch.FriendlyName}' and '{otherBranch.FriendlyName} is {findMergeBase}");
+ Logger.WriteInfo($"Merge base of {sha1Name}' and '{sha2Name} is {findMergeBase}");
return findMergeBase;
}
}
@@ -198,7 +212,7 @@ public BranchCommit FindCommitBranchWasBranchedFrom(Branch branch, params Branch
return BranchCommit.Empty;
}
- var possibleBranches = GetMergeCommitsForBranch(branch)
+ var possibleBranches = GetMergeBasesForBranch(branch)
.ExcludingBranches(excludedBranches)
.Where(b => !branch.IsSameBranch(b.Branch))
.ToList();
@@ -216,7 +230,7 @@ public BranchCommit FindCommitBranchWasBranchedFrom(Branch branch, params Branch
}
}
- List GetMergeCommitsForBranch(Branch branch)
+ List GetMergeBasesForBranch(Branch branch)
{
if (mergeBaseCommitsCache.ContainsKey(branch))
{
@@ -259,17 +273,15 @@ List GetMergeCommitsForBranch(Branch branch)
private class MergeBaseData
{
- public Branch Branch { get; private set; }
- public Branch OtherBranch { get; private set; }
- public IRepository Repository { get; private set; }
+ public string Sha1 { get; private set; }
+ public string Sha2 { get; private set; }
- public Commit MergeBase { get; private set; }
+ public string MergeBase { get; private set; }
- public MergeBaseData(Branch branch, Branch otherBranch, IRepository repository, Commit mergeBase)
+ public MergeBaseData(string sha1, string sha2, string mergeBase)
{
- Branch = branch;
- OtherBranch = otherBranch;
- Repository = repository;
+ Sha1 = sha1;
+ Sha2 = sha2;
MergeBase = mergeBase;
}
}
diff --git a/src/GitVersionCore/GitRepoInformation/Libgit2RepoMetadataProvider.cs b/src/GitVersionCore/GitRepoInformation/Libgit2RepoMetadataProvider.cs
new file mode 100644
index 0000000000..118f675b76
--- /dev/null
+++ b/src/GitVersionCore/GitRepoInformation/Libgit2RepoMetadataProvider.cs
@@ -0,0 +1,87 @@
+using LibGit2Sharp;
+using System.Collections.Generic;
+using System.Linq;
+using System;
+using System.Text.RegularExpressions;
+
+namespace GitVersion.GitRepoInformation
+{
+ public class Libgit2RepoMetadataProvider
+ {
+ public static GitRepoMetadata ReadMetadata(GitVersionContext context)
+ {
+ var tags = ReadRepoTags(context);
+ var currentBranchInfo = ReadBranchInfo(context, context.CurrentBranch, context.CurrentCommit, tags);
+ var releaseBranches = ReadReleaseBranches(context, tags);
+ var masterBranch = context.Repository.Branches["master"];
+ var masterBranchInfo = masterBranch != null ? ReadBranchInfo(context, masterBranch, masterBranch.Tip, tags) : null;
+ return new GitRepoMetadata(
+ tags,
+ currentBranchInfo,
+ masterBranchInfo,
+ releaseBranches);
+ }
+
+ private static List ReadReleaseBranches(GitVersionContext context, List allTags)
+ {
+ var releaseBranchConfig = context.FullConfiguration.Branches
+ .Where(b => b.Value.IsReleaseBranch == true)
+ .ToList();
+
+ return context.Repository
+ .Branches
+ .Where(b => releaseBranchConfig.Any(c => Regex.IsMatch(b.FriendlyName, c.Key)))
+ .Select(b => ReadBranchInfo(context, b, b.Tip, allTags))
+ .ToList();
+ }
+
+ private static List ReadRepoTags(GitVersionContext context)
+ {
+ var olderThan = context.CurrentCommit.When();
+ return context.Repository
+ .Tags
+ .Where(tag =>
+ {
+ var commit = tag.PeeledTarget() as Commit;
+ return commit != null;
+ })
+ .Select(gitTag =>
+ {
+ var commit = gitTag.PeeledTarget() as Commit;
+ if (commit == null) return null;
+
+ return new MTag(gitTag.Target.Sha, gitTag.FriendlyName, context.FullConfiguration, commit.When() > olderThan);
+ })
+ .Where(t => t != null)
+ .ToList();
+ }
+
+ private static MBranch ReadBranchInfo(GitVersionContext context, Branch branch, Commit at, List allTags)
+ {
+ var filter = new CommitFilter
+ {
+ IncludeReachableFrom = at ?? branch.Tip
+ };
+
+ var mergeMessages = new List();
+ var branchTags = new List();
+ var commits = context.Repository.Commits.QueryBy(filter);
+ foreach (var branchCommit in commits)
+ {
+ if (branchCommit.Parents.Count() >= 2)
+ {
+ mergeMessages.Add(new MergeMessage(branchCommit.Message, branchCommit.Sha, context.FullConfiguration));
+ }
+
+ // Adding range because the same commit may have two tags
+ branchTags.AddRange(allTags.Where(t => t.Sha == branchCommit.Sha));
+ }
+
+ var parentCommit = context.RepositoryMetadataProvider.FindCommitBranchWasBranchedFrom(branch);
+ var parent = parentCommit == null || parentCommit.Commit == null
+ ? null
+ : new MParent(parentCommit.Commit.Sha);
+ return new MBranch(branch.FriendlyName, at.Sha, parent, branchTags, mergeMessages);
+ }
+ }
+}
diff --git a/src/GitVersionCore/GitVersionContext.cs b/src/GitVersionCore/GitVersionContext.cs
index 27cd14f527..4aa87d45de 100644
--- a/src/GitVersionCore/GitVersionContext.cs
+++ b/src/GitVersionCore/GitVersionContext.cs
@@ -1,5 +1,6 @@
namespace GitVersion
{
+ using GitVersion.GitRepoInformation;
using LibGit2Sharp;
using System;
using System.Linq;
@@ -66,6 +67,7 @@ public GitVersionContext(IRepository repository, Branch currentBranch, Config co
})
.Max();
IsCurrentCommitTagged = CurrentCommitTaggedVersion != null;
+ RepositoryMetadata = Libgit2RepoMetadataProvider.ReadMetadata(this);
}
///
@@ -80,6 +82,13 @@ public GitVersionContext(IRepository repository, Branch currentBranch, Config co
public Commit CurrentCommit { get; private set; }
public bool IsCurrentCommitTagged { get; private set; }
public GitRepoMetadataProvider RepositoryMetadataProvider { get; private set; }
+ ///
+ /// This is a new concept which is static metadata
+ /// It has no runtime dependencies on libgit2 and all information is pre-calculated.
+ /// We should move to use this, that way libgit2 is used when bootstrapping
+ /// this will be far easier to optimise then all the logic for gitversion will be entirely in memory
+ ///
+ public GitRepoMetadata RepositoryMetadata { get; private set; }
void CalculateEffectiveConfiguration()
{
diff --git a/src/GitVersionCore/GitVersionCore.csproj b/src/GitVersionCore/GitVersionCore.csproj
index fea4f65af9..6f99e45bf2 100644
--- a/src/GitVersionCore/GitVersionCore.csproj
+++ b/src/GitVersionCore/GitVersionCore.csproj
@@ -115,7 +115,9 @@
-
+
+
+
@@ -134,6 +136,7 @@
+
@@ -147,7 +150,6 @@
-
diff --git a/src/GitVersionCore/MergeMessage.cs b/src/GitVersionCore/MergeMessage.cs
index 1dd5ecc3ac..8acb60d54d 100644
--- a/src/GitVersionCore/MergeMessage.cs
+++ b/src/GitVersionCore/MergeMessage.cs
@@ -4,7 +4,7 @@
namespace GitVersion
{
- class MergeMessage
+ public class MergeMessage
{
static Regex parseMergeMessage = new Regex(
@"^Merge (branch|tag) '(?[^']*)'",
@@ -15,12 +15,12 @@ class MergeMessage
static Regex smartGitMergeMessage = new Regex(
@"^Finish (?.*)",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
- private string mergeMessage;
private Config config;
- public MergeMessage(string mergeMessage, Config config)
+ public MergeMessage(string mergeMessage, string sourceCommitSha, Config config)
{
- this.mergeMessage = mergeMessage;
+ Message = mergeMessage;
+ SourceCommitSha = sourceCommitSha;
this.config = config;
var lastIndexOf = mergeMessage.LastIndexOf("into", StringComparison.OrdinalIgnoreCase);
@@ -51,19 +51,19 @@ public MergeMessage(string mergeMessage, Config config)
private string ParseBranch()
{
- var match = parseMergeMessage.Match(mergeMessage);
+ var match = parseMergeMessage.Match(Message);
if (match.Success)
{
return match.Groups["Branch"].Value;
}
- match = smartGitMergeMessage.Match(mergeMessage);
+ match = smartGitMergeMessage.Match(Message);
if (match.Success)
{
return match.Groups["Branch"].Value;
}
- match = parseGitHubPullMergeMessage.Match(mergeMessage);
+ match = parseGitHubPullMergeMessage.Match(Message);
if (match.Success)
{
IsMergedPullRequest = true;
@@ -80,10 +80,12 @@ private string ParseBranch()
return "";
}
+ public string Message { get; }
public string TargetBranch { get; }
public string MergedBranch { get; }
public bool IsMergedPullRequest { get; private set; }
public int? PullRequestNumber { get; private set; }
public SemanticVersion Version { get; }
+ public string SourceCommitSha { get; private set; }
}
}
diff --git a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/MergeMessageBaseVersionStrategy.cs b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/MergeMessageBaseVersionStrategy.cs
index e9fac9c84c..e3fa106c5c 100644
--- a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/MergeMessageBaseVersionStrategy.cs
+++ b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/MergeMessageBaseVersionStrategy.cs
@@ -13,40 +13,16 @@ public class MergeMessageBaseVersionStrategy : BaseVersionStrategy
{
public override IEnumerable GetVersions(GitVersionContext context)
{
- var commitsPriorToThan = context.CurrentBranch
- .CommitsPriorToThan(context.CurrentCommit.When());
- var baseVersions = commitsPriorToThan
- .SelectMany(c =>
+ return context
+ .RepositoryMetadata
+ .CurrentBranch
+ .MergeMessages
+ .Where(m => m.Version != null)
+ .Select(m =>
{
- SemanticVersion semanticVersion;
- if (TryParse(c, context, out semanticVersion))
- {
- var shouldIncrement = !context.Configuration.PreventIncrementForMergedBranchVersion;
- return new[]
- {
- new BaseVersion(context, string.Format("Merge message '{0}'", c.Message.Trim()), shouldIncrement, semanticVersion, c, null)
- };
- }
- return Enumerable.Empty();
- }).ToList();
- return baseVersions;
- }
-
- static bool TryParse(Commit mergeCommit, GitVersionContext context, out SemanticVersion semanticVersion)
- {
- semanticVersion = Inner(mergeCommit, context);
- return semanticVersion != null;
- }
-
- static SemanticVersion Inner(Commit mergeCommit, GitVersionContext context)
- {
- if (mergeCommit.Parents.Count() < 2)
- {
- return null;
- }
-
- var mergeMessage = new MergeMessage(mergeCommit.Message, context.FullConfiguration);
- return mergeMessage.Version;
+ var shouldIncrement = !context.Configuration.PreventIncrementForMergedBranchVersion;
+ return new BaseVersion(context, string.Format("Merge message '{0}'", m.Message.Trim()), shouldIncrement, m.Version, context.Repository.Lookup(m.SourceCommitSha), null);
+ });
}
}
}
\ No newline at end of file
diff --git a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/TaggedCommitVersionStrategy.cs b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/TaggedCommitVersionStrategy.cs
index 4955be0203..c22301fd8f 100644
--- a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/TaggedCommitVersionStrategy.cs
+++ b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/TaggedCommitVersionStrategy.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using LibGit2Sharp;
+ using GitVersion.GitRepoInformation;
///
/// Version is extracted from all tags on the branch which are valid, and not newer than the current commit.
@@ -14,63 +15,21 @@ public class TaggedCommitVersionStrategy : BaseVersionStrategy
{
public override IEnumerable GetVersions(GitVersionContext context)
{
- return GetTaggedVersions(context, context.CurrentBranch, context.CurrentCommit.When());
+ return GetTaggedVersions(context, context.RepositoryMetadata.CurrentBranch);
}
- public IEnumerable GetTaggedVersions(GitVersionContext context, Branch currentBranch, DateTimeOffset? olderThan)
+ public IEnumerable GetTaggedVersions(GitVersionContext context, MBranch currentBranch)
{
- var allTags = context.Repository.Tags
- .Where(tag => !olderThan.HasValue || ((Commit) tag.PeeledTarget()).When() <= olderThan.Value)
- .ToList();
- var tagsOnBranch = currentBranch
- .Commits
- .SelectMany(commit => { return allTags.Where(t => IsValidTag(t, commit)); })
- .Select(t =>
- {
- SemanticVersion version;
- if (SemanticVersion.TryParse(t.FriendlyName, context.Configuration.GitTagPrefix, out version))
- {
- var commit = t.PeeledTarget() as Commit;
- if (commit != null)
- return new VersionTaggedCommit(commit, version, t.FriendlyName);
- }
- return null;
- })
- .Where(a => a != null)
- .ToList();
-
- return tagsOnBranch.Select(t => CreateBaseVersion(context, t));
- }
-
- BaseVersion CreateBaseVersion(GitVersionContext context, VersionTaggedCommit version)
- {
- var shouldUpdateVersion = version.Commit.Sha != context.CurrentCommit.Sha;
- var baseVersion = new BaseVersion(context, FormatSource(version), shouldUpdateVersion, version.SemVer, version.Commit, null);
- return baseVersion;
+ return currentBranch
+ .Tags
+ .Where(t => t.Version != null)
+ .Select(t => CreateBaseVersion(context, t));
}
- protected virtual string FormatSource(VersionTaggedCommit version)
+ BaseVersion CreateBaseVersion(GitVersionContext context, MTag tag)
{
- return string.Format("Git tag '{0}'", version.Tag);
- }
-
- protected virtual bool IsValidTag(Tag tag, Commit commit)
- {
- return tag.PeeledTarget() == commit;
- }
-
- protected class VersionTaggedCommit
- {
- public string Tag;
- public Commit Commit;
- public SemanticVersion SemVer;
-
- public VersionTaggedCommit(Commit commit, SemanticVersion semVer, string tag)
- {
- Tag = tag;
- Commit = commit;
- SemVer = semVer;
- }
+ var shouldUpdateVersion = tag.Sha != context.CurrentCommit.Sha;
+ return new BaseVersion(context, $"Git tag '{tag.Name}'", shouldUpdateVersion, tag.Version, context.Repository.Lookup(tag.Sha), null);
}
}
}
\ No newline at end of file
diff --git a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/VersionInBranchNameBaseVersionStrategy.cs b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/VersionInBranchNameBaseVersionStrategy.cs
index db2546e06a..59959cf4d5 100644
--- a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/VersionInBranchNameBaseVersionStrategy.cs
+++ b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/VersionInBranchNameBaseVersionStrategy.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using LibGit2Sharp;
+ using GitVersion.GitRepoInformation;
///
/// Version is extracted from the name of the branch.
@@ -13,21 +14,21 @@ public class VersionInBranchNameBaseVersionStrategy : BaseVersionStrategy
{
public override IEnumerable GetVersions(GitVersionContext context)
{
- var currentBranch = context.CurrentBranch;
+ var currentBranch = context.RepositoryMetadata.CurrentBranch;
var tagPrefixRegex = context.Configuration.GitTagPrefix;
var repository = context.Repository;
return GetVersions(context, tagPrefixRegex, currentBranch, repository);
}
- public IEnumerable GetVersions(GitVersionContext context, string tagPrefixRegex, Branch currentBranch, IRepository repository)
+ public IEnumerable GetVersions(GitVersionContext context, string tagPrefixRegex, MBranch currentBranch, IRepository repository)
{
- var branchName = currentBranch.FriendlyName;
+ var branchName = currentBranch.Name;
var versionInBranch = GetVersionInBranch(branchName, tagPrefixRegex);
if (versionInBranch != null)
{
- var commitBranchWasBranchedFrom = context.RepositoryMetadataProvider.FindCommitBranchWasBranchedFrom(currentBranch);
var branchNameOverride = branchName.RegexReplace("[-/]" + versionInBranch.Item1, string.Empty);
- yield return new BaseVersion(context, "Version in branch name", false, versionInBranch.Item2, commitBranchWasBranchedFrom.Commit, branchNameOverride);
+ var baseCommit = repository.Lookup(currentBranch.Parent.MergeBase);
+ yield return new BaseVersion(context, "Version in branch name", false, versionInBranch.Item2, baseCommit, branchNameOverride);
}
}
diff --git a/src/GitVersionCore/VersionCalculation/MainlineVersionCalculator.cs b/src/GitVersionCore/VersionCalculation/MainlineVersionCalculator.cs
index 4d27c77d79..fd5d871213 100644
--- a/src/GitVersionCore/VersionCalculation/MainlineVersionCalculator.cs
+++ b/src/GitVersionCore/VersionCalculation/MainlineVersionCalculator.cs
@@ -199,7 +199,7 @@ private static VersionField TryFindIncrementFromMergeMessage(Commit mergeCommit,
{
if (mergeCommit != null)
{
- var mergeMessage = new MergeMessage(mergeCommit.Message, context.FullConfiguration);
+ var mergeMessage = new MergeMessage(mergeCommit.Message, mergeCommit.Sha, context.FullConfiguration);
if (mergeMessage.MergedBranch != null)
{
var config = context.FullConfiguration.GetConfigForBranch(mergeMessage.MergedBranch);
diff --git a/src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs b/src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs
index 3cb2a5e145..0385b1651e 100644
--- a/src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs
+++ b/src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs
@@ -19,7 +19,7 @@ public NextVersionCalculator(IBaseVersionCalculator baseVersionCalculator = null
new TaggedCommitVersionStrategy(),
new MergeMessageBaseVersionStrategy(),
new VersionInBranchNameBaseVersionStrategy(),
- new TrackReleaseBranchesVersionStrategy());
+ new TrackReleaseBranchesVersionStrategy(() => baseVersionFinder));
}
public SemanticVersion FindVersion(GitVersionContext context)
diff --git a/src/GitVersionCore/VersionCalculation/DevelopVersionStrategy.cs b/src/GitVersionCore/VersionCalculation/TrackReleaseBranchesVersionStrategy.cs
similarity index 62%
rename from src/GitVersionCore/VersionCalculation/DevelopVersionStrategy.cs
rename to src/GitVersionCore/VersionCalculation/TrackReleaseBranchesVersionStrategy.cs
index 99cea3298d..4a2defe722 100644
--- a/src/GitVersionCore/VersionCalculation/DevelopVersionStrategy.cs
+++ b/src/GitVersionCore/VersionCalculation/TrackReleaseBranchesVersionStrategy.cs
@@ -6,6 +6,8 @@ namespace GitVersion.VersionCalculation
using BaseVersionCalculators;
using GitTools;
using LibGit2Sharp;
+ using System;
+ using GitVersion.GitRepoInformation;
///
/// Active only when the branch is marked as IsDevelop.
@@ -27,11 +29,28 @@ public class TrackReleaseBranchesVersionStrategy : BaseVersionStrategy
{
VersionInBranchNameBaseVersionStrategy releaseVersionStrategy = new VersionInBranchNameBaseVersionStrategy();
TaggedCommitVersionStrategy taggedCommitVersionStrategy = new TaggedCommitVersionStrategy();
+ Func getBaseVersionCalculator;
+
+ public TrackReleaseBranchesVersionStrategy(Func getBaseVersionCalculator)
+ {
+ this.getBaseVersionCalculator = getBaseVersionCalculator;
+ }
public override IEnumerable GetVersions(GitVersionContext context)
{
if (context.Configuration.TracksReleaseBranches)
{
+
+
+ // I feel this is actually a recursive path for GitVersion and rather than
+ // having all this logic in here, we should just run it for each release branch and master
+
+ // Something like this, but will need to refactor BaseVersionStrategy
+ //var baseVersionCalculator = getBaseVersionCalculator();
+ //context.RepositoryMetadata.ReleaseBranches
+ // .Select(r => baseVersionCalculator.GetBaseVersion()
+
+
return ReleaseBranchBaseVersions(context).Union(MasterTagsVersions(context));
}
@@ -40,10 +59,10 @@ public override IEnumerable GetVersions(GitVersionContext context)
private IEnumerable MasterTagsVersions(GitVersionContext context)
{
- var master = context.Repository.FindBranch("master");
+ var master = context.RepositoryMetadata.MasterBranch;
if (master != null)
{
- return taggedCommitVersionStrategy.GetTaggedVersions(context, master, null);
+ return taggedCommitVersionStrategy.GetTaggedVersions(context, master);
}
return new BaseVersion[0];
@@ -51,40 +70,32 @@ private IEnumerable MasterTagsVersions(GitVersionContext context)
private IEnumerable ReleaseBranchBaseVersions(GitVersionContext context)
{
- var releaseBranchConfig = context.FullConfiguration.Branches
- .Where(b => b.Value.IsReleaseBranch == true)
+ return context
+ .RepositoryMetadata
+ .ReleaseBranches
+ .SelectMany(b => GetReleaseVersion(context, b))
+ .Select(baseVersion =>
+ {
+ // Need to drop branch overrides and give a bit more context about
+ // where this version came from
+ var source1 = "Release branch exists -> " + baseVersion.Source;
+ return new BaseVersion(context,
+ source1,
+ baseVersion.ShouldIncrement,
+ baseVersion.SemanticVersion,
+ baseVersion.BaseVersionSource,
+ null);
+ })
.ToList();
- if (releaseBranchConfig.Any())
- {
- var releaseBranches = context.Repository.Branches
- .Where(b => releaseBranchConfig.Any(c => Regex.IsMatch(b.FriendlyName, c.Key)));
-
- return releaseBranches
- .SelectMany(b => GetReleaseVersion(context, b))
- .Select(baseVersion =>
- {
- // Need to drop branch overrides and give a bit more context about
- // where this version came from
- var source1 = "Release branch exists -> " + baseVersion.Source;
- return new BaseVersion(context,
- source1,
- baseVersion.ShouldIncrement,
- baseVersion.SemanticVersion,
- baseVersion.BaseVersionSource,
- null);
- })
- .ToList();
- }
- return new BaseVersion[0];
}
- IEnumerable GetReleaseVersion(GitVersionContext context, Branch releaseBranch)
+ IEnumerable GetReleaseVersion(GitVersionContext context, MBranch releaseBranch)
{
var tagPrefixRegex = context.Configuration.GitTagPrefix;
var repository = context.Repository;
// Find the commit where the child branch was created.
- var baseSource = context.RepositoryMetadataProvider.FindMergeBase(releaseBranch, context.CurrentBranch);
+ var baseSource = context.RepositoryMetadataProvider.FindMergeBase(releaseBranch.TipSha, context.CurrentCommit.Sha);
if (baseSource == context.CurrentCommit)
{
// Ignore the branch if it has no commits.
diff --git a/src/GitVersionExe.Tests/GitVersionExe.Tests.csproj b/src/GitVersionExe.Tests/GitVersionExe.Tests.csproj
index 0de79326e5..95d4eb488b 100644
--- a/src/GitVersionExe.Tests/GitVersionExe.Tests.csproj
+++ b/src/GitVersionExe.Tests/GitVersionExe.Tests.csproj
@@ -1,5 +1,6 @@
+
@@ -67,9 +68,8 @@
..\packages\NSubstitute.1.10.0.0\lib\net45\NSubstitute.dll
True
-
- ..\packages\NUnit.3.6.0\lib\net45\nunit.framework.dll
- True
+
+ ..\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll
..\packages\Shouldly.2.7.0\lib\net40\Shouldly.dll
@@ -147,5 +147,6 @@
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
\ No newline at end of file
diff --git a/src/GitVersionExe.Tests/packages.config b/src/GitVersionExe.Tests/packages.config
index 30641d4d15..22e547e4ae 100644
--- a/src/GitVersionExe.Tests/packages.config
+++ b/src/GitVersionExe.Tests/packages.config
@@ -6,7 +6,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/src/GitVersionTask.Tests/GitVersionTask.Tests.csproj b/src/GitVersionTask.Tests/GitVersionTask.Tests.csproj
index 8fcf5aa054..415eafcfe1 100644
--- a/src/GitVersionTask.Tests/GitVersionTask.Tests.csproj
+++ b/src/GitVersionTask.Tests/GitVersionTask.Tests.csproj
@@ -1,5 +1,6 @@
+
Debug
@@ -87,9 +88,8 @@
..\packages\NSubstitute.1.10.0.0\lib\net45\NSubstitute.dll
True
-
- ..\packages\NUnit.3.6.0\lib\net45\nunit.framework.dll
- True
+
+ ..\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll
..\packages\ObjectApproval.1.3.0\lib\NET40\ObjectApproval.dll
@@ -191,6 +191,7 @@
+
\ No newline at end of file
diff --git a/src/GitVersionTask.Tests/packages.config b/src/GitVersionTask.Tests/packages.config
index 856ed3b632..b41a4ea0d7 100644
--- a/src/GitVersionTask.Tests/packages.config
+++ b/src/GitVersionTask.Tests/packages.config
@@ -14,8 +14,8 @@
-
-
+
+