Skip to content

Commit dc815f8

Browse files
committed
Introduce ObjectDatabase.ShortenObjectId()
Fix #677
1 parent eedeac0 commit dc815f8

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
@@ -556,5 +556,47 @@ public void CalculatingHistoryDivergenceWithBadParamsThrows()
556556
() => repo.ObjectDatabase.CalculateHistoryDivergence(null, repo.Head.Tip));
557557
}
558558
}
559+
560+
[Fact]
561+
public void CanShortenObjectIdentifier()
562+
{
563+
/*
564+
* $ echo "aabqhq" | git hash-object -t blob --stdin
565+
* dea509d0b3cb8ee0650f6ca210bc83f4678851ba
566+
*
567+
* $ echo "aaazvc" | git hash-object -t blob --stdin
568+
* dea509d097ce692e167dfc6a48a7a280cc5e877e
569+
*/
570+
571+
string path = CloneBareTestRepo();
572+
using (var repo = new Repository(path))
573+
{
574+
repo.Config.Set("core.abbrev", 4);
575+
576+
Blob blob1 = CreateBlob(repo, "aabqhq\n");
577+
Assert.Equal("dea509d0b3cb8ee0650f6ca210bc83f4678851ba", blob1.Sha);
578+
579+
Assert.Equal("dea5", repo.ObjectDatabase.ShortenObjectId(blob1));
580+
Assert.Equal("dea509d0b3cb", repo.ObjectDatabase.ShortenObjectId(blob1, 12));
581+
Assert.Equal("dea509d0b3cb8ee0650f6ca210bc83f4678851b", repo.ObjectDatabase.ShortenObjectId(blob1, 39));
582+
583+
Blob blob2 = CreateBlob(repo, "aaazvc\n");
584+
Assert.Equal("dea509d09", repo.ObjectDatabase.ShortenObjectId(blob2));
585+
Assert.Equal("dea509d09", repo.ObjectDatabase.ShortenObjectId(blob2, 4));
586+
Assert.Equal("dea509d0b", repo.ObjectDatabase.ShortenObjectId(blob1));
587+
Assert.Equal("dea509d0b", repo.ObjectDatabase.ShortenObjectId(blob1, 7));
588+
589+
Assert.Equal("dea509d0b3cb", repo.ObjectDatabase.ShortenObjectId(blob1, 12));
590+
Assert.Equal("dea509d097ce", repo.ObjectDatabase.ShortenObjectId(blob2, 12));
591+
}
592+
}
593+
594+
private static Blob CreateBlob(Repository repo, string content)
595+
{
596+
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(content)))
597+
{
598+
return repo.ObjectDatabase.CreateBlob(stream);
599+
}
600+
}
559601
}
560602
}

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,11 @@ internal static extern int git_object_peel(
753753
GitObjectSafeHandle obj,
754754
GitObjectType type);
755755

756+
[DllImport(libgit2)]
757+
internal static extern int git_object_short_id(
758+
GitBuf buf,
759+
GitObjectSafeHandle obj);
760+
756761
[DllImport(libgit2)]
757762
internal static extern GitObjectType git_object_type(GitObjectSafeHandle obj);
758763

LibGit2Sharp/Core/Proxy.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,19 @@ public static GitObjectSafeHandle git_object_peel(RepositorySafeHandle repo, Obj
12511251
}
12521252
}
12531253

1254+
public static string git_object_short_id(RepositorySafeHandle repo, ObjectId id)
1255+
{
1256+
using (ThreadAffinity())
1257+
using (var obj = new ObjectSafeWrapper(id, repo))
1258+
using (var buf = new GitBuf())
1259+
{
1260+
int res = NativeMethods.git_object_short_id(buf, obj.ObjectPtr);
1261+
Ensure.Int32Result(res);
1262+
1263+
return LaxUtf8Marshaler.FromNative(buf.ptr);
1264+
}
1265+
}
1266+
12541267
public static GitObjectType git_object_type(GitObjectSafeHandle obj)
12551268
{
12561269
return NativeMethods.git_object_type(obj);

LibGit2Sharp/ObjectDatabase.cs

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

369369
return new HistoryDivergence(repo, one, another);
370370
}
371+
372+
/// <summary>
373+
/// Calculates the current shortest abbreviated <see cref="ObjectId"/>
374+
/// string representation for a <see cref="GitObject"/>.
375+
/// </summary>
376+
/// <param name="gitObject">The <see cref="GitObject"/> which identifier should be shortened.</param>
377+
/// <param name="minLength">Minimum length of the shortened representation.</param>
378+
/// <returns>A short string representation of the <see cref="ObjectId"/>.</returns>
379+
public virtual string ShortenObjectId(GitObject gitObject, int? minLength = null)
380+
{
381+
if (minLength.HasValue && (minLength <= 0 || minLength > ObjectId.HexSize))
382+
{
383+
throw new ArgumentOutOfRangeException("minLength", minLength,
384+
string.Format("Expected value should be greater than zero and less than or equal to {0}.", ObjectId.HexSize));
385+
}
386+
387+
string shortSha = Proxy.git_object_short_id(repo.Handle, gitObject.Id);
388+
389+
if (minLength == null || (minLength <= shortSha.Length))
390+
{
391+
return shortSha;
392+
}
393+
394+
return gitObject.Sha.Substring(0, minLength.Value);
395+
}
371396
}
372397
}

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)