Skip to content

Commit 992774c

Browse files
committed
Find branch detached head is on
1 parent 53945c5 commit 992774c

File tree

5 files changed

+75
-33
lines changed

5 files changed

+75
-33
lines changed

GitVersionCore/ExtensionMethods.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace GitVersion
22
{
33
using System;
4+
using System.Collections.Generic;
45
using System.Text;
56
using System.Text.RegularExpressions;
67
using JetBrains.Annotations;
@@ -11,6 +12,7 @@ public static bool IsOdd(this int number)
1112
{
1213
return number % 2 != 0;
1314
}
15+
1416
public static string TrimToFirstLine(this string s)
1517
{
1618
return s.Split(new[]
@@ -37,7 +39,6 @@ public static string TrimStart(this string value, string toTrim)
3739
return value.Substring(startIndex);
3840
}
3941

40-
4142
public static string JsonEncode(this string value)
4243
{
4344
if (value != null)
@@ -59,5 +60,25 @@ public static string RegexReplace(this string input, string pattern, string repl
5960
return Regex.Replace(input, pattern, replace, options);
6061
}
6162

63+
public static T OnlyOrDefault<T>(this IEnumerable<T> source)
64+
{
65+
if (source == null) throw new ArgumentNullException("source");
66+
67+
var list = source as IList<T>;
68+
69+
if (list != null && list.Count == 1)
70+
{
71+
return list[0];
72+
}
73+
74+
using (var e = source.GetEnumerator())
75+
{
76+
if (!e.MoveNext()) return default(T);
77+
var result = e.Current;
78+
if (!e.MoveNext()) return result;
79+
}
80+
81+
return default(T);
82+
}
6283
}
6384
}

GitVersionCore/GitVersionContext.cs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
namespace GitVersion
22
{
3+
using System.Collections.Generic;
4+
using System.Linq;
35
using LibGit2Sharp;
46

57
/// <summary>
@@ -15,16 +17,56 @@ public GitVersionContext(IRepository repository)
1517
public GitVersionContext(IRepository repository, Branch currentBranch)
1618
{
1719
Repository = repository;
18-
CurrentBranch = currentBranch;
1920

20-
if (CurrentBranch != null)
21+
if (currentBranch == null)
22+
return;
23+
24+
CurrentCommit = currentBranch.Tip;
25+
26+
if (repository != null && currentBranch.IsDetachedHead())
2127
{
22-
CurrentCommit = CurrentBranch.Tip;
28+
CurrentBranch = GetBranchesContaininingCommit(CurrentCommit.Sha).OnlyOrDefault() ?? currentBranch;
29+
}
30+
else
31+
{
32+
CurrentBranch = currentBranch;
2333
}
2434
}
2535

2636
public IRepository Repository { get; private set; }
2737
public Branch CurrentBranch { get; private set; }
2838
public Commit CurrentCommit { get; private set; }
39+
40+
private IEnumerable<Branch> GetBranchesContaininingCommit(string commitSha)
41+
{
42+
var directBranchHasBeenFound = false;
43+
foreach (var branch in Repository.Branches)
44+
{
45+
if (branch.Tip.Sha != commitSha)
46+
{
47+
continue;
48+
}
49+
50+
directBranchHasBeenFound = true;
51+
yield return branch;
52+
}
53+
54+
if (directBranchHasBeenFound)
55+
{
56+
yield break;
57+
}
58+
59+
foreach (var branch in Repository.Branches)
60+
{
61+
var commits = Repository.Commits.QueryBy(new CommitFilter { Since = branch }).Where(c => c.Sha == commitSha);
62+
63+
if (!commits.Any())
64+
{
65+
continue;
66+
}
67+
68+
yield return branch;
69+
}
70+
}
2971
}
3072
}

GitVersionCore/GitVersionFinder.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
namespace GitVersion
22
{
3-
using System;
43
using System.Linq;
54
using LibGit2Sharp;
65

@@ -34,7 +33,7 @@ void EnsureMainTopologyConstraints(GitVersionContext context)
3433

3534
void EnsureHeadIsNotDetached(GitVersionContext context)
3635
{
37-
if (!context.CurrentBranch.CanonicalName.Equals("(no branch)", StringComparison.OrdinalIgnoreCase))
36+
if (!context.CurrentBranch.IsDetachedHead())
3837
{
3938
return;
4039
}

GitVersionCore/LibGitExtensions.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ namespace GitVersion
77

88
static class LibGitExtensions
99
{
10-
1110
public static DateTimeOffset When(this Commit commit)
1211
{
1312
return commit.Committer.When;
@@ -69,5 +68,10 @@ public static IEnumerable<Commit> CommitsPriorToThan(this Branch branch, DateTim
6968
{
7069
return branch.Commits.SkipWhile(c => c.When() > olderThan);
7170
}
71+
72+
public static bool IsDetachedHead(this Branch branch)
73+
{
74+
return branch.CanonicalName.Equals("(no branch)", StringComparison.OrdinalIgnoreCase);
75+
}
7276
}
73-
}
77+
}

Tests/UpdateAssemblyInfoTests.cs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public void StandardExecutionMode_CanDetermineTheVersionFromALocalDevelop()
6666
task.InnerExecute();
6767
}
6868

69-
7069
[Test]
7170
public void StandardExecutionMode_CanDetermineTheVersionFromALocalFeature()
7271
{
@@ -81,27 +80,6 @@ public void StandardExecutionMode_CanDetermineTheVersionFromALocalFeature()
8180
task.InnerExecute();
8281
}
8382

84-
[Test]
85-
public void StandardExecutionMode_CannotDetermineTheVersionFromADetachedHead()
86-
{
87-
var repoPath = Clone(ASBMTestRepoWorkingDirPath);
88-
89-
using (var repo = new Repository(repoPath))
90-
{
91-
repo.Checkout("469f851");
92-
Assert.IsTrue(repo.Info.IsHeadDetached);
93-
}
94-
95-
var task = new UpdateAssemblyInfo
96-
{
97-
BuildEngine = new MockBuildEngine(),
98-
SolutionDirectory = repoPath,
99-
};
100-
101-
var exception = Assert.Throws<WarningException>(task.InnerExecute);
102-
Assert.AreEqual("It looks like the branch being examined is a detached Head pointing to commit '469f851'. Without a proper branch name GitVersion cannot determine the build version.", exception.Message);
103-
}
104-
10583
[TestCase("Major")]
10684
[TestCase("MajorMinor")]
10785
[TestCase("MajorMinorPatch")]
@@ -138,7 +116,6 @@ public void StandardExecutionMode_ThrowsUponUnexpectedAssemblyVersioningSchemes(
138116

139117
var exception = Assert.Throws<WarningException>(task.InnerExecute);
140118
Assert.AreEqual("Unexpected assembly versioning scheme 'Boom'.", exception.Message);
141-
142119
}
143120

144121
[SetUp]
@@ -148,12 +125,12 @@ public void SetUp()
148125
BuildServerList.Selector = arguments => new List<IBuildServer>();
149126
}
150127

151-
152128
[TearDown]
153129
public void TearDown()
154130
{
155131
BuildServerList.ResetSelector();
156132
}
133+
157134
string CheckoutLocal(string repositoryPath, string monitoredReference)
158135
{
159136
var repoPath = Clone(repositoryPath);
@@ -164,5 +141,4 @@ string CheckoutLocal(string repositoryPath, string monitoredReference)
164141
}
165142
return repoPath;
166143
}
167-
168144
}

0 commit comments

Comments
 (0)