Skip to content

Commit 2eb72b5

Browse files
committed
Add Archive() to ObjectDatabase
1 parent 27cd2dc commit 2eb72b5

File tree

5 files changed

+194
-0
lines changed

5 files changed

+194
-0
lines changed

LibGit2Sharp.Tests/ArchiveFixture.cs

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System;
2+
using System.Collections;
3+
using System.IO;
4+
using LibGit2Sharp.Tests.TestHelpers;
5+
using Xunit;
6+
7+
namespace LibGit2Sharp.Tests
8+
{
9+
public class ArchiveFixture : BaseFixture
10+
{
11+
[Fact]
12+
public void CanArchiveATree()
13+
{
14+
using (var repo = new Repository(BareTestRepoPath))
15+
{
16+
var tree = repo.Lookup<Tree>("581f9824ecaf824221bd36edf5430f2739a7c4f5");
17+
18+
var archiver = new MockArchiver();
19+
20+
repo.ObjectDatabase.Archive(tree, archiver);
21+
22+
var expected = new ArrayList
23+
{
24+
new { Path = "1", Sha = "7f76480d939dc401415927ea7ef25c676b8ddb8f" },
25+
new { Path = Path.Combine("1", "branch_file.txt"), Sha = "45b983be36b73c0788dc9cbcb76cbb80fc7bb057" },
26+
new { Path = "README", Sha = "a8233120f6ad708f843d861ce2b7228ec4e3dec6" },
27+
new { Path = "branch_file.txt", Sha = "45b983be36b73c0788dc9cbcb76cbb80fc7bb057" },
28+
new { Path = "new.txt", Sha = "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd" },
29+
};
30+
Assert.Equal(expected, archiver.Files);
31+
Assert.Null(archiver.ReceivedCommitSha);
32+
Assert.InRange(archiver.ModificationTime, DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(100)), DateTimeOffset.UtcNow);
33+
}
34+
}
35+
36+
[Fact]
37+
public void CanArchiveACommit()
38+
{
39+
using (var repo = new Repository(BareTestRepoPath))
40+
{
41+
var commit = repo.Lookup<Commit>("4c062a6361ae6959e06292c1fa5e2822d9c96345");
42+
43+
var archiver = new MockArchiver();
44+
45+
repo.ObjectDatabase.Archive(commit, archiver);
46+
47+
var expected = new ArrayList
48+
{
49+
new { Path = "1", Sha = "7f76480d939dc401415927ea7ef25c676b8ddb8f" },
50+
new { Path = Path.Combine("1", "branch_file.txt"), Sha = "45b983be36b73c0788dc9cbcb76cbb80fc7bb057" },
51+
new { Path = "README", Sha = "a8233120f6ad708f843d861ce2b7228ec4e3dec6" },
52+
new { Path = "branch_file.txt", Sha = "45b983be36b73c0788dc9cbcb76cbb80fc7bb057" },
53+
new { Path = "new.txt", Sha = "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd" },
54+
};
55+
Assert.Equal(expected, archiver.Files);
56+
Assert.Equal(commit.Sha, archiver.ReceivedCommitSha);
57+
Assert.Equal(commit.Committer.When, archiver.ModificationTime);
58+
}
59+
}
60+
61+
[Fact]
62+
public void ArchivingANullTreeOrCommitThrows()
63+
{
64+
using (var repo = new Repository(BareTestRepoPath))
65+
{
66+
Assert.Throws<ArgumentNullException>(() => repo.ObjectDatabase.Archive((Commit)null, null));
67+
Assert.Throws<ArgumentNullException>(() => repo.ObjectDatabase.Archive((Tree)null, null));
68+
}
69+
}
70+
71+
#region MockArchiver
72+
73+
private class MockArchiver : ArchiverBase
74+
{
75+
public readonly ArrayList Files = new ArrayList();
76+
public string ReceivedCommitSha;
77+
public DateTimeOffset ModificationTime;
78+
79+
#region Overrides of ArchiverBase
80+
81+
public override void BeforeArchiving(Tree tree, ObjectId oid, DateTimeOffset modificationTime)
82+
{
83+
if (oid != null)
84+
{
85+
ReceivedCommitSha = oid.Sha;
86+
}
87+
ModificationTime = modificationTime;
88+
}
89+
90+
protected override void AddTreeEntry(string path, TreeEntry entry, DateTimeOffset modificationTime)
91+
{
92+
Files.Add(new { Path = path, entry.Target.Sha });
93+
}
94+
95+
#endregion
96+
}
97+
98+
#endregion
99+
}
100+
}

LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<Compile Include="SubmoduleFixture.cs" />
7777
<Compile Include="IgnoreFixture.cs" />
7878
<Compile Include="FetchHeadFixture.cs" />
79+
<Compile Include="ArchiveFixture.cs" />
7980
<Compile Include="MergeFixture.cs" />
8081
<Compile Include="CleanFixture.cs" />
8182
<Compile Include="CurrentOperationFixture.cs" />

LibGit2Sharp/ArchiverBase.cs

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
5+
namespace LibGit2Sharp
6+
{
7+
/// <summary>
8+
/// The archiving method needs to be passed an inheritor of this class, which will then be used
9+
/// to provide low-level archiving facilities (tar, zip, ...).
10+
/// <para>
11+
/// <see cref="ObjectDatabase.Archive(LibGit2Sharp.Commit,LibGit2Sharp.ArchiverBase)"/>
12+
/// </para>
13+
/// </summary>
14+
public abstract class ArchiverBase
15+
{
16+
/// <summary>
17+
/// Override this method to perform operations before the archiving of each entry of the tree takes place.
18+
/// </summary>
19+
/// <param name="tree">The tree that will be archived</param>
20+
/// <param name="oid">The ObjectId of the commit being archived, or null if there is no commit.</param>
21+
/// <param name="modificationTime">The modification time that will be used for the files in the archive.</param>
22+
public virtual void BeforeArchiving(Tree tree, ObjectId oid, DateTimeOffset modificationTime)
23+
{ }
24+
25+
/// <summary>
26+
/// Override this method to perform operations after the archiving of each entry of the tree took place.
27+
/// </summary>
28+
/// <param name="tree">The tree that was archived</param>
29+
/// <param name="oid">The ObjectId of the commit being archived, or null if there is no commit.</param>
30+
/// <param name="modificationTime">The modification time that was used for the files in the archive.</param>
31+
public virtual void AfterArchiving(Tree tree, ObjectId oid, DateTimeOffset modificationTime)
32+
{ }
33+
34+
internal void OrchestrateArchiving(Tree tree, ObjectId oid, DateTimeOffset modificationTime)
35+
{
36+
BeforeArchiving(tree, oid, modificationTime);
37+
38+
ArchiveTree(tree, "", modificationTime);
39+
40+
AfterArchiving(tree, oid, modificationTime);
41+
}
42+
43+
private void ArchiveTree(IEnumerable<TreeEntry> tree, string path, DateTimeOffset modificationTime)
44+
{
45+
foreach (var entry in tree)
46+
{
47+
AddTreeEntry(Path.Combine(path, entry.Name), entry, modificationTime);
48+
49+
// Recurse if we have subtrees
50+
if (entry.Mode == Mode.Directory)
51+
{
52+
ArchiveTree((Tree)entry.Target, Path.Combine(path, entry.Name), modificationTime);
53+
}
54+
}
55+
}
56+
57+
/// <summary>
58+
/// Implements the archiving of a TreeEntry in a given format.
59+
/// </summary>
60+
/// <param name="path">The path of the entry in the archive.</param>
61+
/// <param name="entry">The entry to archive.</param>
62+
/// <param name="modificationTime">The datetime the entry was last modified.</param>
63+
protected abstract void AddTreeEntry(string path, TreeEntry entry, DateTimeOffset modificationTime);
64+
}
65+
}

LibGit2Sharp/LibGit2Sharp.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
</ItemGroup>
5757
<ItemGroup>
5858
<Compile Include="AmbiguousSpecificationException.cs" />
59+
<Compile Include="ArchiverBase.cs" />
5960
<Compile Include="BareRepositoryException.cs" />
6061
<Compile Include="BlameHunkCollection.cs" />
6162
<Compile Include="BlameHunk.cs" />

LibGit2Sharp/ObjectDatabase.cs

+27
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Runtime.InteropServices;
88
using LibGit2Sharp.Core;
99
using LibGit2Sharp.Core.Handles;
10+
using LibGit2Sharp.Handlers;
1011

1112
namespace LibGit2Sharp
1213
{
@@ -236,6 +237,32 @@ public virtual TagAnnotation CreateTagAnnotation(string name, GitObject target,
236237
return repo.Lookup<TagAnnotation>(tagId);
237238
}
238239

240+
/// <summary>
241+
/// Archive the given commit.
242+
/// </summary>
243+
/// <param name="commit">The commit.</param>
244+
/// <param name="archiver">The archiver to use.</param>
245+
public virtual void Archive(Commit commit, ArchiverBase archiver)
246+
{
247+
Ensure.ArgumentNotNull(commit, "commit");
248+
Ensure.ArgumentNotNull(archiver, "archiver");
249+
250+
archiver.OrchestrateArchiving(commit.Tree, commit.Id, commit.Committer.When);
251+
}
252+
253+
/// <summary>
254+
/// Archive the given tree.
255+
/// </summary>
256+
/// <param name="tree">The tree.</param>
257+
/// <param name="archiver">The archiver to use.</param>
258+
public virtual void Archive(Tree tree, ArchiverBase archiver)
259+
{
260+
Ensure.ArgumentNotNull(tree, "tree");
261+
Ensure.ArgumentNotNull(archiver, "archiver");
262+
263+
archiver.OrchestrateArchiving(tree, null, DateTimeOffset.UtcNow);
264+
}
265+
239266
/// <summary>
240267
/// Returns the merge base (best common ancestor) of the given commits
241268
/// and the distance between each of these commits and this base.

0 commit comments

Comments
 (0)