using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Handles;
namespace LibGit2Sharp
{
///
/// Provides methods to directly work against the Git object database
/// without involving the index nor the working directory.
///
public class ObjectDatabase
{
private readonly Repository repo;
private readonly ObjectDatabaseSafeHandle handle;
internal ObjectDatabase(Repository repo)
{
this.repo = repo;
Ensure.Success(NativeMethods.git_repository_odb(out handle, repo.Handle));
repo.RegisterForCleanup(handle);
}
///
/// Determines if the given object can be found in the object database.
///
/// Identifier of the object being searched for.
/// True if the object has been found; false otherwise.
public bool Contains(ObjectId objectId)
{
var oid = objectId.Oid;
return NativeMethods.git_odb_exists(handle, ref oid) != (int)GitErrorCode.GIT_OK;
}
///
/// Inserts a into the object database, created from the content of a file.
///
/// Path to the file to create the blob from.
/// The created .
public Blob CreateBlob(string path)
{
Ensure.ArgumentNotNullOrEmptyString(path, "path");
var oid = new GitOid();
if (!repo.Info.IsBare && !Path.IsPathRooted(path))
{
Ensure.Success(NativeMethods.git_blob_create_fromfile(ref oid, repo.Handle, path));
}
else
{
Ensure.Success(NativeMethods.git_blob_create_fromdisk(ref oid, repo.Handle, path));
}
return repo.Lookup(new ObjectId(oid));
}
///
/// Inserts a into the object database, created from a .
///
/// The .
/// The created .
public Tree CreateTree(TreeDefinition treeDefinition)
{
return treeDefinition.Build(repo);
}
///
/// Inserts a into the object database, referencing an existing .
///
/// The description of why a change was made to the repository.
/// The of who made the change.
/// The of who added the change to the repository.
/// The of the to be created.
/// The parents of the to be created.
/// The created .
public Commit CreateCommit(string message, Signature author, Signature committer, Tree tree, IEnumerable parents)
{
return CreateCommit(message, author, committer, tree, parents, null);
}
internal Commit CreateCommit(string message, Signature author, Signature committer, Tree tree, IEnumerable parents, string referenceName)
{
Ensure.ArgumentNotNull(message, "message");
Ensure.ArgumentNotNull(author, "author");
Ensure.ArgumentNotNull(committer, "committer");
Ensure.ArgumentNotNull(tree, "tree");
Ensure.ArgumentNotNull(parents, "parents");
IEnumerable parentIds = parents.Select(p => p.Id);
GitOid commitOid;
using (var treePtr = new ObjectSafeWrapper(tree.Id, repo))
using (var parentObjectPtrs = new DisposableEnumerable(parentIds.Select(id => new ObjectSafeWrapper(id, repo))))
using (SignatureSafeHandle authorHandle = author.BuildHandle())
using (SignatureSafeHandle committerHandle = committer.BuildHandle())
{
string encoding = null; //TODO: Handle the encoding of the commit to be created
IntPtr[] parentsPtrs = parentObjectPtrs.Select(o => o.ObjectPtr.DangerousGetHandle()).ToArray();
int res = NativeMethods.git_commit_create(out commitOid, repo.Handle, referenceName, authorHandle,
committerHandle, encoding, message, treePtr.ObjectPtr, parentObjectPtrs.Count(), parentsPtrs);
Ensure.Success(res);
}
return repo.Lookup(new ObjectId(commitOid));
}
}
}