Skip to content

Commit 41c32a3

Browse files
committed
Indexer: add bindings for the pack indexer
This allows the user to index a packfile they have in a file or are retrieving through a Stream.
1 parent d677741 commit 41c32a3

File tree

7 files changed

+199
-0
lines changed

7 files changed

+199
-0
lines changed

LibGit2Sharp.Tests/IndexerFixture.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using System.IO;
3+
using LibGit2Sharp.Advanced;
4+
using LibGit2Sharp.Tests.TestHelpers;
5+
using Xunit;
6+
7+
namespace LibGit2Sharp.Tests
8+
{
9+
public class IndexerFixture : BaseFixture
10+
{
11+
[Fact]
12+
[Trait("run", "me")]
13+
public void CanIndexFromAFilePath()
14+
{
15+
using (var repo = new Repository(CloneStandardTestRepo()))
16+
{
17+
var path = Path.Combine(repo.Info.Path, "objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack");
18+
var indexer = new Indexer(repo.Info.WorkingDirectory);
19+
indexer.Index(path);
20+
Assert.Equal(1628, indexer.Progress.TotalObjects);
21+
}
22+
}
23+
24+
[Fact]
25+
[Trait("run", "me")]
26+
public void CanIndexFromAStream()
27+
{
28+
using (var repo = new Repository(CloneStandardTestRepo()))
29+
{
30+
var path = Path.Combine(repo.Info.Path, "objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack");
31+
var indexer = new Indexer(repo.Info.WorkingDirectory);
32+
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
33+
{
34+
indexer.Index(stream);
35+
Assert.Equal(1628, indexer.Progress.TotalObjects);
36+
}
37+
}
38+
}
39+
40+
}
41+
}
42+

LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
<Compile Include="TreeFixture.cs" />
123123
<Compile Include="TupleFixture.cs" />
124124
<Compile Include="UnstageFixture.cs" />
125+
<Compile Include="IndexerFixture.cs" />
125126
</ItemGroup>
126127
<ItemGroup>
127128
<ProjectReference Include="..\LibGit2Sharp\LibGit2Sharp.csproj">

LibGit2Sharp/Advanced/Indexer.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System;
2+
using System.IO;
3+
using LibGit2Sharp.Core;
4+
using LibGit2Sharp.Handlers;
5+
using LibGit2Sharp.Core.Handles;
6+
7+
namespace LibGit2Sharp.Advanced
8+
{
9+
public class Indexer
10+
{
11+
12+
readonly IndexerSafeHandle handle;
13+
readonly TransferProgressHandler callback;
14+
15+
GitTransferProgress progress;
16+
byte[] buffer;
17+
18+
/// <summary>
19+
/// The indexing progress
20+
/// </summary>
21+
/// <value>The progres information for the current operation.</value>
22+
public TransferProgress Progress
23+
{
24+
get
25+
{
26+
return new TransferProgress(progress);
27+
}
28+
}
29+
30+
public Indexer(string prefix, uint mode, ObjectDatabase odb = null, TransferProgressHandler onProgress = null)
31+
{
32+
ObjectDatabaseSafeHandle odbHandle = odb != null ? odb.Handle : null;
33+
handle = Proxy.git_indexer_new(prefix, odbHandle, mode, onProgress);
34+
progress = new GitTransferProgress();
35+
}
36+
37+
/// <summary>
38+
/// Index the packfile at the specified path. This function runs synchronously and should usually be run
39+
/// in a background thread.
40+
/// </summary>
41+
/// <param name="path">The packfile's path</param>
42+
public ObjectId Index(string path)
43+
{
44+
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
45+
{
46+
return Index(fs);
47+
}
48+
}
49+
50+
/// <summary>
51+
/// Index the packfile from the specified stream. This function runs synchronously and should usually be run
52+
/// in a background thread.
53+
/// </summary>
54+
/// <param name="stream">The stream from which to read the packfile data</param>
55+
public ObjectId Index(Stream stream)
56+
{
57+
buffer = new byte[65536];
58+
int read;
59+
60+
do
61+
{
62+
read = stream.Read(buffer, 0, buffer.Length);
63+
Proxy.git_indexer_append(handle, buffer, (UIntPtr)read, ref progress);
64+
} while (read > 0);
65+
66+
Proxy.git_indexer_commit(handle, ref progress);
67+
68+
return Proxy.git_indexer_hash(handle);
69+
}
70+
}
71+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
namespace LibGit2Sharp.Core.Handles
3+
{
4+
internal class IndexerSafeHandle : SafeHandleBase
5+
{
6+
protected override bool ReleaseHandleImpl()
7+
{
8+
Proxy.git_indexer_free(handle);
9+
return true;
10+
}
11+
}
12+
}
13+

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,27 @@ internal static extern int git_treebuilder_insert(
13271327

13281328
[DllImport(libgit2)]
13291329
internal static extern int git_blob_is_binary(GitObjectSafeHandle blob);
1330+
1331+
[DllImport(libgit2)]
1332+
public static extern int git_indexer_new(
1333+
out IndexerSafeHandle idx,
1334+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictFilePathMarshaler))] FilePath prefix,
1335+
uint mode,
1336+
ObjectDatabaseSafeHandle odbHandle,
1337+
git_transfer_progress_callback callback,
1338+
IntPtr payload);
1339+
1340+
[DllImport(libgit2)]
1341+
public static extern int git_indexer_append(IndexerSafeHandle idx, byte[] data, UIntPtr size, ref GitTransferProgress progress);
1342+
1343+
[DllImport(libgit2)]
1344+
public static extern int git_indexer_commit(IndexerSafeHandle idx, ref GitTransferProgress progress);
1345+
1346+
[DllImport(libgit2)]
1347+
public static extern OidSafeHandle git_indexer_hash(IndexerSafeHandle idx);
1348+
1349+
[DllImport(libgit2)]
1350+
public static extern void git_indexer_free(IntPtr idx);
13301351
}
13311352
}
13321353
// ReSharper restore InconsistentNaming

LibGit2Sharp/Core/Proxy.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,52 @@ public static ObjectId git_tree_create_fromindex(Index index)
921921

922922
#endregion
923923

924+
#region git_indexer_
925+
926+
public static IndexerSafeHandle git_indexer_new(FilePath prefix, ObjectDatabaseSafeHandle odbHandle, uint mode,
927+
NativeMethods.git_transfer_progress_callback progressCallback)
928+
{
929+
using (ThreadAffinity())
930+
{
931+
IndexerSafeHandle handle;
932+
933+
int res = NativeMethods.git_indexer_new(out handle, prefix, mode, odbHandle, progressCallback, IntPtr.Zero);
934+
Ensure.ZeroResult(res);
935+
936+
return handle;
937+
}
938+
}
939+
940+
public static void git_indexer_append(IndexerSafeHandle handle, byte[] data, UIntPtr length, ref GitTransferProgress progress)
941+
{
942+
using (ThreadAffinity())
943+
{
944+
int res = NativeMethods.git_indexer_append(handle, data, length, ref progress);
945+
Ensure.ZeroResult(res);
946+
}
947+
}
948+
949+
public static void git_indexer_commit(IndexerSafeHandle handle, ref GitTransferProgress progress)
950+
{
951+
using (ThreadAffinity())
952+
{
953+
int res = NativeMethods.git_indexer_commit(handle, ref progress);
954+
Ensure.ZeroResult(res);
955+
}
956+
}
957+
958+
public static ObjectId git_indexer_hash(IndexerSafeHandle handle)
959+
{
960+
return NativeMethods.git_indexer_hash(handle).MarshalAsObjectId();
961+
}
962+
963+
public static void git_indexer_free(IntPtr handle)
964+
{
965+
NativeMethods.git_indexer_free(handle);
966+
}
967+
968+
#endregion
969+
924970
#region git_merge_
925971

926972
public static ObjectId git_merge_base(RepositorySafeHandle repo, Commit first, Commit second)

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ IEnumerator IEnumerable.GetEnumerator()
6060

6161
#endregion
6262

63+
internal ObjectDatabaseSafeHandle Handle
64+
{
65+
get { return handle; }
66+
}
67+
6368
/// <summary>
6469
/// Determines if the given object can be found in the object database.
6570
/// </summary>

0 commit comments

Comments
 (0)