Skip to content

Commit e0c3581

Browse files
committed
Adding Add<T> and AddRecursively<T> to PackBuilder. Adding some testing for them. Several edits and enhancements.
1 parent 173bc64 commit e0c3581

File tree

3 files changed

+112
-66
lines changed

3 files changed

+112
-66
lines changed

LibGit2Sharp.Tests/PackBuilderFixture.cs

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
1-
using LibGit2Sharp.Tests.TestHelpers;
2-
using System;
1+
using System;
32
using System.IO;
43
using System.Linq;
4+
using LibGit2Sharp.Tests.TestHelpers;
55
using Xunit;
66

77
namespace LibGit2Sharp.Tests
88
{
99
public class PackBuilderFixture : BaseFixture
1010
{
1111
[Fact]
12-
public void TestDefaultBuildDelegate()
12+
public void TestDefaultPackDelegate()
1313
{
1414
TestIfSameRepoAfterPacking(null);
1515
}
1616

1717
[Fact]
18-
public void TestCommitsPerBranchBuildDelegate()
18+
public void TestCommitsPerBranchPackDelegate()
1919
{
20-
TestIfSameRepoAfterPacking(TestBuildDelegate);
20+
TestIfSameRepoAfterPacking(AddingObjectIdsTestDelegate);
2121
}
2222

23-
internal void TestIfSameRepoAfterPacking(Action<PackBuilder> buildingDelegate)
23+
[Fact]
24+
public void TestCommitsPerBranchIdsPackDelegate()
25+
{
26+
TestIfSameRepoAfterPacking(AddingObjectsTestDelegate);
27+
}
28+
29+
internal void TestIfSameRepoAfterPacking(Action<IRepository, PackBuilder> packDelegate)
2430
{
2531
// read a repo
2632
// pack with the provided action
@@ -29,22 +35,19 @@ internal void TestIfSameRepoAfterPacking(Action<PackBuilder> buildingDelegate)
2935
// compare
3036

3137
string orgRepoPath = SandboxPackBuilderTestRepo();
32-
SelfCleaningDirectory scd = BuildSelfCleaningDirectory(orgRepoPath + "_mrr");
33-
string mrrRepoPath = scd.DirectoryPath;
34-
string mrrRepoPathPackDirPath = mrrRepoPath + "/.git/objects";
38+
string mrrRepoPath = SandboxPackBuilderTestRepo();
39+
string mrrRepoPackDirPath = Path.Combine(mrrRepoPath + "/.git/objects");
3540

36-
DirectoryHelper.CopyFilesRecursively(new DirectoryInfo(orgRepoPath), new DirectoryInfo(mrrRepoPath));
37-
DirectoryHelper.DeleteDirectory(mrrRepoPathPackDirPath);
38-
Directory.CreateDirectory(mrrRepoPathPackDirPath);
39-
Directory.CreateDirectory(mrrRepoPathPackDirPath + "/pack");
41+
DirectoryHelper.DeleteDirectory(mrrRepoPackDirPath);
42+
Directory.CreateDirectory(mrrRepoPackDirPath + "/pack");
4043

41-
PackBuilderOptions packBuilderOptions = new PackBuilderOptions(mrrRepoPathPackDirPath + "/pack");
44+
PackBuilderOptions packBuilderOptions = new PackBuilderOptions(mrrRepoPackDirPath + "/pack");
4245

4346
using (Repository orgRepo = new Repository(orgRepoPath))
4447
{
4548
PackBuilderResults results;
46-
if (buildingDelegate != null)
47-
results = orgRepo.ObjectDatabase.Pack(packBuilderOptions, buildingDelegate);
49+
if (packDelegate != null)
50+
results = orgRepo.ObjectDatabase.Pack(packBuilderOptions, b => packDelegate(orgRepo, b));
4851
else
4952
results = orgRepo.ObjectDatabase.Pack(packBuilderOptions);
5053

@@ -55,7 +58,7 @@ internal void TestIfSameRepoAfterPacking(Action<PackBuilder> buildingDelegate)
5558
using (Repository mrrRepo = new Repository(mrrRepoPath))
5659
{
5760
// make sure the objects of the original repo are the same as the ones in the mirror repo
58-
// doing that by making sure the count is the same, and the set differnce is empty
61+
// doing that by making sure the count is the same, and the set difference is empty
5962
Assert.True(mrrRepo.ObjectDatabase.Count() == orgRepo.ObjectDatabase.Count() && !mrrRepo.ObjectDatabase.Except(orgRepo.ObjectDatabase).Any());
6063

6164
Assert.Equal(orgRepo.Commits.Count(), mrrRepo.Commits.Count());
@@ -65,15 +68,36 @@ internal void TestIfSameRepoAfterPacking(Action<PackBuilder> buildingDelegate)
6568
}
6669
}
6770

68-
internal void TestBuildDelegate(PackBuilder builder)
71+
internal void AddingObjectIdsTestDelegate(IRepository repo, PackBuilder builder)
6972
{
70-
foreach (Branch branch in builder.Repository.Branches)
73+
foreach (Branch branch in repo.Branches)
7174
{
7275
foreach (Commit commit in branch.Commits)
7376
{
7477
builder.AddRecursively(commit.Id);
7578
}
7679
}
80+
81+
foreach (Tag tag in repo.Tags)
82+
{
83+
builder.Add(tag.Target.Id);
84+
}
85+
}
86+
87+
internal void AddingObjectsTestDelegate(IRepository repo, PackBuilder builder)
88+
{
89+
foreach (Branch branch in repo.Branches)
90+
{
91+
foreach (Commit commit in branch.Commits)
92+
{
93+
builder.AddRecursively(commit);
94+
}
95+
}
96+
97+
foreach (Tag tag in repo.Tags)
98+
{
99+
builder.Add(tag.Target);
100+
}
77101
}
78102

79103
[Fact]
@@ -149,7 +173,7 @@ public void ExceptionIfAddNullObjectID()
149173
{
150174
Assert.Throws<ArgumentNullException>(() =>
151175
{
152-
orgRepo.ObjectDatabase.Pack(packBuilderOptions, (PackBuilder builder) =>
176+
orgRepo.ObjectDatabase.Pack(packBuilderOptions, builder =>
153177
{
154178
builder.Add(null);
155179
});
@@ -167,7 +191,7 @@ public void ExceptionIfAddRecursivelyNullObjectID()
167191
{
168192
Assert.Throws<ArgumentNullException>(() =>
169193
{
170-
orgRepo.ObjectDatabase.Pack(packBuilderOptions, (PackBuilder builder) =>
194+
orgRepo.ObjectDatabase.Pack(packBuilderOptions, builder =>
171195
{
172196
builder.AddRecursively(null);
173197
});

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -645,44 +645,45 @@ public virtual MergeTreeResult MergeCommits(Commit ours, Commit theirs, MergeTre
645645
}
646646

647647
/// <summary>
648-
/// Pack the objects in the <see cref="ObjectDatabase"/> and write a pack (.pack) and index (.idx) files for it.
648+
/// Packs all the objects in the <see cref="ObjectDatabase"/> and write a pack (.pack) and index (.idx) files for them.
649649
/// </summary>
650650
/// <param name="options">Packing options</param>
651651
/// This method will invoke the default action of packing all objects in an arbitrary order.
652652
/// <returns>Packing results</returns>
653653
public virtual PackBuilderResults Pack(PackBuilderOptions options)
654654
{
655-
return InternalPack(options, (PackBuilder builder) =>
655+
return InternalPack(options, builder =>
656656
{
657-
foreach (GitObject obj in this)
657+
foreach (GitObject obj in repo.ObjectDatabase)
658658
{
659659
builder.Add(obj.Id);
660660
}
661661
});
662662
}
663663

664664
/// <summary>
665-
/// Pack the objects in the <see cref="ObjectDatabase"/> and write a pack (.pack) and index (.idx) files for it.
665+
/// Packs objects in the <see cref="ObjectDatabase"/> chosen by the packDelegate action
666+
/// and write a pack (.pack) and index (.idx) files for them
666667
/// </summary>
667668
/// <param name="options">Packing options</param>
668-
/// <param name="buildDelegate">Packing action</param>
669+
/// <param name="packDelegate">Packing action</param>
669670
/// <returns>Packing results</returns>
670-
public virtual PackBuilderResults Pack(PackBuilderOptions options, Action<PackBuilder> buildDelegate)
671+
public virtual PackBuilderResults Pack(PackBuilderOptions options, Action<PackBuilder> packDelegate)
671672
{
672-
return InternalPack(options, buildDelegate);
673+
return InternalPack(options, packDelegate);
673674
}
674675

675676
/// <summary>
676-
/// Pack the objects in the <see cref="ObjectDatabase"/> and write a pack (.pack) and index (.idx) files for it. For internal use only.
677+
/// Packs objects in the <see cref="ObjectDatabase"/> and write a pack (.pack) and index (.idx) files for them.
678+
/// For internal use only.
677679
/// </summary>
678680
/// <param name="options">Packing options</param>
679-
/// <param name="buildDelegate">Packing action. If null is passed, the pack method will invoke the default action of packing
680-
/// all objects in an arbitrary order.</param>
681+
/// <param name="packDelegate">Packing action</param>
681682
/// <returns>Packing results</returns>
682-
private PackBuilderResults InternalPack(PackBuilderOptions options, Action<PackBuilder> buildDelegate)
683+
private PackBuilderResults InternalPack(PackBuilderOptions options, Action<PackBuilder> packDelegate)
683684
{
684685
Ensure.ArgumentNotNull(options, "options");
685-
Ensure.ArgumentNotNull(buildDelegate, "buildDelegate");
686+
Ensure.ArgumentNotNull(packDelegate, "packDelegate");
686687

687688
PackBuilderResults results = new PackBuilderResults();
688689

@@ -692,7 +693,7 @@ private PackBuilderResults InternalPack(PackBuilderOptions options, Action<PackB
692693
builder.SetMaximumNumberOfThreads(options.MaximumNumberOfThreads);
693694

694695
// call the provided action
695-
buildDelegate(builder);
696+
packDelegate(builder);
696697

697698
// writing the pack and index files
698699
builder.Write(options.PackDirectoryPath);

LibGit2Sharp/PackBuilder.cs

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
namespace LibGit2Sharp
77
{
88
/// <summary>
9-
/// Representation of a git packbuilder.
9+
/// Representation of a git PackBuilder.
1010
/// </summary>
1111
public sealed class PackBuilder : IDisposable
1212
{
1313
private readonly PackBuilderSafeHandle packBuilderHandle;
1414
private readonly Repository repo;
1515

1616
/// <summary>
17-
/// Constructs a packbuilder from a repository.
17+
/// Constructs a PackBuilder for a <see cref="Repository"/>.
1818
/// </summary>
1919
internal PackBuilder(Repository repository)
2020
{
@@ -25,81 +25,102 @@ internal PackBuilder(Repository repository)
2525
}
2626

2727
/// <summary>
28-
/// Inserts a single object to the packbuilder.
28+
/// Inserts a single <see cref="GitObject"/> to the PackBuilder.
2929
/// For an optimal pack it's mandatory to insert objects in recency order, commits followed by trees and blobs. (quoted from libgit2 API ref)
3030
/// </summary>
31-
/// <param name="gitObjectID">The object ID to be inserted.</param>
32-
public void Add(ObjectId gitObjectID)
31+
/// <param name="gitObject">The object to be inserted.</param>
32+
/// <exception cref="ArgumentNullException">if the gitObject is null</exception>
33+
public void Add<T>(T gitObject) where T : GitObject
3334
{
34-
Ensure.ArgumentNotNull(gitObjectID, "gitObject");
35+
Ensure.ArgumentNotNull(gitObject, "gitObject");
3536

36-
Proxy.git_packbuilder_insert(packBuilderHandle, gitObjectID, null);
37+
Add(gitObject.Id);
3738
}
3839

3940
/// <summary>
40-
/// Recursively insert an object and its referenced objects. Inserts the object as well as any object it references.
41+
/// Recursively inserts a <see cref="GitObject"/> and its referenced objects.
42+
/// Inserts the object as well as any object it references.
4143
/// </summary>
42-
/// <param name="gitObjectID">The object ID to be recursively inserted.</param>
43-
public void AddRecursively(ObjectId gitObjectID)
44+
/// <param name="gitObject">The object to be inserted recursively.</param>
45+
/// <exception cref="ArgumentNullException">if the gitObject is null</exception>
46+
public void AddRecursively<T>(T gitObject) where T : GitObject
4447
{
45-
Ensure.ArgumentNotNull(gitObjectID, "gitObject");
48+
Ensure.ArgumentNotNull(gitObject, "gitObject");
4649

47-
Proxy.git_packbuilder_insert_recur(packBuilderHandle, gitObjectID, null);
50+
AddRecursively(gitObject.Id);
4851
}
4952

5053
/// <summary>
51-
/// Writes the new pack file and corresponding index file to path.
54+
/// Inserts a single object to the PackBuilder by its <see cref="ObjectId"/>.
55+
/// For an optimal pack it's mandatory to insert objects in recency order, commits followed by trees and blobs. (quoted from libgit2 API ref)
5256
/// </summary>
53-
/// <param name="path">The path that pack and index files will be written to it.</param>
54-
internal void Write(string path)
57+
/// <param name="id">The object ID to be inserted.</param>
58+
/// <exception cref="ArgumentNullException">if the id is null</exception>
59+
public void Add(ObjectId id)
5560
{
56-
Proxy.git_packbuilder_write(packBuilderHandle, path);
61+
Ensure.ArgumentNotNull(id, "id");
62+
63+
Proxy.git_packbuilder_insert(packBuilderHandle, id, null);
5764
}
5865

5966
/// <summary>
60-
/// Disposes the packbuilder object.
67+
/// Recursively inserts an object and its referenced objects by its <see cref="ObjectId"/>.
68+
/// Inserts the object as well as any object it references.
69+
/// </summary>
70+
/// <param name="id">The object ID to be recursively inserted.</param>
71+
/// <exception cref="ArgumentNullException">if the id is null</exception>
72+
public void AddRecursively(ObjectId id)
73+
{
74+
Ensure.ArgumentNotNull(id, "id");
75+
76+
Proxy.git_packbuilder_insert_recur(packBuilderHandle, id, null);
77+
}
78+
79+
/// <summary>
80+
/// Disposes the PackBuilder object.
6181
/// </summary>
6282
public void Dispose()
6383
{
6484
packBuilderHandle.SafeDispose();
6585
}
6686

87+
/// <summary>
88+
/// Writes the pack file and corresponding index file to path.
89+
/// </summary>
90+
/// <param name="path">The path that pack and index files will be written to it.</param>
91+
internal void Write(string path)
92+
{
93+
Proxy.git_packbuilder_write(packBuilderHandle, path);
94+
}
95+
6796
/// <summary>
6897
/// Sets number of threads to spawn.
6998
/// </summary>
7099
/// <returns> Returns the number of actual threads to be used.</returns>
71-
/// <param name="nThread">The Number of threads to spawn. An argument of 0 enusures using all available CPUs</param>
100+
/// <param name="nThread">The Number of threads to spawn. An argument of 0 ensures using all available CPUs</param>
72101
internal int SetMaximumNumberOfThreads(int nThread)
73102
{
74103
// Libgit2 set the number of threads to 1 by default, 0 ensures git_online_cpus
75104
return (int)Proxy.git_packbuilder_set_threads(packBuilderHandle, (uint)nThread);
76105
}
77106

78107
/// <summary>
79-
/// Get the total number of objects the packbuilder will write out.
108+
/// Number of objects the PackBuilder will write out.
80109
/// </summary>
81110
internal long ObjectsCount
82111
{
83112
get { return Proxy.git_packbuilder_object_count(packBuilderHandle); }
84113
}
85114

86115
/// <summary>
87-
/// Number of objects the packbuilder has already written out.
88-
/// This is only correct after the packfile has been written.
116+
/// Number of objects the PackBuilder has already written out.
117+
/// This is only correct after the pack file has been written.
89118
/// </summary>
90119
internal long WrittenObjectsCount
91120
{
92121
get { return Proxy.git_packbuilder_written(packBuilderHandle); }
93122
}
94123

95-
/// <summary>
96-
/// A refernce to the repository that the packbuilder is working on.
97-
/// </summary>
98-
public Repository Repository
99-
{
100-
get { return repo; }
101-
}
102-
103124
internal PackBuilderSafeHandle Handle
104125
{
105126
get { return packBuilderHandle; }
@@ -112,7 +133,7 @@ internal PackBuilderSafeHandle Handle
112133
public struct PackBuilderResults
113134
{
114135
/// <summary>
115-
/// Number of objects the packbuilder has already written out.
136+
/// Number of objects the PackBuilder has already written out.
116137
/// </summary>
117138
public long WrittenObjectsCount { get; internal set; }
118139
}
@@ -129,7 +150,7 @@ public sealed class PackBuilderOptions
129150
/// The default value for maximum number of threads to spawn is 0 which ensures using all available CPUs.
130151
/// <exception cref="ArgumentNullException">if packDirectory is null or empty</exception>
131152
/// <exception cref="DirectoryNotFoundException">if packDirectory doesn't exist</exception>
132-
public PackBuilderOptions (string packDirectory)
153+
public PackBuilderOptions(string packDirectory)
133154
{
134155
PackDirectoryPath = packDirectory;
135156
MaximumNumberOfThreads = 0;
@@ -176,7 +197,7 @@ public int MaximumNumberOfThreads
176197
{
177198
return nThreads;
178199
}
179-
200+
180201
}
181202

182203
private string path;

0 commit comments

Comments
 (0)