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)); } } }