diff --git a/GitVersionCore/GitFlow/BranchFinders/DevelopBasedVersionFinderBase.cs b/GitVersionCore/GitFlow/BranchFinders/DevelopBasedVersionFinderBase.cs
index 2f915d8052..c0a9e76165 100644
--- a/GitVersionCore/GitFlow/BranchFinders/DevelopBasedVersionFinderBase.cs
+++ b/GitVersionCore/GitFlow/BranchFinders/DevelopBasedVersionFinderBase.cs
@@ -37,6 +37,8 @@ protected SemanticVersion FindVersion(
context.CurrentBranch.Name, releaseDate)
};
+ semanticVersion.OverrideVersionManuallyIfNeeded(context.Repository);
+
return semanticVersion;
}
diff --git a/GitVersionCore/GitFlow/BranchFinders/DevelopVersionFinder.cs b/GitVersionCore/GitFlow/BranchFinders/DevelopVersionFinder.cs
index 90f8bd6e7c..f6e60196a8 100644
--- a/GitVersionCore/GitFlow/BranchFinders/DevelopVersionFinder.cs
+++ b/GitVersionCore/GitFlow/BranchFinders/DevelopVersionFinder.cs
@@ -30,6 +30,9 @@ public SemanticVersion FindVersion(GitVersionContext context)
PreReleaseTag = "unstable" + numberOfCommitsSinceRelease,
BuildMetaData = new SemanticVersionBuildMetaData(numberOfCommitsSinceRelease, context.CurrentBranch.Name, releaseDate),
};
+
+ semanticVersion.OverrideVersionManuallyIfNeeded(context.Repository);
+
return semanticVersion;
}
}
diff --git a/GitVersionCore/GitFlow/BranchFinders/MasterVersionFinder.cs b/GitVersionCore/GitFlow/BranchFinders/MasterVersionFinder.cs
index 4eb976ed33..8e160f71bf 100644
--- a/GitVersionCore/GitFlow/BranchFinders/MasterVersionFinder.cs
+++ b/GitVersionCore/GitFlow/BranchFinders/MasterVersionFinder.cs
@@ -17,16 +17,23 @@ public SemanticVersion FindVersion(IRepository repository, Commit tip)
}
}
+ var semanticVersion = new SemanticVersion();
+
string versionString;
if (MergeMessageParser.TryParse(tip, out versionString))
{
if (ShortVersionParser.TryParse(versionString, out major, out minor, out patch))
{
- return BuildVersion(repository, tip, major, minor, patch);
+ semanticVersion = BuildVersion(repository, tip, major, minor, patch);
}
}
- throw new WarningException("The head of master should always be a merge commit if you follow gitflow. Please create one or work around this by tagging the commit with SemVer compatible Id.");
+ if (semanticVersion == null || semanticVersion.IsEmpty())
+ {
+ throw new WarningException("The head of master should always be a merge commit if you follow gitflow. Please create one or work around this by tagging the commit with SemVer compatible Id.");
+ }
+
+ return semanticVersion;
}
SemanticVersion BuildVersion(IRepository repository, Commit tip, int major, int minor, int patch)
diff --git a/GitVersionCore/GitFlow/BranchFinders/SupportVersionFinder.cs b/GitVersionCore/GitFlow/BranchFinders/SupportVersionFinder.cs
index 318aa086df..f96535be91 100644
--- a/GitVersionCore/GitFlow/BranchFinders/SupportVersionFinder.cs
+++ b/GitVersionCore/GitFlow/BranchFinders/SupportVersionFinder.cs
@@ -17,16 +17,25 @@ public SemanticVersion FindVersion(IRepository repository, Commit tip)
}
}
+ var semanticVersion = new SemanticVersion();
+
string versionString;
if (MergeMessageParser.TryParse(tip, out versionString))
{
if (ShortVersionParser.TryParse(versionString, out major, out minor, out patch))
{
- return BuildVersion(repository, tip, major, minor, patch);
+ semanticVersion = BuildVersion(repository, tip, major, minor, patch);
}
}
- throw new WarningException("The head of a support branch should always be a merge commit if you follow gitflow. Please create one or work around this by tagging the commit with SemVer compatible Id.");
+ semanticVersion.OverrideVersionManuallyIfNeeded(repository);
+
+ if (semanticVersion == null || semanticVersion.IsEmpty())
+ {
+ throw new WarningException("The head of a support branch should always be a merge commit if you follow gitflow. Please create one or work around this by tagging the commit with SemVer compatible Id.");
+ }
+
+ return semanticVersion;
}
SemanticVersion BuildVersion(IRepository repository, Commit tip, int major, int minor, int patch)
diff --git a/GitVersionCore/GitHubFlow/NextVersionTxtFileFinder.cs b/GitVersionCore/GitHubFlow/NextVersionTxtFileFinder.cs
index fb45b92360..7c9e8bb23a 100644
--- a/GitVersionCore/GitHubFlow/NextVersionTxtFileFinder.cs
+++ b/GitVersionCore/GitHubFlow/NextVersionTxtFileFinder.cs
@@ -19,14 +19,18 @@ public SemanticVersion GetNextVersion()
{
return new SemanticVersion();
}
- var version = File.ReadAllText(filePath);
+ var version = File.ReadAllText(filePath);
if (string.IsNullOrEmpty(version))
+ {
return new SemanticVersion();
+ }
SemanticVersion semanticVersion;
if (!SemanticVersion.TryParse(version, out semanticVersion))
+ {
throw new ArgumentException("Make sure you have a valid semantic version in NextVersion.txt");
+ }
return semanticVersion;
}
diff --git a/GitVersionCore/GitVersionCore.csproj b/GitVersionCore/GitVersionCore.csproj
index 0f11721778..4f1680a25b 100644
--- a/GitVersionCore/GitVersionCore.csproj
+++ b/GitVersionCore/GitVersionCore.csproj
@@ -7,7 +7,7 @@
{F9741A0D-B9D7-4557-9A1C-A7252C1071F5}
Library
Properties
- GitVersionCore
+ GitVersion
GitVersionCore
v4.0
512
@@ -66,6 +66,7 @@
+
diff --git a/GitVersionCore/LibGitExtensions.cs b/GitVersionCore/LibGitExtensions.cs
index bd12998c17..2ffe323ca7 100644
--- a/GitVersionCore/LibGitExtensions.cs
+++ b/GitVersionCore/LibGitExtensions.cs
@@ -2,6 +2,7 @@ namespace GitVersion
{
using System;
using System.Collections.Generic;
+ using System.IO;
using System.Linq;
using LibGit2Sharp;
@@ -73,5 +74,59 @@ public static bool IsDetachedHead(this Branch branch)
{
return branch.CanonicalName.Equals("(no branch)", StringComparison.OrdinalIgnoreCase);
}
+
+ public static string GetRepositoryDirectory(this IRepository repository)
+ {
+ var gitDirectory = repository.Info.Path;
+
+ gitDirectory = gitDirectory.TrimEnd('\\');
+
+ if (gitDirectory.EndsWith(".git"))
+ {
+ gitDirectory = gitDirectory.Substring(0, gitDirectory.Length - ".git".Length);
+ }
+
+ return gitDirectory;
+ }
+
+ public static void CheckoutFilesIfExist(this IRepository repository, params string[] fileNames)
+ {
+ if (fileNames == null || fileNames.Length == 0)
+ {
+ return;
+ }
+
+ Logger.WriteInfo(string.Format("Checking out files that might be needed later in dynamic repository"));
+
+ foreach (var fileName in fileNames)
+ {
+ try
+ {
+ Logger.WriteInfo(string.Format(" Trying to check out '{0}'", fileName));
+
+ var headBranch = repository.Head;
+ var tip = headBranch.Tip;
+
+ var treeEntry = tip[fileName];
+ if (treeEntry == null)
+ {
+ continue;
+ }
+
+ var fullPath = Path.Combine(repository.GetRepositoryDirectory(), fileName);
+ using (var stream = ((Blob) treeEntry.Target).GetContentStream())
+ {
+ using (var streamReader = new BinaryReader(stream))
+ {
+ File.WriteAllBytes(fullPath, streamReader.ReadBytes((int)stream.Length));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.WriteWarning(string.Format(" An error occurred while checking out '{0}': '{1}'", fileName, ex.Message));
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/GitVersionCore/SemanticVersion.cs b/GitVersionCore/SemanticVersion.cs
index a1f1bd83f6..578f672ae5 100644
--- a/GitVersionCore/SemanticVersion.cs
+++ b/GitVersionCore/SemanticVersion.cs
@@ -5,6 +5,8 @@ namespace GitVersion
public class SemanticVersion : IFormattable, IComparable
{
+ public static SemanticVersion Empty = new SemanticVersion();
+
static Regex ParseSemVer = new Regex(
@"[vV]?(?(?\d+)(\.(?\d+))?(\.(?\d+))?)(\.(?\d+))?(-(?[^\+]*))?(\+(?.*))?",
RegexOptions.Compiled);
@@ -34,6 +36,11 @@ public bool Equals(SemanticVersion obj)
BuildMetaData == obj.BuildMetaData;
}
+ public bool IsEmpty()
+ {
+ return Equals(Empty);
+ }
+
public static bool operator ==(SemanticVersion v1, SemanticVersion v2)
{
if (ReferenceEquals(v1, null))
diff --git a/GitVersionCore/SemanticVersionExtensions.cs b/GitVersionCore/SemanticVersionExtensions.cs
new file mode 100644
index 0000000000..002ffddfbb
--- /dev/null
+++ b/GitVersionCore/SemanticVersionExtensions.cs
@@ -0,0 +1,22 @@
+namespace GitVersion
+{
+ using LibGit2Sharp;
+
+ public static class SemanticVersionExtensions
+ {
+ public static void OverrideVersionManuallyIfNeeded(this SemanticVersion version, IRepository repository)
+ {
+ var nextVersionTxtFileFinder = new NextVersionTxtFileFinder(repository.GetRepositoryDirectory());
+ var manualNextVersion = nextVersionTxtFileFinder.GetNextVersion();
+ if (!manualNextVersion.IsEmpty())
+ {
+ if (manualNextVersion > version)
+ {
+ version.Major = manualNextVersion.Major;
+ version.Minor = manualNextVersion.Minor;
+ version.Patch = manualNextVersion.Patch;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/GitVersionExe/GitPreparer.cs b/GitVersionExe/GitPreparer.cs
index d47fb672ef..fa1ea63394 100644
--- a/GitVersionExe/GitPreparer.cs
+++ b/GitVersionExe/GitPreparer.cs
@@ -73,6 +73,8 @@ string GetGitInfoFromUrl()
repository.Refs.UpdateTarget("HEAD", targetBranchName);
}
+
+ repository.CheckoutFilesIfExist("NextVersion.txt");
}
}
diff --git a/Tests/SemanticVersionTests.cs b/Tests/SemanticVersionTests.cs
index 8bcd519543..1be429565e 100644
--- a/Tests/SemanticVersionTests.cs
+++ b/Tests/SemanticVersionTests.cs
@@ -61,5 +61,12 @@ public void LegacySemVerTest()
new SemanticVersionPreReleaseTag("AReallyReallyReallyLongBranchName", 1).ToString("lp").ShouldBe("AReallyReallyRea0001");
}
+ [Test]
+ public void EmptyVersion()
+ {
+ Assert.IsTrue(SemanticVersion.Empty.IsEmpty());
+ var emptyVersion = new SemanticVersion();
+ Assert.IsTrue(emptyVersion.IsEmpty());
+ }
}
\ No newline at end of file