Skip to content

Commit f06b942

Browse files
committed
Exposing Packbuilder capabilities of libgit2
1 parent ac4c7d9 commit f06b942

File tree

5 files changed

+247
-0
lines changed

5 files changed

+247
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace LibGit2Sharp.Core.Handles
2+
{
3+
internal class PackBuilderSafeHandle : SafeHandleBase
4+
{
5+
protected override bool ReleaseHandleImpl()
6+
{
7+
Proxy.git_packbuilder_free(handle);
8+
return true;
9+
}
10+
}
11+
}

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,51 @@ internal static extern int git_patch_line_stats(
938938
internal delegate int git_push_transfer_progress(uint current, uint total, UIntPtr bytes, IntPtr payload);
939939
internal delegate int git_packbuilder_progress(int stage, uint current, uint total, IntPtr payload);
940940

941+
[DllImport(libgit2)]
942+
internal static extern void git_packbuilder_free(IntPtr packbuilder);
943+
944+
[DllImport(libgit2)]
945+
internal static extern int git_packbuilder_insert(
946+
PackBuilderSafeHandle packbuilder,
947+
ref GitOid id,
948+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string name);
949+
950+
[DllImport(libgit2)]
951+
internal static extern int git_packbuilder_insert_commit(
952+
PackBuilderSafeHandle packbuilder,
953+
ref GitOid id);
954+
955+
[DllImport(libgit2)]
956+
internal static extern int git_packbuilder_insert_recur(
957+
PackBuilderSafeHandle packbuilder,
958+
ref GitOid id,
959+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string name);
960+
961+
[DllImport(libgit2)]
962+
internal static extern int git_packbuilder_insert_tree(
963+
PackBuilderSafeHandle packbuilder,
964+
ref GitOid id);
965+
966+
[DllImport(libgit2)]
967+
internal static extern int git_packbuilder_new(out PackBuilderSafeHandle packbuilder, RepositorySafeHandle repo);
968+
969+
[DllImport(libgit2)]
970+
internal static extern UInt32 git_packbuilder_object_count(PackBuilderSafeHandle packbuilder);
971+
972+
[DllImport(libgit2)]
973+
internal static extern UInt32 git_packbuilder_set_threads(PackBuilderSafeHandle packbuilder, UInt32 numThreads);
974+
975+
[DllImport(libgit2)]
976+
internal static extern int git_packbuilder_write(
977+
PackBuilderSafeHandle packbuilder,
978+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictFilePathMarshaler))] FilePath path,
979+
uint mode,
980+
IntPtr progressCallback,
981+
IntPtr payload);
982+
983+
[DllImport(libgit2)]
984+
internal static extern UInt32 git_packbuilder_written(PackBuilderSafeHandle packbuilder);
985+
941986
[DllImport(libgit2)]
942987
internal static extern int git_reference_create(
943988
out ReferenceSafeHandle reference,

LibGit2Sharp/Core/Proxy.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,6 +1549,77 @@ public static Tuple<int, int> git_patch_line_stats(PatchSafeHandle patch)
15491549

15501550
#endregion
15511551

1552+
#region git_packbuilder_
1553+
1554+
public static void git_packbuilder_free(IntPtr packbuilder)
1555+
{
1556+
NativeMethods.git_packbuilder_free(packbuilder);
1557+
}
1558+
1559+
public static PackBuilderSafeHandle git_packbuilder_new(RepositorySafeHandle repo)
1560+
{
1561+
PackBuilderSafeHandle handle;
1562+
1563+
int res = NativeMethods.git_packbuilder_new(out handle, repo);
1564+
Ensure.ZeroResult(res);
1565+
1566+
return handle;
1567+
}
1568+
1569+
public static void git_packbuilder_insert(PackBuilderSafeHandle packbuilder, ObjectId targetId, string name)
1570+
{
1571+
GitOid oid = targetId.Oid;
1572+
1573+
int res = NativeMethods.git_packbuilder_insert(packbuilder, ref oid, name);
1574+
Ensure.ZeroResult(res);
1575+
}
1576+
1577+
internal static void git_packbuilder_insert_commit(PackBuilderSafeHandle packbuilder, ObjectId targetId)
1578+
{
1579+
GitOid oid = targetId.Oid;
1580+
1581+
int res = NativeMethods.git_packbuilder_insert_commit(packbuilder, ref oid);
1582+
Ensure.ZeroResult(res);
1583+
}
1584+
1585+
internal static void git_packbuilder_insert_tree(PackBuilderSafeHandle packbuilder, ObjectId targetId)
1586+
{
1587+
GitOid oid = targetId.Oid;
1588+
1589+
int res = NativeMethods.git_packbuilder_insert_tree(packbuilder, ref oid);
1590+
Ensure.ZeroResult(res);
1591+
}
1592+
1593+
public static void git_packbuilder_insert_recur(PackBuilderSafeHandle packbuilder, ObjectId targetId, string name)
1594+
{
1595+
GitOid oid = targetId.Oid;
1596+
1597+
int res = NativeMethods.git_packbuilder_insert_recur(packbuilder, ref oid, name);
1598+
Ensure.ZeroResult(res);
1599+
}
1600+
1601+
public static uint git_packbuilder_set_threads(PackBuilderSafeHandle packbuilder, uint numThreads)
1602+
{
1603+
return NativeMethods.git_packbuilder_set_threads(packbuilder, numThreads);
1604+
}
1605+
1606+
public static void git_packbuilder_write(PackBuilderSafeHandle packbuilder, FilePath path)
1607+
{
1608+
int res = NativeMethods.git_packbuilder_write(packbuilder, path, 0, IntPtr.Zero, IntPtr.Zero);
1609+
Ensure.ZeroResult(res);
1610+
}
1611+
1612+
public static uint git_packbuilder_object_count(PackBuilderSafeHandle packbuilder)
1613+
{
1614+
return NativeMethods.git_packbuilder_object_count(packbuilder);
1615+
}
1616+
1617+
public static uint git_packbuilder_written(PackBuilderSafeHandle packbuilder)
1618+
{
1619+
return NativeMethods.git_packbuilder_written(packbuilder);
1620+
}
1621+
#endregion
1622+
15521623
#region git_rebase
15531624

15541625
public static RebaseSafeHandle git_rebase_init(

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
<Compile Include="Core\GitFetchOptions.cs" />
7474
<Compile Include="Core\GitPushUpdate.cs" />
7575
<Compile Include="Core\GitSubmoduleIgnore.cs" />
76+
<Compile Include="Core\Handles\PackBuilderSafeHandle.cs" />
7677
<Compile Include="Core\Platform.cs" />
7778
<Compile Include="Core\Handles\ConflictIteratorSafeHandle.cs" />
7879
<Compile Include="Core\GitWriteStream.cs" />
@@ -129,6 +130,7 @@
129130
<Compile Include="MergeTreeResult.cs" />
130131
<Compile Include="NotFoundException.cs" />
131132
<Compile Include="GitObjectMetadata.cs" />
133+
<Compile Include="PackBuilder.cs" />
132134
<Compile Include="PatchEntryChanges.cs" />
133135
<Compile Include="PatchStats.cs" />
134136
<Compile Include="PeelException.cs" />

LibGit2Sharp/PackBuilder.cs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
using System;
2+
using LibGit2Sharp.Core;
3+
using LibGit2Sharp.Core.Handles;
4+
5+
namespace LibGit2Sharp
6+
{
7+
/// <summary>
8+
/// Representation of a git packbuilder.
9+
/// </summary>
10+
public sealed class PackBuilder : IDisposable
11+
{
12+
private readonly PackBuilderSafeHandle packBuilderHandle;
13+
14+
/// <summary>
15+
/// Constructs a packbuilder from a repository.
16+
/// </summary>
17+
public PackBuilder(IRepository repository)
18+
{
19+
Repository repo = (Repository)repository;
20+
packBuilderHandle = Proxy.git_packbuilder_new(repo.Handle);
21+
}
22+
23+
/// <summary>
24+
/// Insert a single object to the packbuilder.
25+
/// For an optimal pack it's mandatory to insert objects in recency order, commits followed by trees and blobs. (quoted from libgit2 API ref)
26+
/// </summary>
27+
/// <param name="gitObject">The object to be inserted.</param>
28+
public void InsertObject(GitObject gitObject)
29+
{
30+
Proxy.git_packbuilder_insert(packBuilderHandle, gitObject.Id, null);
31+
}
32+
33+
/// <summary>
34+
/// Insert a <see cref="Tag"/> object to the packbuilder.
35+
/// </summary>
36+
/// <param name="tag">The tag object to be inserted.</param>
37+
public void InsertTag(Tag tag)
38+
{
39+
Proxy.git_packbuilder_insert(packBuilderHandle, tag.Target.Id, null);
40+
}
41+
42+
/// <summary>
43+
/// Insert a commit object. This will add a commit as well as the completed referenced tree.
44+
/// </summary>
45+
/// <param name="commit">The commit object to be inserted.</param>
46+
public void InsertCommit(Commit commit)
47+
{
48+
Proxy.git_packbuilder_insert_commit(packBuilderHandle, commit.Id);
49+
}
50+
51+
/// <summary>
52+
/// Insert a root tree object. This will add the tree as well as all referenced trees and blobs.
53+
/// </summary>
54+
/// <param name="tree">The tree object to be inserted.</param>
55+
public void InsertTree(Tree tree)
56+
{
57+
Proxy.git_packbuilder_insert_tree(packBuilderHandle, tree.Id);
58+
}
59+
60+
/// <summary>
61+
/// Recursively insert an object and its referenced objects. Inserts the object as well as any object it references.
62+
/// </summary>
63+
/// <param name="gitObject">The object to be recursively inserted.</param>
64+
public void InsertRecursively(GitObject gitObject)
65+
{
66+
Proxy.git_packbuilder_insert_recur(packBuilderHandle, gitObject.Id, null);
67+
}
68+
69+
/// <summary>
70+
/// Writes the new pack file and corresponding index file to path.
71+
/// </summary>
72+
/// <param name="path">The path that pack and index files will be written to it.</param>
73+
public void Write(string path)
74+
{
75+
Proxy.git_packbuilder_write(packBuilderHandle, path);
76+
}
77+
78+
/// <summary>
79+
/// Disposes the packbuilder object.
80+
/// </summary>
81+
public void Dispose()
82+
{
83+
packBuilderHandle.SafeDispose();
84+
}
85+
86+
/// <summary>
87+
/// Sets number of threads to spawn.
88+
/// </summary>
89+
/// <returns> Returns the number of actual threads to be used.</returns>
90+
/// <param name="nThread">The Number of threads to spawn. An argument of 0 enusures using all available CPUs</param>
91+
public int SetMaximumNumberOfThreads(int nThread)
92+
{
93+
// Libgit2 set the number of threads to 1 by default, 0 ensures git_online_cpus
94+
return (int)Proxy.git_packbuilder_set_threads(packBuilderHandle, (uint)nThread);
95+
}
96+
97+
/// <summary>
98+
/// Get the total number of objects the packbuilder will write out.
99+
/// </summary>
100+
public long ObjectsCount
101+
{
102+
get { return Proxy.git_packbuilder_object_count(packBuilderHandle); }
103+
}
104+
105+
/// <summary>
106+
/// Get the number of objects the packbuilder has already written out. This is only correct after the packfile has been written.
107+
/// </summary>
108+
public long WrittenObjectsCount
109+
{
110+
get { return Proxy.git_packbuilder_written(packBuilderHandle); }
111+
}
112+
113+
internal PackBuilderSafeHandle Handle
114+
{
115+
get { return packBuilderHandle; }
116+
}
117+
}
118+
}

0 commit comments

Comments
 (0)