Skip to content

Commit 4252d55

Browse files
committed
Ensure Tags can be created in detached Head state
Fix libgit2#791
1 parent b5c658d commit 4252d55

File tree

5 files changed

+56
-7
lines changed

5 files changed

+56
-7
lines changed

LibGit2Sharp.Tests/ResetHeadFixture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public void ResetANewlyInitializedRepositoryThrows(bool isBare)
1818

1919
using (var repo = new Repository(repoPath))
2020
{
21-
Assert.Throws<LibGit2SharpException>(() => repo.Reset(ResetMode.Soft));
21+
Assert.Throws<UnbornBranchException>(() => repo.Reset(ResetMode.Soft));
2222
}
2323
}
2424

LibGit2Sharp.Tests/ResetIndexFixture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public void ResetANewlyInitializedNonBareRepositoryThrows()
2525

2626
using (var repo = new Repository(repoPath))
2727
{
28-
Assert.Throws<LibGit2SharpException>(() => repo.Reset());
28+
Assert.Throws<UnbornBranchException>(() => repo.Reset());
2929
}
3030
}
3131

LibGit2Sharp.Tests/TagFixture.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ public void CreatingATagInAEmptyRepositoryThrows()
234234

235235
using (var repo = new Repository(repoPath))
236236
{
237-
Assert.Throws<LibGit2SharpException>(() => repo.ApplyTag("mynotag"));
237+
Assert.Throws<UnbornBranchException>(() => repo.ApplyTag("mynotag"));
238238
}
239239
}
240240

@@ -246,7 +246,8 @@ public void CreatingATagForHeadInAEmptyRepositoryThrows()
246246

247247
using (var repo = new Repository(repoPath))
248248
{
249-
Assert.Throws<LibGit2SharpException>(() => repo.ApplyTag("mytaghead", "HEAD"));
249+
Assert.Throws<UnbornBranchException>(() => repo.ApplyTag("mytaghead", "HEAD"));
250+
Assert.Throws<UnbornBranchException>(() => repo.ApplyTag("mytaghead"));
250251
}
251252
}
252253

@@ -287,6 +288,26 @@ public void CanAddATagForImplicitHead()
287288
}
288289
}
289290

291+
[Fact]
292+
public void CanAddATagForImplicitHeadInDetachedState()
293+
{
294+
string path = CloneStandardTestRepo();
295+
using (var repo = new Repository(path))
296+
{
297+
repo.Checkout(repo.Head.Tip);
298+
299+
Assert.True(repo.Info.IsHeadDetached);
300+
301+
Tag tag = repo.ApplyTag("mytag");
302+
Assert.NotNull(tag);
303+
304+
Assert.Equal(repo.Head.Tip.Id, tag.Target.Id);
305+
306+
Tag retrievedTag = repo.Tags[tag.CanonicalName];
307+
Assert.Equal(retrievedTag, tag);
308+
}
309+
}
310+
290311
[Fact]
291312
// Ported from cgit (https://github.com/git/git/blob/1c08bf50cfcf924094eca56c2486a90e2bf1e6e2/t/t7004-tag.sh#L87)
292313
public void CreatingADuplicateTagThrows()

LibGit2Sharp/Core/Ensure.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,32 @@ public static void ArgumentConformsTo<T>(T argumentValue, Func<T, bool> checker,
209209
}
210210

211211
public static void GitObjectIsNotNull(GitObject gitObject, string identifier)
212+
{
213+
Func<string, LibGit2SharpException> exceptionBuilder;
214+
215+
if (string.Equals("HEAD", identifier, StringComparison.Ordinal))
216+
{
217+
exceptionBuilder = m => new UnbornBranchException(m);
218+
}
219+
else
220+
{
221+
exceptionBuilder = m => new LibGit2SharpException(m);
222+
}
223+
224+
GitObjectIsNotNull(gitObject, identifier, exceptionBuilder);
225+
}
226+
227+
public static void GitObjectIsNotNull(
228+
GitObject gitObject,
229+
string identifier,
230+
Func<string, LibGit2SharpException> exceptionBuilder)
212231
{
213232
if (gitObject != null)
214233
{
215234
return;
216235
}
217236

218-
throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture,
237+
throw exceptionBuilder(string.Format(CultureInfo.InvariantCulture,
219238
"No valid git object identified by '{0}' exists in the repository.",
220239
identifier));
221240
}

LibGit2Sharp/RepositoryExtensions.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private static void EnsureNoGitLink<T>() where T : GitObject
6868
/// <param name="tagName">The name of the tag to create.</param>
6969
public static Tag ApplyTag(this IRepository repository, string tagName)
7070
{
71-
return ApplyTag(repository, tagName, repository.Head.CanonicalName);
71+
return repository.Tags.Add(tagName, RetrieveHeadCommit(repository));
7272
}
7373

7474
/// <summary>
@@ -91,7 +91,16 @@ public static Tag ApplyTag(this IRepository repository, string tagName, string o
9191
/// <param name="message">The annotation message.</param>
9292
public static Tag ApplyTag(this IRepository repository, string tagName, Signature tagger, string message)
9393
{
94-
return ApplyTag(repository, tagName, repository.Head.CanonicalName, tagger, message);
94+
return repository.Tags.Add(tagName, RetrieveHeadCommit(repository), tagger, message);
95+
}
96+
97+
private static Commit RetrieveHeadCommit(IRepository repository)
98+
{
99+
Commit commit = repository.Head.Tip;
100+
101+
Ensure.GitObjectIsNotNull(commit, "HEAD", m => new UnbornBranchException(m));
102+
103+
return commit;
95104
}
96105

97106
/// <summary>

0 commit comments

Comments
 (0)