Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2sharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2012-04-16 23:56:18 +0400
committernulltoken <emeric.fermas@gmail.com>2012-04-28 05:32:17 +0400
commit660d27aff85f01c608dbe1b014c3d1bc9faa3939 (patch)
treeed6095b6b24b491ef65dc47923e3747944cb535f
parent77fd1e48d22b99dbcac789ae014edaf9328776c2 (diff)
Add Repository.ObjectDatabase.CreateTree()
-rw-r--r--LibGit2Sharp.Tests/ObjectDatabaseFixture.cs59
-rw-r--r--LibGit2Sharp/Core/Handles/TreeBuilderSafeHandle.cs11
-rw-r--r--LibGit2Sharp/Core/NativeMethods.cs17
-rw-r--r--LibGit2Sharp/LibGit2Sharp.csproj1
-rw-r--r--LibGit2Sharp/ObjectDatabase.cs10
-rw-r--r--LibGit2Sharp/TreeDefinition.cs61
6 files changed, 159 insertions, 0 deletions
diff --git a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs
index bc613302..fbece8f0 100644
--- a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs
+++ b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs
@@ -45,5 +45,64 @@ namespace LibGit2Sharp.Tests
Assert.Equal(blob, fetchedBlob);
}
}
+
+ [Theory]
+ [InlineData("README")]
+ [InlineData("README AS WELL")]
+ [InlineData("2/README AS WELL")]
+ [InlineData("1/README AS WELL")]
+ [InlineData("1")]
+ public void CanCreateATreeByAlteringAnExistingOne(string targetPath)
+ {
+ TemporaryCloneOfTestRepo scd = BuildTemporaryCloneOfTestRepo();
+
+ using (var repo = new Repository(scd.RepositoryPath))
+ {
+ var blob = repo.Lookup<Blob>(new ObjectId("a8233120f6ad708f843d861ce2b7228ec4e3dec6"));
+
+ TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree)
+ .Add(targetPath, blob, Mode.NonExecutableFile);
+
+ Tree tree = repo.ObjectDatabase.CreateTree(td);
+ Assert.NotNull(tree);
+ }
+ }
+
+ [Fact]
+ public void CanCreateAnEmptyTree()
+ {
+ TemporaryCloneOfTestRepo scd = BuildTemporaryCloneOfTestRepo();
+
+ using (var repo = new Repository(scd.RepositoryPath))
+ {
+ var td = new TreeDefinition();
+
+ Tree tree = repo.ObjectDatabase.CreateTree(td);
+ Assert.NotNull(tree);
+ Assert.Equal("4b825dc642cb6eb9a060e54bf8d69288fbee4904", tree.Sha);
+ }
+ }
+
+ [Fact]
+ public void CanReplaceAnExistingTreeWithAnotherPersitedTree()
+ {
+ TemporaryCloneOfTestRepo scd = BuildTemporaryCloneOfTestRepo();
+
+ using (var repo = new Repository(scd.RepositoryPath))
+ {
+ TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
+ Assert.Equal(GitObjectType.Tree, td["1"].Type);
+
+ TreeDefinition newTd = new TreeDefinition()
+ .Add("new/one", repo.Lookup<Blob>("a823312"), Mode.NonExecutableFile)
+ .Add("new/two", repo.Lookup<Blob>("a71586c"), Mode.NonExecutableFile)
+ .Add("new/tree", repo.Lookup<Tree>("7f76480"));
+
+ repo.ObjectDatabase.CreateTree(newTd);
+
+ td.Add("1", newTd["new"]);
+ Assert.Equal(GitObjectType.Tree, td["1/tree"].Type);
+ }
+ }
}
}
diff --git a/LibGit2Sharp/Core/Handles/TreeBuilderSafeHandle.cs b/LibGit2Sharp/Core/Handles/TreeBuilderSafeHandle.cs
new file mode 100644
index 00000000..5ba90a44
--- /dev/null
+++ b/LibGit2Sharp/Core/Handles/TreeBuilderSafeHandle.cs
@@ -0,0 +1,11 @@
+namespace LibGit2Sharp.Core.Handles
+{
+ internal class TreeBuilderSafeHandle : SafeHandleBase
+ {
+ protected override bool ReleaseHandle()
+ {
+ NativeMethods.git_treebuilder_free(handle);
+ return true;
+ }
+ }
+}
diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs
index d739ea64..864b07d3 100644
--- a/LibGit2Sharp/Core/NativeMethods.cs
+++ b/LibGit2Sharp/Core/NativeMethods.cs
@@ -507,5 +507,22 @@ namespace LibGit2Sharp.Core
[DllImport(libgit2)]
public static extern int git_tree_get_subtree(out GitObjectSafeHandle tree, GitObjectSafeHandle root,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath treeentry_path);
+
+ [DllImport(libgit2)]
+ public static extern int git_treebuilder_create(out TreeBuilderSafeHandle builder, IntPtr src);
+
+ [DllImport(libgit2)]
+ public static extern int git_treebuilder_insert(
+ IntPtr entry_out,
+ TreeBuilderSafeHandle builder,
+ [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string treeentry_name,
+ ref GitOid id,
+ uint attributes);
+
+ [DllImport(libgit2)]
+ public static extern int git_treebuilder_write(out GitOid oid, RepositorySafeHandle repo, TreeBuilderSafeHandle bld);
+
+ [DllImport(libgit2)]
+ public static extern int git_treebuilder_free(IntPtr bld);
}
}
diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj
index 4e6451e2..6fb0edf9 100644
--- a/LibGit2Sharp/LibGit2Sharp.csproj
+++ b/LibGit2Sharp/LibGit2Sharp.csproj
@@ -65,6 +65,7 @@
<Compile Include="Core\Handles\IndexEntrySafeHandle.cs" />
<Compile Include="Core\Handles\NotOwnedSafeHandleBase.cs" />
<Compile Include="Core\Handles\OidSafeHandle.cs" />
+ <Compile Include="Core\Handles\TreeBuilderSafeHandle.cs" />
<Compile Include="Core\ReferenceExtensions.cs" />
<Compile Include="Core\Handles\ReferenceSafeHandle.cs" />
<Compile Include="Core\Handles\SignatureSafeHandle.cs" />
diff --git a/LibGit2Sharp/ObjectDatabase.cs b/LibGit2Sharp/ObjectDatabase.cs
index 293cf8de..1a430440 100644
--- a/LibGit2Sharp/ObjectDatabase.cs
+++ b/LibGit2Sharp/ObjectDatabase.cs
@@ -49,5 +49,15 @@ namespace LibGit2Sharp
Ensure.Success(NativeMethods.git_blob_create_fromfile(ref oid, repo.Handle, path));
return repo.Lookup<Blob>(new ObjectId(oid));
}
+
+ /// <summary>
+ /// Inserts a <see cref = "Tree"/> into the object database, created from a <see cref = "TreeDefinition"/>.
+ /// </summary>
+ /// <param name = "treeDefinition">The <see cref = "TreeDefinition"/>.</param>
+ /// <returns>The created <see cref = "Tree"/>.</returns>
+ public Tree CreateTree(TreeDefinition treeDefinition)
+ {
+ return treeDefinition.Build(repo);
+ }
}
}
diff --git a/LibGit2Sharp/TreeDefinition.cs b/LibGit2Sharp/TreeDefinition.cs
index dddccd25..8ebe90e7 100644
--- a/LibGit2Sharp/TreeDefinition.cs
+++ b/LibGit2Sharp/TreeDefinition.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Compat;
+using LibGit2Sharp.Core.Handles;
namespace LibGit2Sharp
{
@@ -162,6 +163,36 @@ namespace LibGit2Sharp
return td;
}
+ internal Tree Build(Repository repository)
+ {
+ WrapAllTreeDefinitions(repository);
+
+ using (var builder = new TreeBuilder())
+ {
+ foreach (KeyValuePair<string, TreeEntryDefinition> kvp in entries)
+ {
+ string name = kvp.Key;
+ TreeEntryDefinition ted = kvp.Value;
+
+ builder.Insert(name, ted);
+ }
+
+ ObjectId treeId = builder.Write(repository);
+ return repository.Lookup<Tree>(treeId);
+ }
+ }
+
+ private void WrapAllTreeDefinitions(Repository repository)
+ {
+ foreach (KeyValuePair<string, TreeDefinition> pair in unwrappedTrees)
+ {
+ Tree tree = pair.Value.Build(repository);
+ entries[pair.Key] = TreeEntryDefinition.From(tree);
+ }
+
+ unwrappedTrees.Clear();
+ }
+
private void WrapTree(string entryName, TreeEntryDefinition treeEntryDefinition)
{
entries[entryName] = treeEntryDefinition;
@@ -203,5 +234,35 @@ namespace LibGit2Sharp
return new Tuple<string, string>(segments[0], segments.Length == 2 ? segments[1] : null);
}
+
+ private class TreeBuilder : IDisposable
+ {
+ private readonly TreeBuilderSafeHandle handle;
+
+ public TreeBuilder()
+ {
+ Ensure.Success(NativeMethods.git_treebuilder_create(out handle, IntPtr.Zero));
+ }
+
+ public void Insert(string name, TreeEntryDefinition treeEntryDefinition)
+ {
+ GitOid oid = treeEntryDefinition.TargetId.Oid;
+
+ Ensure.Success(NativeMethods.git_treebuilder_insert(IntPtr.Zero, handle, name, ref oid, (uint)treeEntryDefinition.Mode));
+ }
+
+ public ObjectId Write(Repository repo)
+ {
+ GitOid oid;
+ Ensure.Success(NativeMethods.git_treebuilder_write(out oid, repo.Handle, handle));
+
+ return new ObjectId(oid);
+ }
+
+ public void Dispose()
+ {
+ handle.SafeDispose();
+ }
+ }
}
}