Skip to content

Commit a5ab1b7

Browse files
committed
Introduce ObjectDatabase.ShortenObjectId()
Fix #677
1 parent e59a0e7 commit a5ab1b7

File tree

5 files changed

+87
-2
lines changed

5 files changed

+87
-2
lines changed

LibGit2Sharp.Tests/ObjectDatabaseFixture.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,5 +532,47 @@ public void CalculatingHistoryDivergenceWithBadParamsThrows()
532532
() => repo.ObjectDatabase.CalculateHistoryDivergence(null, repo.Head.Tip));
533533
}
534534
}
535+
536+
[Fact]
537+
public void CanShortenObjectIdentifier()
538+
{
539+
/*
540+
* $ echo "aabqhq" | git hash-object -t blob --stdin
541+
* dea509d0b3cb8ee0650f6ca210bc83f4678851ba
542+
*
543+
* $ echo "aaazvc" | git hash-object -t blob --stdin
544+
* dea509d097ce692e167dfc6a48a7a280cc5e877e
545+
*/
546+
547+
string path = CloneBareTestRepo();
548+
using (var repo = new Repository(path))
549+
{
550+
repo.Config.Set("core.abbrev", 4);
551+
552+
Blob blob1 = CreateBlob(repo, "aabqhq\n");
553+
Assert.Equal("dea509d0b3cb8ee0650f6ca210bc83f4678851ba", blob1.Sha);
554+
555+
Assert.Equal("dea5", repo.ObjectDatabase.ShortenObjectId(blob1));
556+
Assert.Equal("dea509d0b3cb", repo.ObjectDatabase.ShortenObjectId(blob1, 12));
557+
Assert.Equal("dea509d0b3cb8ee0650f6ca210bc83f4678851b", repo.ObjectDatabase.ShortenObjectId(blob1, 39));
558+
559+
Blob blob2 = CreateBlob(repo, "aaazvc\n");
560+
Assert.Equal("dea509d09", repo.ObjectDatabase.ShortenObjectId(blob2));
561+
Assert.Equal("dea509d09", repo.ObjectDatabase.ShortenObjectId(blob2, 4));
562+
Assert.Equal("dea509d0b", repo.ObjectDatabase.ShortenObjectId(blob1));
563+
Assert.Equal("dea509d0b", repo.ObjectDatabase.ShortenObjectId(blob1, 7));
564+
565+
Assert.Equal("dea509d0b3cb", repo.ObjectDatabase.ShortenObjectId(blob1, 12));
566+
Assert.Equal("dea509d097ce", repo.ObjectDatabase.ShortenObjectId(blob2, 12));
567+
}
568+
}
569+
570+
private static Blob CreateBlob(Repository repo, string content)
571+
{
572+
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(content)))
573+
{
574+
return repo.ObjectDatabase.CreateBlob(stream);
575+
}
576+
}
535577
}
536578
}

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,11 @@ internal static extern int git_object_peel(
725725
GitObjectSafeHandle obj,
726726
GitObjectType type);
727727

728+
[DllImport(libgit2)]
729+
internal static extern int git_object_short_id(
730+
GitBuf buf,
731+
GitObjectSafeHandle obj);
732+
728733
[DllImport(libgit2)]
729734
internal static extern GitObjectType git_object_type(GitObjectSafeHandle obj);
730735

LibGit2Sharp/Core/Proxy.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,19 @@ public static GitObjectSafeHandle git_object_peel(RepositorySafeHandle repo, Obj
12281228
}
12291229
}
12301230

1231+
public static string git_object_short_id(RepositorySafeHandle repo, ObjectId id)
1232+
{
1233+
using (ThreadAffinity())
1234+
using (var obj = new ObjectSafeWrapper(id, repo))
1235+
using (var buf = new GitBuf())
1236+
{
1237+
int res = NativeMethods.git_object_short_id(buf, obj.ObjectPtr);
1238+
Ensure.Int32Result(res);
1239+
1240+
return LaxUtf8Marshaler.FromNative(buf.ptr);
1241+
}
1242+
}
1243+
12311244
public static GitObjectType git_object_type(GitObjectSafeHandle obj)
12321245
{
12331246
return NativeMethods.git_object_type(obj);

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,5 +283,30 @@ public virtual HistoryDivergence CalculateHistoryDivergence(Commit one, Commit a
283283

284284
return new HistoryDivergence(repo, one, another);
285285
}
286+
287+
/// <summary>
288+
/// Calculates the current shortest abbreviated <see cref="ObjectId"/>
289+
/// string representation for a <see cref="GitObject"/>.
290+
/// </summary>
291+
/// <param name="gitObject">The <see cref="GitObject"/> which identifier should be shortened.</param>
292+
/// <param name="minLength">Minimum length of the shortened representation.</param>
293+
/// <returns>A short string representation of the <see cref="ObjectId"/>.</returns>
294+
public virtual string ShortenObjectId(GitObject gitObject, int? minLength = null)
295+
{
296+
if (minLength.HasValue && (minLength <= 0 || minLength > ObjectId.HexSize))
297+
{
298+
throw new ArgumentOutOfRangeException("minLength", minLength,
299+
string.Format("Expected value should be greater than zero and less than or equal to {0}.", ObjectId.HexSize));
300+
}
301+
302+
string shortSha = Proxy.git_object_short_id(repo.Handle, gitObject.Id);
303+
304+
if (minLength == null || (minLength <= shortSha.Length))
305+
{
306+
return shortSha;
307+
}
308+
309+
return gitObject.Sha.Substring(0, minLength.Value);
310+
}
286311
}
287312
}

LibGit2Sharp/ObjectId.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ namespace LibGit2Sharp
1111
public sealed class ObjectId : IEquatable<ObjectId>
1212
{
1313
private readonly GitOid oid;
14-
private const int rawSize = 20;
14+
private const int rawSize = GitOid.Size;
1515
private readonly string sha;
1616

1717
/// <summary>
1818
/// Size of the string-based representation of a SHA-1.
1919
/// </summary>
20-
private const int HexSize = rawSize * 2;
20+
internal const int HexSize = rawSize * 2;
2121

2222
private const string hexDigits = "0123456789abcdef";
2323
private static readonly byte[] reverseHexDigits = BuildReverseHexDigits();

0 commit comments

Comments
 (0)