Skip to content

Commit 41364ef

Browse files
committed
Make Refs.Add() accept a revparse specification
1 parent 4819b80 commit 41364ef

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

LibGit2Sharp.Tests/ReferenceFixture.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ public void CanAddADirectReference()
3333
}
3434
}
3535

36+
[Fact]
37+
public void CanAddADirectReferenceFromRevParseSpec()
38+
{
39+
const string name = "refs/heads/extendedShaSyntaxRulz";
40+
41+
TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo();
42+
using (var repo = new Repository(path.RepositoryPath))
43+
{
44+
var newRef = (DirectReference)repo.Refs.Add(name, "master^1^2");
45+
Assert.NotNull(newRef);
46+
Assert.Equal(name, newRef.CanonicalName);
47+
Assert.NotNull(newRef.Target);
48+
Assert.Equal("c47800c7266a2be04c571c04d5a6614691ea99bd", newRef.Target.Sha);
49+
Assert.Equal(newRef.Target.Sha, newRef.TargetIdentifier);
50+
Assert.NotNull(repo.Refs[name]);
51+
}
52+
}
53+
3654
[Fact]
3755
public void CanAddASymbolicReference()
3856
{

LibGit2Sharp/ReferenceCollection.cs

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,28 +65,62 @@ IEnumerator IEnumerable.GetEnumerator()
6565

6666
#endregion
6767

68+
private enum RefState
69+
{
70+
Exists,
71+
DoesNotExistButLooksValid,
72+
DoesNotLookValid,
73+
}
74+
75+
private RefState TryResolveReference(out Reference reference, string canonicalName)
76+
{
77+
try
78+
{
79+
//TODO: Maybe would it be better to rather rely on git_reference_normalize_name()
80+
//This would be much more straightforward and less subject to fail for the wrong reason.
81+
82+
reference = repo.Refs[canonicalName];
83+
84+
if (reference != null)
85+
{
86+
return RefState.Exists;
87+
}
88+
89+
return RefState.DoesNotExistButLooksValid;
90+
}
91+
catch (LibGit2SharpException)
92+
{
93+
reference = null;
94+
return RefState.DoesNotLookValid;
95+
}
96+
}
97+
6898
/// <summary>
6999
/// Creates a direct or symbolic reference with the specified name and target
70100
/// </summary>
71101
/// <param name = "name">The name of the reference to create.</param>
72-
/// <param name = "target">The target which can be either a sha or the canonical name of another reference.</param>
102+
/// <param name = "canonicalRefNameOrObjectish">The target which can be either the canonical name of a branch reference or a revparse spec.</param>
73103
/// <param name = "allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param>
74104
/// <returns>A new <see cref = "Reference" />.</returns>
75-
public virtual Reference Add(string name, string target, bool allowOverwrite = false)
105+
public virtual Reference Add(string name, string canonicalRefNameOrObjectish, bool allowOverwrite = false)
76106
{
77107
Ensure.ArgumentNotNullOrEmptyString(name, "name");
78-
Ensure.ArgumentNotNullOrEmptyString(target, "target");
108+
Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish");
79109

80-
ObjectId id;
81110
Func<string, bool, ReferenceSafeHandle> referenceCreator;
82111

83-
if (ObjectId.TryParse(target, out id))
112+
Reference reference;
113+
RefState refState = TryResolveReference(out reference, canonicalRefNameOrObjectish);
114+
115+
var gitObject = repo.Lookup(canonicalRefNameOrObjectish, GitObjectType.Any, LookUpOptions.None);
116+
117+
if (refState == RefState.Exists || (refState == RefState.DoesNotExistButLooksValid && gitObject == null))
84118
{
85-
referenceCreator = (n, o) => CreateDirectReference(n, id, o);
119+
referenceCreator = (n, o) => CreateSymbolicReference(n, canonicalRefNameOrObjectish, o);
86120
}
87121
else
88122
{
89-
referenceCreator = (n, o) => CreateSymbolicReference(n, target, o);
123+
referenceCreator = (n, o) => CreateDirectReference(n, gitObject.Id, o);
90124
}
91125

92126
using (ReferenceSafeHandle handle = referenceCreator(name, allowOverwrite))

0 commit comments

Comments
 (0)