using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using LibGit2Sharp.Core.Handles;
using LibGit2Sharp.Handlers;
// ReSharper disable InconsistentNaming
namespace LibGit2Sharp.Core
{
internal class Proxy
{
#region giterr_
public static void giterr_set_str(GitErrorCategory error_class, Exception exception)
{
if (exception is OutOfMemoryException)
{
NativeMethods.giterr_set_oom();
}
else
{
NativeMethods.giterr_set_str(error_class, ErrorMessageFromException(exception));
}
}
public static void giterr_set_str(GitErrorCategory error_class, String errorString)
{
NativeMethods.giterr_set_str(error_class, errorString);
}
///
/// This method will take an exception and try to generate an error message
/// that captures the important messages of the error.
/// The formatting is a bit subjective.
///
///
///
public static string ErrorMessageFromException(Exception ex)
{
StringBuilder sb = new StringBuilder();
BuildErrorMessageFromException(sb, 0, ex);
return sb.ToString();
}
private static void BuildErrorMessageFromException(StringBuilder sb, int level, Exception ex)
{
string indent = new string(' ', level * 4);
sb.AppendFormat("{0}{1}", indent, ex.Message);
if (ex is AggregateException)
{
AggregateException aggregateException = ((AggregateException)ex).Flatten();
if (aggregateException.InnerExceptions.Count == 1)
{
sb.AppendLine();
sb.AppendLine();
sb.AppendFormat("{0}Contained Exception:{1}", indent, Environment.NewLine);
BuildErrorMessageFromException(sb, level + 1, aggregateException.InnerException);
}
else
{
sb.AppendLine();
sb.AppendLine();
sb.AppendFormat("{0}Contained Exceptions:{1}", indent, Environment.NewLine);
for (int i = 0; i < aggregateException.InnerExceptions.Count; i++)
{
if (i != 0)
{
sb.AppendLine();
sb.AppendLine();
}
BuildErrorMessageFromException(sb, level + 1, aggregateException.InnerExceptions[i]);
}
}
}
else if (ex.InnerException != null)
{
sb.AppendLine();
sb.AppendLine();
sb.AppendFormat("{0}Inner Exception:{1}", indent, Environment.NewLine);
BuildErrorMessageFromException(sb, level + 1, ex.InnerException);
}
}
#endregion
#region git_blame_
public static unsafe BlameHandle git_blame_file(
RepositoryHandle repo,
FilePath path,
git_blame_options options)
{
git_blame* ptr;
int res = NativeMethods.git_blame_file(out ptr, repo, path, options);
Ensure.ZeroResult(res);
return new BlameHandle(ptr, true);
}
public static unsafe git_blame_hunk* git_blame_get_hunk_byindex(BlameHandle blame, uint idx)
{
return NativeMethods.git_blame_get_hunk_byindex(blame, idx);
}
#endregion
#region git_blob_
public static unsafe ObjectId git_blob_create_fromchunks(RepositoryHandle repo, FilePath hintpath, NativeMethods.source_callback fileCallback)
{
var oid = new GitOid();
int res = NativeMethods.git_blob_create_fromchunks(ref oid, repo, hintpath, fileCallback, IntPtr.Zero);
if (res == (int)GitErrorCode.User)
{
throw new EndOfStreamException("The stream ended unexpectedly");
}
Ensure.ZeroResult(res);
return oid;
}
public static unsafe ObjectId git_blob_create_fromdisk(RepositoryHandle repo, FilePath path)
{
var oid = new GitOid();
int res = NativeMethods.git_blob_create_fromdisk(ref oid, repo, path);
Ensure.ZeroResult(res);
return oid;
}
public static unsafe ObjectId git_blob_create_fromfile(RepositoryHandle repo, FilePath path)
{
var oid = new GitOid();
int res = NativeMethods.git_blob_create_fromworkdir(ref oid, repo, path);
Ensure.ZeroResult(res);
return oid;
}
public static unsafe UnmanagedMemoryStream git_blob_filtered_content_stream(RepositoryHandle repo, ObjectId id, FilePath path, bool check_for_binary_data)
{
var buf = new GitBuf();
var handle = new ObjectSafeWrapper(id, repo).ObjectPtr;
return new RawContentStream(handle, h =>
{
Ensure.ZeroResult(NativeMethods.git_blob_filtered_content(buf, h, path, check_for_binary_data));
return buf.ptr;
},
h => (long)buf.size,
new[] { buf });
}
public static unsafe UnmanagedMemoryStream git_blob_rawcontent_stream(RepositoryHandle repo, ObjectId id, Int64 size)
{
var handle = new ObjectSafeWrapper(id, repo).ObjectPtr;
return new RawContentStream(handle, h => NativeMethods.git_blob_rawcontent(h), h => size);
}
public static unsafe long git_blob_rawsize(ObjectHandle obj)
{
return NativeMethods.git_blob_rawsize(obj);
}
public static unsafe bool git_blob_is_binary(ObjectHandle obj)
{
int res = NativeMethods.git_blob_is_binary(obj);
Ensure.BooleanResult(res);
return (res == 1);
}
#endregion
#region git_branch_
public static unsafe ReferenceHandle git_branch_create_from_annotated(RepositoryHandle repo, string branch_name, string targetIdentifier, bool force)
{
git_reference* reference;
using (var annotatedCommit = git_annotated_commit_from_revspec(repo, targetIdentifier))
{
int res = NativeMethods.git_branch_create_from_annotated(out reference, repo, branch_name, annotatedCommit, force);
Ensure.ZeroResult(res);
}
return new ReferenceHandle(reference, true);
}
public static unsafe void git_branch_delete(ReferenceHandle reference)
{
int res = NativeMethods.git_branch_delete(reference);
Ensure.ZeroResult(res);
}
public static IEnumerable git_branch_iterator(Repository repo, GitBranchType branchType)
{
IntPtr iter;
var res = NativeMethods.git_branch_iterator_new(out iter, repo.Handle.AsIntPtr(), branchType);
Ensure.ZeroResult(res);
try
{
while (true)
{
IntPtr refPtr = IntPtr.Zero;
GitBranchType _branchType;
res = NativeMethods.git_branch_next(out refPtr, out _branchType, iter);
if (res == (int)GitErrorCode.IterOver)
{
yield break;
}
Ensure.ZeroResult(res);
Reference reference;
using (var refHandle = new ReferenceHandle(refPtr, true))
{
reference = Reference.BuildFromPtr(refHandle, repo);
}
yield return new Branch(repo, reference, reference.CanonicalName);
}
}
finally
{
NativeMethods.git_branch_iterator_free(iter);
}
}
public static void git_branch_iterator_free(IntPtr iter)
{
NativeMethods.git_branch_iterator_free(iter);
}
public static unsafe ReferenceHandle git_branch_move(ReferenceHandle reference, string new_branch_name, bool force)
{
git_reference* ref_out;
int res = NativeMethods.git_branch_move(out ref_out, reference, new_branch_name, force);
Ensure.ZeroResult(res);
return new ReferenceHandle(ref_out, true);
}
public static unsafe string git_branch_remote_name(RepositoryHandle repo, string canonical_branch_name, bool shouldThrowIfNotFound)
{
using (var buf = new GitBuf())
{
int res = NativeMethods.git_branch_remote_name(buf, repo, canonical_branch_name);
if (!shouldThrowIfNotFound &&
(res == (int)GitErrorCode.NotFound || res == (int)GitErrorCode.Ambiguous))
{
return null;
}
Ensure.ZeroResult(res);
return LaxUtf8Marshaler.FromNative(buf.ptr);
}
}
public static unsafe string git_branch_upstream_name(RepositoryHandle handle, string canonicalReferenceName)
{
using (var buf = new GitBuf())
{
int res = NativeMethods.git_branch_upstream_name(buf, handle, canonicalReferenceName);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return LaxUtf8Marshaler.FromNative(buf.ptr);
}
}
#endregion
#region git_buf_
public static void git_buf_free(GitBuf buf)
{
NativeMethods.git_buf_free(buf);
}
#endregion
#region git_checkout_
public static unsafe void git_checkout_tree(
RepositoryHandle repo,
ObjectId treeId,
ref GitCheckoutOpts opts)
{
using (var osw = new ObjectSafeWrapper(treeId, repo))
{
int res = NativeMethods.git_checkout_tree(repo, osw.ObjectPtr, ref opts);
Ensure.ZeroResult(res);
}
}
public static unsafe void git_checkout_index(RepositoryHandle repo, ObjectHandle treeish, ref GitCheckoutOpts opts)
{
int res = NativeMethods.git_checkout_index(repo, treeish, ref opts);
Ensure.ZeroResult(res);
}
#endregion
#region git_cherry_pick_
internal static unsafe void git_cherrypick(RepositoryHandle repo, ObjectId commit, GitCherryPickOptions options)
{
using (var nativeCommit = git_object_lookup(repo, commit, GitObjectType.Commit))
{
int res = NativeMethods.git_cherrypick(repo, nativeCommit, options);
Ensure.ZeroResult(res);
}
}
#endregion
#region git_clone_
public static unsafe RepositoryHandle git_clone(
string url,
string workdir,
ref GitCloneOptions opts)
{
git_repository *repo;
int res = NativeMethods.git_clone(out repo, url, workdir, ref opts);
Ensure.ZeroResult(res);
return new RepositoryHandle(repo, true);
}
#endregion
#region git_commit_
public static unsafe Signature git_commit_author(ObjectHandle obj)
{
return new Signature(NativeMethods.git_commit_author(obj));
}
public static unsafe Signature git_commit_committer(ObjectHandle obj)
{
return new Signature(NativeMethods.git_commit_committer(obj));
}
public static unsafe ObjectId git_commit_create(
RepositoryHandle repo,
string referenceName,
Signature author,
Signature committer,
string message,
Tree tree,
GitOid[] parentIds)
{
using (SignatureHandle authorHandle = author.BuildHandle())
using (SignatureHandle committerHandle = committer.BuildHandle())
using (var parentPtrs = new ArrayMarshaler(parentIds))
{
GitOid commitOid;
var treeOid = tree.Id.Oid;
int res = NativeMethods.git_commit_create_from_ids(out commitOid,
repo,
referenceName,
authorHandle,
committerHandle,
null,
message,
ref treeOid,
(UIntPtr)parentPtrs.Count,
parentPtrs.ToArray());
Ensure.ZeroResult(res);
return commitOid;
}
}
public static unsafe string git_commit_message(ObjectHandle obj)
{
return NativeMethods.git_commit_message(obj);
}
public static unsafe string git_commit_summary(ObjectHandle obj)
{
return NativeMethods.git_commit_summary(obj);
}
public static unsafe string git_commit_message_encoding(ObjectHandle obj)
{
return NativeMethods.git_commit_message_encoding(obj);
}
public static unsafe ObjectId git_commit_parent_id(ObjectHandle obj, uint i)
{
return ObjectId.BuildFromPtr(NativeMethods.git_commit_parent_id(obj, i));
}
public static int git_commit_parentcount(RepositoryHandle repo, ObjectId id)
{
using (var obj = new ObjectSafeWrapper(id, repo))
{
return git_commit_parentcount(obj);
}
}
public static unsafe int git_commit_parentcount(ObjectSafeWrapper obj)
{
return (int)NativeMethods.git_commit_parentcount(obj.ObjectPtr);
}
public static unsafe ObjectId git_commit_tree_id(ObjectHandle obj)
{
return ObjectId.BuildFromPtr(NativeMethods.git_commit_tree_id(obj));
}
#endregion
#region git_config_
public static unsafe void git_config_add_file_ondisk(ConfigurationHandle config, FilePath path, ConfigurationLevel level)
{
int res = NativeMethods.git_config_add_file_ondisk(config, path, (uint)level, true);
Ensure.ZeroResult(res);
}
public static unsafe bool git_config_delete(ConfigurationHandle config, string name)
{
int res = NativeMethods.git_config_delete_entry(config, name);
if (res == (int)GitErrorCode.NotFound)
{
return false;
}
Ensure.ZeroResult(res);
return true;
}
const string anyValue = ".*";
public static unsafe bool git_config_delete_multivar(ConfigurationHandle config, string name)
{
int res = NativeMethods.git_config_delete_multivar(config, name, anyValue);
if (res == (int)GitErrorCode.NotFound)
{
return false;
}
Ensure.ZeroResult(res);
return true;
}
public static FilePath git_config_find_global()
{
return ConvertPath(NativeMethods.git_config_find_global);
}
public static FilePath git_config_find_system()
{
return ConvertPath(NativeMethods.git_config_find_system);
}
public static FilePath git_config_find_xdg()
{
return ConvertPath(NativeMethods.git_config_find_xdg);
}
public static unsafe ConfigurationEntry git_config_get_entry(ConfigurationHandle config, string key)
{
if (!configurationParser.ContainsKey(typeof(T)))
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Generic Argument of type '{0}' is not supported.", typeof(T).FullName));
}
GitConfigEntry* entry = null;
try
{
var res = NativeMethods.git_config_get_entry(out entry, config, key);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return new ConfigurationEntry(LaxUtf8Marshaler.FromNative(entry->namePtr),
(T)configurationParser[typeof(T)](LaxUtf8Marshaler.FromNative(entry->valuePtr)),
(ConfigurationLevel)entry->level);
}
finally
{
NativeMethods.git_config_entry_free(entry);
}
}
public static unsafe ConfigurationHandle git_config_new()
{
git_config* handle;
int res = NativeMethods.git_config_new(out handle);
Ensure.ZeroResult(res);
return new ConfigurationHandle(handle, true);
}
public static unsafe ConfigurationHandle git_config_open_level(ConfigurationHandle parent, ConfigurationLevel level)
{
git_config* handle;
int res = NativeMethods.git_config_open_level(out handle, parent, (uint)level);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return new ConfigurationHandle(handle, true);
}
public static bool git_config_parse_bool(string value)
{
bool outVal;
var res = NativeMethods.git_config_parse_bool(out outVal, value);
Ensure.ZeroResult(res);
return outVal;
}
public static int git_config_parse_int32(string value)
{
int outVal;
var res = NativeMethods.git_config_parse_int32(out outVal, value);
Ensure.ZeroResult(res);
return outVal;
}
public static long git_config_parse_int64(string value)
{
long outVal;
var res = NativeMethods.git_config_parse_int64(out outVal, value);
Ensure.ZeroResult(res);
return outVal;
}
public static unsafe void git_config_set_bool(ConfigurationHandle config, string name, bool value)
{
int res = NativeMethods.git_config_set_bool(config, name, value);
Ensure.ZeroResult(res);
}
public static unsafe void git_config_set_int32(ConfigurationHandle config, string name, int value)
{
int res = NativeMethods.git_config_set_int32(config, name, value);
Ensure.ZeroResult(res);
}
public static unsafe void git_config_set_int64(ConfigurationHandle config, string name, long value)
{
int res = NativeMethods.git_config_set_int64(config, name, value);
Ensure.ZeroResult(res);
}
public static unsafe void git_config_set_string(ConfigurationHandle config, string name, string value)
{
int res = NativeMethods.git_config_set_string(config, name, value);
Ensure.ZeroResult(res);
}
public static unsafe ICollection git_config_foreach(
ConfigurationHandle config,
Func resultSelector)
{
return git_foreach(resultSelector, c => NativeMethods.git_config_foreach(config, (e, p) => c(e, p), IntPtr.Zero));
}
public static IEnumerable> git_config_iterator_glob(
ConfigurationHandle config,
string regexp)
{
IntPtr iter;
var res = NativeMethods.git_config_iterator_glob_new(out iter, config.AsIntPtr(), regexp);
Ensure.ZeroResult(res);
try
{
while (true)
{
IntPtr entry;
res = NativeMethods.git_config_next(out entry, iter);
if (res == (int)GitErrorCode.IterOver)
{
yield break;
}
Ensure.ZeroResult(res);
yield return Configuration.BuildConfigEntry(entry);
}
}
finally
{
NativeMethods.git_config_iterator_free(iter);
}
}
public static unsafe ConfigurationHandle git_config_snapshot(ConfigurationHandle config)
{
git_config* handle;
int res = NativeMethods.git_config_snapshot(out handle, config);
Ensure.ZeroResult(res);
return new ConfigurationHandle(handle, true);
}
#endregion
#region git_describe_
public static unsafe string git_describe_commit(
RepositoryHandle repo,
ObjectId committishId,
DescribeOptions options)
{
Ensure.ArgumentPositiveInt32(options.MinimumCommitIdAbbreviatedSize, "options.MinimumCommitIdAbbreviatedSize");
using (var osw = new ObjectSafeWrapper(committishId, repo))
{
GitDescribeOptions opts = new GitDescribeOptions
{
Version = 1,
DescribeStrategy = options.Strategy,
MaxCandidatesTags = 10,
OnlyFollowFirstParent = options.OnlyFollowFirstParent,
ShowCommitOidAsFallback = options.UseCommitIdAsFallback,
};
DescribeResultHandle describeHandle = null;
try
{
git_describe_result* result;
int res = NativeMethods.git_describe_commit(out result, osw.ObjectPtr, ref opts);
Ensure.ZeroResult(res);
describeHandle = new DescribeResultHandle(result, true);
using (var buf = new GitBuf())
{
GitDescribeFormatOptions formatOptions = new GitDescribeFormatOptions
{
Version = 1,
MinAbbreviatedSize = (uint)options.MinimumCommitIdAbbreviatedSize,
AlwaysUseLongFormat = options.AlwaysRenderLongFormat,
};
res = NativeMethods.git_describe_format(buf, describeHandle, ref formatOptions);
Ensure.ZeroResult(res);
describeHandle.Dispose();
return LaxUtf8Marshaler.FromNative(buf.ptr);
}
}
finally
{
if (describeHandle != null)
{
describeHandle.Dispose();
}
}
}
}
#endregion
#region git_diff_
public static unsafe void git_diff_blobs(
RepositoryHandle repo,
ObjectId oldBlob,
ObjectId newBlob,
GitDiffOptions options,
NativeMethods.git_diff_file_cb fileCallback,
NativeMethods.git_diff_hunk_cb hunkCallback,
NativeMethods.git_diff_line_cb lineCallback)
{
using (var osw1 = new ObjectSafeWrapper(oldBlob, repo, true))
using (var osw2 = new ObjectSafeWrapper(newBlob, repo, true))
{
int res = NativeMethods.git_diff_blobs(osw1.ObjectPtr,
null,
osw2.ObjectPtr,
null,
options,
fileCallback,
null,
hunkCallback,
lineCallback,
IntPtr.Zero);
Ensure.ZeroResult(res);
}
}
public static unsafe void git_diff_foreach(
git_diff* diff,
NativeMethods.git_diff_file_cb fileCallback,
NativeMethods.git_diff_hunk_cb hunkCallback,
NativeMethods.git_diff_line_cb lineCallback)
{
int res = NativeMethods.git_diff_foreach(diff, fileCallback, null, hunkCallback, lineCallback, IntPtr.Zero);
Ensure.ZeroResult(res);
}
public static unsafe DiffHandle git_diff_tree_to_index(
RepositoryHandle repo,
IndexHandle index,
ObjectId oldTree,
GitDiffOptions options)
{
using (var osw = new ObjectSafeWrapper(oldTree, repo, true))
{
git_diff* diff;
int res = NativeMethods.git_diff_tree_to_index(out diff, repo, osw.ObjectPtr, index, options);
Ensure.ZeroResult(res);
return new DiffHandle(diff, true);
}
}
public static unsafe void git_diff_merge(DiffHandle onto, DiffHandle from)
{
int res = NativeMethods.git_diff_merge(onto, from);
Ensure.ZeroResult(res);
}
public static unsafe DiffHandle git_diff_tree_to_tree(
RepositoryHandle repo,
ObjectId oldTree,
ObjectId newTree,
GitDiffOptions options)
{
using (var osw1 = new ObjectSafeWrapper(oldTree, repo, true))
using (var osw2 = new ObjectSafeWrapper(newTree, repo, true))
{
git_diff* diff;
int res = NativeMethods.git_diff_tree_to_tree(out diff, repo, osw1.ObjectPtr, osw2.ObjectPtr, options);
Ensure.ZeroResult(res);
return new DiffHandle(diff, true);
}
}
public static unsafe DiffHandle git_diff_index_to_workdir(
RepositoryHandle repo,
IndexHandle index,
GitDiffOptions options)
{
git_diff* diff;
int res = NativeMethods.git_diff_index_to_workdir(out diff, repo, index, options);
Ensure.ZeroResult(res);
return new DiffHandle(diff, true);
}
public static unsafe DiffHandle git_diff_tree_to_workdir(
RepositoryHandle repo,
ObjectId oldTree,
GitDiffOptions options)
{
using (var osw = new ObjectSafeWrapper(oldTree, repo, true))
{
git_diff* diff;
int res = NativeMethods.git_diff_tree_to_workdir(out diff, repo, osw.ObjectPtr, options);
Ensure.ZeroResult(res);
return new DiffHandle(diff, true);
}
}
public static unsafe void git_diff_find_similar(DiffHandle diff, GitDiffFindOptions options)
{
int res = NativeMethods.git_diff_find_similar(diff, options);
Ensure.ZeroResult(res);
}
public static unsafe int git_diff_num_deltas(DiffHandle diff)
{
return (int)NativeMethods.git_diff_num_deltas(diff);
}
public static unsafe git_diff_delta* git_diff_get_delta(DiffHandle diff, int idx)
{
return NativeMethods.git_diff_get_delta(diff, (UIntPtr)idx);
}
#endregion
#region git_filter_
public static void git_filter_register(string name, IntPtr filterPtr, int priority)
{
int res = NativeMethods.git_filter_register(name, filterPtr, priority);
if (res == (int)GitErrorCode.Exists)
{
throw new EntryExistsException("A filter with the name '{0}' is already registered", name);
}
Ensure.ZeroResult(res);
}
public static void git_filter_unregister(string name)
{
int res = NativeMethods.git_filter_unregister(name);
Ensure.ZeroResult(res);
}
public static unsafe FilterMode git_filter_source_mode(git_filter_source* filterSource)
{
var res = NativeMethods.git_filter_source_mode(filterSource);
return (FilterMode)res;
}
#endregion
#region git_graph_
public static unsafe Tuple git_graph_ahead_behind(RepositoryHandle repo, Commit first, Commit second)
{
if (first == null || second == null)
{
return new Tuple(null, null);
}
GitOid oid1 = first.Id.Oid;
GitOid oid2 = second.Id.Oid;
UIntPtr ahead;
UIntPtr behind;
int res = NativeMethods.git_graph_ahead_behind(out ahead, out behind, repo, ref oid1, ref oid2);
Ensure.ZeroResult(res);
return new Tuple((int)ahead, (int)behind);
}
public static unsafe bool git_graph_descendant_of(RepositoryHandle repo, ObjectId commitId, ObjectId ancestorId)
{
GitOid oid1 = commitId.Oid;
GitOid oid2 = ancestorId.Oid;
int res = NativeMethods.git_graph_descendant_of(repo, ref oid1, ref oid2);
Ensure.BooleanResult(res);
return (res == 1);
}
#endregion
#region git_ignore_
public static unsafe void git_ignore_add_rule(RepositoryHandle repo, string rules)
{
int res = NativeMethods.git_ignore_add_rule(repo, rules);
Ensure.ZeroResult(res);
}
public static unsafe void git_ignore_clear_internal_rules(RepositoryHandle repo)
{
int res = NativeMethods.git_ignore_clear_internal_rules(repo);
Ensure.ZeroResult(res);
}
public static unsafe bool git_ignore_path_is_ignored(RepositoryHandle repo, string path)
{
int ignored;
int res = NativeMethods.git_ignore_path_is_ignored(out ignored, repo, path);
Ensure.ZeroResult(res);
return (ignored != 0);
}
#endregion
#region git_index_
public static unsafe void git_index_add(IndexHandle index, git_index_entry* entry)
{
int res = NativeMethods.git_index_add(index, entry);
Ensure.ZeroResult(res);
}
public static unsafe void git_index_add_bypath(IndexHandle index, FilePath path)
{
int res = NativeMethods.git_index_add_bypath(index, path);
Ensure.ZeroResult(res);
}
public static unsafe Conflict git_index_conflict_get(
IndexHandle index,
FilePath path)
{
git_index_entry* ancestor, ours, theirs;
int res = NativeMethods.git_index_conflict_get(out ancestor,
out ours,
out theirs,
index,
path);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return new Conflict(IndexEntry.BuildFromPtr(ancestor),
IndexEntry.BuildFromPtr(ours),
IndexEntry.BuildFromPtr(theirs));
}
public static unsafe ConflictIteratorHandle git_index_conflict_iterator_new(IndexHandle index)
{
git_index_conflict_iterator* iter;
int res = NativeMethods.git_index_conflict_iterator_new(out iter, index);
Ensure.ZeroResult(res);
return new ConflictIteratorHandle(iter, true);
}
public static unsafe Conflict git_index_conflict_next(ConflictIteratorHandle iterator)
{
git_index_entry* ancestor, ours, theirs;
int res = NativeMethods.git_index_conflict_next(out ancestor, out ours, out theirs, iterator);
if (res == (int)GitErrorCode.IterOver)
{
return null;
}
Ensure.ZeroResult(res);
return new Conflict(IndexEntry.BuildFromPtr(ancestor),
IndexEntry.BuildFromPtr(ours),
IndexEntry.BuildFromPtr(theirs));
}
public static unsafe int git_index_entrycount(IndexHandle index)
{
return NativeMethods.git_index_entrycount(index)
.ConvertToInt();
}
public static unsafe StageLevel git_index_entry_stage(git_index_entry* entry)
{
return (StageLevel)NativeMethods.git_index_entry_stage(entry);
}
public static unsafe git_index_entry* git_index_get_byindex(IndexHandle index, UIntPtr n)
{
return NativeMethods.git_index_get_byindex(index, n);
}
public static unsafe git_index_entry* git_index_get_bypath(IndexHandle index, FilePath path, int stage)
{
return NativeMethods.git_index_get_bypath(index, path, stage);
}
public static unsafe bool git_index_has_conflicts(IndexHandle index)
{
int res = NativeMethods.git_index_has_conflicts(index);
Ensure.BooleanResult(res);
return res != 0;
}
public static unsafe int git_index_name_entrycount(IndexHandle index)
{
return NativeMethods.git_index_name_entrycount(index)
.ConvertToInt();
}
public static unsafe git_index_name_entry* git_index_name_get_byindex(IndexHandle index, UIntPtr n)
{
return NativeMethods.git_index_name_get_byindex(index, n);
}
public static unsafe IndexHandle git_index_open(FilePath indexpath)
{
git_index* handle;
int res = NativeMethods.git_index_open(out handle, indexpath);
Ensure.ZeroResult(res);
return new IndexHandle(handle, true);
}
public static unsafe void git_index_read(IndexHandle index)
{
int res = NativeMethods.git_index_read(index, false);
Ensure.ZeroResult(res);
}
public static unsafe void git_index_remove_bypath(IndexHandle index, FilePath path)
{
int res = NativeMethods.git_index_remove_bypath(index, path);
Ensure.ZeroResult(res);
}
public static unsafe int git_index_reuc_entrycount(IndexHandle index)
{
return NativeMethods.git_index_reuc_entrycount(index)
.ConvertToInt();
}
public static unsafe git_index_reuc_entry* git_index_reuc_get_byindex(IndexHandle index, UIntPtr n)
{
return NativeMethods.git_index_reuc_get_byindex(index, n);
}
public static unsafe git_index_reuc_entry* git_index_reuc_get_bypath(IndexHandle index, string path)
{
return NativeMethods.git_index_reuc_get_bypath(index, path);
}
public static unsafe void git_index_write(IndexHandle index)
{
int res = NativeMethods.git_index_write(index);
Ensure.ZeroResult(res);
}
public static unsafe ObjectId git_index_write_tree(IndexHandle index)
{
GitOid treeOid;
int res = NativeMethods.git_index_write_tree(out treeOid, index);
Ensure.ZeroResult(res);
return treeOid;
}
public static unsafe ObjectId git_index_write_tree_to(IndexHandle index, RepositoryHandle repo)
{
GitOid treeOid;
int res = NativeMethods.git_index_write_tree_to(out treeOid, index, repo);
Ensure.ZeroResult(res);
return treeOid;
}
public static unsafe void git_index_read_fromtree(Index index, ObjectHandle tree)
{
int res = NativeMethods.git_index_read_tree(index.Handle, tree);
Ensure.ZeroResult(res);
}
public static unsafe void git_index_clear(Index index)
{
int res = NativeMethods.git_index_clear(index.Handle);
Ensure.ZeroResult(res);
}
#endregion
#region git_merge_
public static unsafe IndexHandle git_merge_commits(RepositoryHandle repo, ObjectHandle ourCommit, ObjectHandle theirCommit, GitMergeOpts opts)
{
git_index* index;
int res = NativeMethods.git_merge_commits(out index, repo, ourCommit, theirCommit, ref opts);
Ensure.ZeroResult(res);
return new IndexHandle(index, true);
}
public static unsafe ObjectId git_merge_base_many(RepositoryHandle repo, GitOid[] commitIds)
{
GitOid ret;
int res = NativeMethods.git_merge_base_many(out ret, repo, commitIds.Length, commitIds);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return ret;
}
public static unsafe ObjectId git_merge_base_octopus(RepositoryHandle repo, GitOid[] commitIds)
{
GitOid ret;
int res = NativeMethods.git_merge_base_octopus(out ret, repo, commitIds.Length, commitIds);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return ret;
}
public static unsafe AnnotatedCommitHandle git_annotated_commit_from_fetchhead(RepositoryHandle repo, string branchName, string remoteUrl, GitOid oid)
{
git_annotated_commit* commit;
int res = NativeMethods.git_annotated_commit_from_fetchhead(out commit, repo, branchName, remoteUrl, ref oid);
Ensure.ZeroResult(res);
return new AnnotatedCommitHandle(commit, true);
}
public static unsafe AnnotatedCommitHandle git_annotated_commit_lookup(RepositoryHandle repo, GitOid oid)
{
git_annotated_commit* commit;
int res = NativeMethods.git_annotated_commit_lookup(out commit, repo, ref oid);
Ensure.ZeroResult(res);
return new AnnotatedCommitHandle(commit, true);
}
public static unsafe AnnotatedCommitHandle git_annotated_commit_from_ref(RepositoryHandle repo, ReferenceHandle reference)
{
git_annotated_commit* commit;
int res = NativeMethods.git_annotated_commit_from_ref(out commit, repo, reference);
Ensure.ZeroResult(res);
return new AnnotatedCommitHandle(commit, true);
}
public static unsafe AnnotatedCommitHandle git_annotated_commit_from_revspec(RepositoryHandle repo, string revspec)
{
git_annotated_commit* commit;
int res = NativeMethods.git_annotated_commit_from_revspec(out commit, repo, revspec);
Ensure.ZeroResult(res);
return new AnnotatedCommitHandle(commit, true);
}
public static unsafe ObjectId git_annotated_commit_id(AnnotatedCommitHandle mergeHead)
{
return ObjectId.BuildFromPtr(NativeMethods.git_annotated_commit_id(mergeHead));
}
public static unsafe void git_merge(RepositoryHandle repo, AnnotatedCommitHandle[] heads, GitMergeOpts mergeOptions, GitCheckoutOpts checkoutOptions)
{
IntPtr[] their_heads = heads.Select(head => head.AsIntPtr()).ToArray();
int res = NativeMethods.git_merge(repo,
their_heads,
(UIntPtr)their_heads.Length,
ref mergeOptions,
ref checkoutOptions);
Ensure.ZeroResult(res);
}
public static unsafe void git_merge_analysis(
RepositoryHandle repo,
AnnotatedCommitHandle[] heads,
out GitMergeAnalysis analysis_out,
out GitMergePreference preference_out)
{
IntPtr[] their_heads = heads.Select(head => head.AsIntPtr()).ToArray();
int res = NativeMethods.git_merge_analysis(out analysis_out,
out preference_out,
repo,
their_heads,
their_heads.Length);
Ensure.ZeroResult(res);
}
#endregion
#region git_message_
public static string git_message_prettify(string message, char? commentChar)
{
if (string.IsNullOrEmpty(message))
{
return string.Empty;
}
int comment = commentChar.GetValueOrDefault();
if (comment > sbyte.MaxValue)
{
throw new InvalidOperationException("Only single byte characters are allowed as commentary characters in a message (eg. '#').");
}
using (var buf = new GitBuf())
{
int res = NativeMethods.git_message_prettify(buf, message, false, (sbyte)comment);
Ensure.Int32Result(res);
return LaxUtf8Marshaler.FromNative(buf.ptr) ?? string.Empty;
}
}
#endregion
#region git_note_
public static unsafe ObjectId git_note_create(
RepositoryHandle repo,
string notes_ref,
Signature author,
Signature committer,
ObjectId targetId,
string note,
bool force)
{
using (SignatureHandle authorHandle = author.BuildHandle())
using (SignatureHandle committerHandle = committer.BuildHandle())
{
GitOid noteOid;
GitOid oid = targetId.Oid;
int res = NativeMethods.git_note_create(out noteOid, repo, notes_ref, authorHandle, committerHandle, ref oid, note, force ? 1 : 0);
Ensure.ZeroResult(res);
return noteOid;
}
}
public static unsafe string git_note_default_ref(RepositoryHandle repo)
{
using (var buf = new GitBuf())
{
int res = NativeMethods.git_note_default_ref(buf, repo);
Ensure.ZeroResult(res);
return LaxUtf8Marshaler.FromNative(buf.ptr);
}
}
public static unsafe ICollection git_note_foreach(RepositoryHandle repo, string notes_ref, Func resultSelector)
{
return git_foreach(resultSelector, c => NativeMethods.git_note_foreach(repo,
notes_ref,
(ref GitOid x, ref GitOid y, IntPtr p) => c(x, y, p),
IntPtr.Zero));
}
public static unsafe string git_note_message(NoteHandle note)
{
return NativeMethods.git_note_message(note);
}
public static unsafe ObjectId git_note_id(NoteHandle note)
{
return ObjectId.BuildFromPtr(NativeMethods.git_note_id(note));
}
public static unsafe NoteHandle git_note_read(RepositoryHandle repo, string notes_ref, ObjectId id)
{
GitOid oid = id.Oid;
git_note* note;
int res = NativeMethods.git_note_read(out note, repo, notes_ref, ref oid);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return new NoteHandle(note, true);
}
public static unsafe void git_note_remove(RepositoryHandle repo, string notes_ref, Signature author, Signature committer, ObjectId targetId)
{
using (SignatureHandle authorHandle = author.BuildHandle())
using (SignatureHandle committerHandle = committer.BuildHandle())
{
GitOid oid = targetId.Oid;
int res = NativeMethods.git_note_remove(repo, notes_ref, authorHandle, committerHandle, ref oid);
if (res == (int)GitErrorCode.NotFound)
{
return;
}
Ensure.ZeroResult(res);
}
}
#endregion
#region git_object_
public static unsafe ObjectId git_object_id(ObjectHandle obj)
{
return ObjectId.BuildFromPtr(NativeMethods.git_object_id(obj));
}
public static unsafe ObjectHandle git_object_lookup(RepositoryHandle repo, ObjectId id, GitObjectType type)
{
git_object* handle;
GitOid oid = id.Oid;
int res = NativeMethods.git_object_lookup(out handle, repo, ref oid, type);
switch (res)
{
case (int)GitErrorCode.NotFound:
return null;
default:
Ensure.ZeroResult(res);
break;
}
return new ObjectHandle(handle, true);
}
public static unsafe ObjectHandle git_object_peel(RepositoryHandle repo, ObjectId id, GitObjectType type, bool throwsIfCanNotPeel)
{
git_object* peeled;
int res;
using (var obj = new ObjectSafeWrapper(id, repo))
{
res = NativeMethods.git_object_peel(out peeled, obj.ObjectPtr, type);
}
if (!throwsIfCanNotPeel &&
(res == (int)GitErrorCode.NotFound || res == (int)GitErrorCode.Ambiguous ||
res == (int)GitErrorCode.InvalidSpecification || res == (int)GitErrorCode.Peel))
{
return null;
}
Ensure.ZeroResult(res);
return new ObjectHandle(peeled, true);
}
public static unsafe string git_object_short_id(RepositoryHandle repo, ObjectId id)
{
using (var obj = new ObjectSafeWrapper(id, repo))
using (var buf = new GitBuf())
{
int res = NativeMethods.git_object_short_id(buf, obj.ObjectPtr);
Ensure.Int32Result(res);
return LaxUtf8Marshaler.FromNative(buf.ptr);
}
}
public static unsafe GitObjectType git_object_type(ObjectHandle obj)
{
return NativeMethods.git_object_type(obj);
}
#endregion
#region git_odb_
public static unsafe void git_odb_add_backend(ObjectDatabaseHandle odb, IntPtr backend, int priority)
{
Ensure.ZeroResult(NativeMethods.git_odb_add_backend(odb, backend, priority));
}
public static IntPtr git_odb_backend_malloc(IntPtr backend, UIntPtr len)
{
IntPtr toReturn = NativeMethods.git_odb_backend_malloc(backend, len);
if (IntPtr.Zero == toReturn)
{
throw new LibGit2SharpException("Unable to allocate {0} bytes; out of memory",
len,
GitErrorCode.Error,
GitErrorCategory.NoMemory);
}
return toReturn;
}
public static unsafe bool git_odb_exists(ObjectDatabaseHandle odb, ObjectId id)
{
GitOid oid = id.Oid;
int res = NativeMethods.git_odb_exists(odb, ref oid);
Ensure.BooleanResult(res);
return (res == 1);
}
public static unsafe GitObjectMetadata git_odb_read_header(ObjectDatabaseHandle odb, ObjectId id)
{
GitOid oid = id.Oid;
UIntPtr length;
GitObjectType objectType;
int res = NativeMethods.git_odb_read_header(out length, out objectType, odb, ref oid);
Ensure.ZeroResult(res);
return new GitObjectMetadata((long)length, objectType);
}
public static unsafe ICollection git_odb_foreach(ObjectDatabaseHandle odb)
{
var list = new List();
NativeMethods.git_odb_foreach(odb, (p, _data) =>
{
list.Add(ObjectId.BuildFromPtr(p));
return 0;
}, IntPtr.Zero);
return list;
}
public static unsafe OdbStreamHandle git_odb_open_wstream(ObjectDatabaseHandle odb, long size, GitObjectType type)
{
git_odb_stream* stream;
int res = NativeMethods.git_odb_open_wstream(out stream, odb, size, type);
Ensure.ZeroResult(res);
return new OdbStreamHandle(stream, true);
}
public static void git_odb_stream_write(OdbStreamHandle stream, byte[] data, int len)
{
int res;
unsafe
{
fixed (byte* p = data)
{
res = NativeMethods.git_odb_stream_write(stream, (IntPtr)p, (UIntPtr)len);
}
}
Ensure.ZeroResult(res);
}
public static unsafe ObjectId git_odb_stream_finalize_write(OdbStreamHandle stream)
{
GitOid id;
int res = NativeMethods.git_odb_stream_finalize_write(out id, stream);
Ensure.ZeroResult(res);
return id;
}
#endregion
#region git_patch_
public static unsafe PatchHandle git_patch_from_diff(DiffHandle diff, int idx)
{
git_patch* handle;
int res = NativeMethods.git_patch_from_diff(out handle, diff, (UIntPtr)idx);
Ensure.ZeroResult(res);
return new PatchHandle(handle, true);
}
public static unsafe void git_patch_print(PatchHandle patch, NativeMethods.git_diff_line_cb printCallback)
{
int res = NativeMethods.git_patch_print(patch, printCallback, IntPtr.Zero);
Ensure.ZeroResult(res);
}
public static unsafe Tuple git_patch_line_stats(PatchHandle patch)
{
UIntPtr ctx, add, del;
int res = NativeMethods.git_patch_line_stats(out ctx, out add, out del, patch);
Ensure.ZeroResult(res);
return new Tuple((int)add, (int)del);
}
#endregion
#region git_packbuilder_
public static unsafe PackBuilderHandle git_packbuilder_new(RepositoryHandle repo)
{
git_packbuilder* handle;
int res = NativeMethods.git_packbuilder_new(out handle, repo);
Ensure.ZeroResult(res);
return new PackBuilderHandle(handle, true);
}
public static unsafe void git_packbuilder_insert(PackBuilderHandle packbuilder, ObjectId targetId, string name)
{
GitOid oid = targetId.Oid;
int res = NativeMethods.git_packbuilder_insert(packbuilder, ref oid, name);
Ensure.ZeroResult(res);
}
internal static unsafe void git_packbuilder_insert_commit(PackBuilderHandle packbuilder, ObjectId targetId)
{
GitOid oid = targetId.Oid;
int res = NativeMethods.git_packbuilder_insert_commit(packbuilder, ref oid);
Ensure.ZeroResult(res);
}
internal static unsafe void git_packbuilder_insert_tree(PackBuilderHandle packbuilder, ObjectId targetId)
{
GitOid oid = targetId.Oid;
int res = NativeMethods.git_packbuilder_insert_tree(packbuilder, ref oid);
Ensure.ZeroResult(res);
}
public static unsafe void git_packbuilder_insert_recur(PackBuilderHandle packbuilder, ObjectId targetId, string name)
{
GitOid oid = targetId.Oid;
int res = NativeMethods.git_packbuilder_insert_recur(packbuilder, ref oid, name);
Ensure.ZeroResult(res);
}
public static unsafe uint git_packbuilder_set_threads(PackBuilderHandle packbuilder, uint numThreads)
{
return NativeMethods.git_packbuilder_set_threads(packbuilder, numThreads);
}
public static unsafe void git_packbuilder_write(PackBuilderHandle packbuilder, FilePath path)
{
int res = NativeMethods.git_packbuilder_write(packbuilder, path, 0, IntPtr.Zero, IntPtr.Zero);
Ensure.ZeroResult(res);
}
public static unsafe uint git_packbuilder_object_count(PackBuilderHandle packbuilder)
{
return NativeMethods.git_packbuilder_object_count(packbuilder);
}
public static unsafe uint git_packbuilder_written(PackBuilderHandle packbuilder)
{
return NativeMethods.git_packbuilder_written(packbuilder);
}
#endregion
#region git_rebase
public static unsafe RebaseHandle git_rebase_init(
RepositoryHandle repo,
AnnotatedCommitHandle branch,
AnnotatedCommitHandle upstream,
AnnotatedCommitHandle onto,
GitRebaseOptions options)
{
git_rebase* rebase = null;
int result = NativeMethods.git_rebase_init(out rebase, repo, branch, upstream, onto, options);
Ensure.ZeroResult(result);
return new RebaseHandle(rebase, true);
}
public static unsafe RebaseHandle git_rebase_open(RepositoryHandle repo, GitRebaseOptions options)
{
git_rebase* rebase = null;
int result = NativeMethods.git_rebase_open(out rebase, repo, options);
Ensure.ZeroResult(result);
return new RebaseHandle(rebase, true);
}
public static unsafe long git_rebase_operation_entrycount(RebaseHandle rebase)
{
return NativeMethods.git_rebase_operation_entrycount(rebase).ConvertToLong();
}
public static unsafe long git_rebase_operation_current(RebaseHandle rebase)
{
UIntPtr result = NativeMethods.git_rebase_operation_current(rebase);
if (result == GIT_REBASE_NO_OPERATION)
{
return RebaseNoOperation;
}
else
{
return result.ConvertToLong();
}
}
///
/// The value from the native layer indicating that no rebase operation is in progress.
///
private static UIntPtr GIT_REBASE_NO_OPERATION
{
get
{
return UIntPtr.Size == 4 ? new UIntPtr(uint.MaxValue) : new UIntPtr(ulong.MaxValue);
}
}
public const long RebaseNoOperation = -1;
public static unsafe git_rebase_operation* git_rebase_operation_byindex(
RebaseHandle rebase,
long index)
{
Debug.Assert(index >= 0);
return NativeMethods.git_rebase_operation_byindex(rebase, ((UIntPtr)index));
}
///
/// Returns null when finished.
///
///
///
public static unsafe git_rebase_operation* git_rebase_next(RebaseHandle rebase)
{
git_rebase_operation* ptr;
int result = NativeMethods.git_rebase_next(out ptr, rebase);
if (result == (int)GitErrorCode.IterOver)
{
return null;
}
Ensure.ZeroResult(result);
return ptr;
}
public static unsafe GitRebaseCommitResult git_rebase_commit(
RebaseHandle rebase,
Identity author,
Identity committer)
{
Ensure.ArgumentNotNull(rebase, "rebase");
Ensure.ArgumentNotNull(committer, "committer");
using (SignatureHandle committerHandle = committer.BuildNowSignatureHandle())
using (SignatureHandle authorHandle = author.SafeBuildNowSignatureHandle())
{
GitRebaseCommitResult commitResult = new GitRebaseCommitResult();
int result = NativeMethods.git_rebase_commit(ref commitResult.CommitId, rebase, authorHandle, committerHandle, IntPtr.Zero, IntPtr.Zero);
if (result == (int)GitErrorCode.Applied)
{
commitResult.CommitId = GitOid.Empty;
commitResult.WasPatchAlreadyApplied = true;
}
else
{
Ensure.ZeroResult(result);
}
return commitResult;
}
}
///
/// Struct to report the result of calling git_rebase_commit.
///
public struct GitRebaseCommitResult
{
///
/// The ID of the commit that was generated, if any
///
public GitOid CommitId;
///
/// bool to indicate if the patch was already applied.
/// If Patch was already applied, then CommitId will be empty (all zeros).
///
public bool WasPatchAlreadyApplied;
}
public static unsafe void git_rebase_abort(
RebaseHandle rebase)
{
Ensure.ArgumentNotNull(rebase, "rebase");
int result = NativeMethods.git_rebase_abort(rebase);
Ensure.ZeroResult(result);
}
public static unsafe void git_rebase_finish(
RebaseHandle rebase,
Identity committer)
{
Ensure.ArgumentNotNull(rebase, "rebase");
Ensure.ArgumentNotNull(committer, "committer");
using (var signatureHandle = committer.BuildNowSignatureHandle())
{
int result = NativeMethods.git_rebase_finish(rebase, signatureHandle);
Ensure.ZeroResult(result);
}
}
#endregion
#region git_reference_
public static unsafe ReferenceHandle git_reference_create(
RepositoryHandle repo,
string name,
ObjectId targetId,
bool allowOverwrite,
string logMessage)
{
GitOid oid = targetId.Oid;
git_reference* handle;
int res = NativeMethods.git_reference_create(out handle, repo, name, ref oid, allowOverwrite, logMessage);
Ensure.ZeroResult(res);
return new ReferenceHandle(handle, true);
}
public static unsafe ReferenceHandle git_reference_symbolic_create(
RepositoryHandle repo,
string name,
string target,
bool allowOverwrite,
string logMessage)
{
git_reference* handle;
int res = NativeMethods.git_reference_symbolic_create(out handle, repo, name, target, allowOverwrite,
logMessage);
Ensure.ZeroResult(res);
return new ReferenceHandle(handle, true);
}
public static unsafe ICollection git_reference_foreach_glob(
RepositoryHandle repo,
string glob,
Func resultSelector)
{
return git_foreach(resultSelector, c => NativeMethods.git_reference_foreach_glob(repo, glob, (x, p) => c(x, p), IntPtr.Zero));
}
public static bool git_reference_is_valid_name(string refname)
{
int res = NativeMethods.git_reference_is_valid_name(refname);
Ensure.BooleanResult(res);
return (res == 1);
}
public static unsafe IList git_reference_list(RepositoryHandle repo)
{
var array = new GitStrArrayNative();
try
{
int res = NativeMethods.git_reference_list(out array.Array, repo);
Ensure.ZeroResult(res);
return array.ReadStrings();
}
finally
{
array.Dispose();
}
}
public static unsafe ReferenceHandle git_reference_lookup(RepositoryHandle repo, string name, bool shouldThrowIfNotFound)
{
git_reference* handle;
int res = NativeMethods.git_reference_lookup(out handle, repo, name);
if (!shouldThrowIfNotFound && res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return new ReferenceHandle(handle, true);
}
public static unsafe string git_reference_name(git_reference* reference)
{
return NativeMethods.git_reference_name(reference);
}
public static unsafe void git_reference_remove(RepositoryHandle repo, string name)
{
int res = NativeMethods.git_reference_remove(repo, name);
Ensure.ZeroResult(res);
}
public static unsafe ObjectId git_reference_target(git_reference* reference)
{
return ObjectId.BuildFromPtr(NativeMethods.git_reference_target(reference));
}
public static unsafe ReferenceHandle git_reference_rename(
ReferenceHandle reference,
string newName,
bool allowOverwrite,
string logMessage)
{
git_reference* ref_out;
int res = NativeMethods.git_reference_rename(out ref_out, reference, newName, allowOverwrite, logMessage);
Ensure.ZeroResult(res);
return new ReferenceHandle(ref_out, true);
}
public static unsafe ReferenceHandle git_reference_set_target(ReferenceHandle reference, ObjectId id, string logMessage)
{
GitOid oid = id.Oid;
git_reference* ref_out;
int res = NativeMethods.git_reference_set_target(out ref_out, reference, ref oid, logMessage);
Ensure.ZeroResult(res);
return new ReferenceHandle(ref_out, true);
}
public static unsafe ReferenceHandle git_reference_symbolic_set_target(ReferenceHandle reference, string target, string logMessage)
{
git_reference* ref_out;
int res = NativeMethods.git_reference_symbolic_set_target(out ref_out, reference, target, logMessage);
Ensure.ZeroResult(res);
return new ReferenceHandle(ref_out, true);
}
public static unsafe string git_reference_symbolic_target(git_reference* reference)
{
return NativeMethods.git_reference_symbolic_target(reference);
}
public static unsafe GitReferenceType git_reference_type(git_reference* reference)
{
return NativeMethods.git_reference_type(reference);
}
public static unsafe void git_reference_ensure_log(RepositoryHandle repo, string refname)
{
int res = NativeMethods.git_reference_ensure_log(repo, refname);
Ensure.ZeroResult(res);
}
#endregion
#region git_reflog_
public static unsafe ReflogHandle git_reflog_read(RepositoryHandle repo, string canonicalName)
{
git_reflog* reflog_out;
int res = NativeMethods.git_reflog_read(out reflog_out, repo, canonicalName);
Ensure.ZeroResult(res);
return new ReflogHandle(reflog_out, true);
}
public static unsafe int git_reflog_entrycount(ReflogHandle reflog)
{
return (int)NativeMethods.git_reflog_entrycount(reflog);
}
public static unsafe git_reflog_entry* git_reflog_entry_byindex(ReflogHandle reflog, int idx)
{
return NativeMethods.git_reflog_entry_byindex(reflog, (UIntPtr)idx);
}
public static unsafe ObjectId git_reflog_entry_id_old(git_reflog_entry* entry)
{
return ObjectId.BuildFromPtr(NativeMethods.git_reflog_entry_id_old(entry));
}
public static unsafe ObjectId git_reflog_entry_id_new(git_reflog_entry* entry)
{
return ObjectId.BuildFromPtr(NativeMethods.git_reflog_entry_id_new(entry));
}
public static unsafe Signature git_reflog_entry_committer(git_reflog_entry* entry)
{
return new Signature(NativeMethods.git_reflog_entry_committer(entry));
}
public static unsafe string git_reflog_entry_message(git_reflog_entry* entry)
{
return NativeMethods.git_reflog_entry_message(entry);
}
#endregion
#region git_refspec
public static unsafe string git_refspec_rtransform(git_refspec* refSpecPtr, string name)
{
using (var buf = new GitBuf())
{
int res = NativeMethods.git_refspec_rtransform(buf, refSpecPtr, name);
Ensure.ZeroResult(res);
return LaxUtf8Marshaler.FromNative(buf.ptr) ?? string.Empty;
}
}
public static unsafe string git_refspec_string(git_refspec* refSpec)
{
return NativeMethods.git_refspec_string(refSpec);
}
public static unsafe string git_refspec_src(git_refspec* refSpec)
{
return NativeMethods.git_refspec_src(refSpec);
}
public static unsafe string git_refspec_dst(git_refspec* refSpec)
{
return NativeMethods.git_refspec_dst(refSpec);
}
public static unsafe RefSpecDirection git_refspec_direction(git_refspec* refSpec)
{
return NativeMethods.git_refspec_direction(refSpec);
}
public static unsafe bool git_refspec_force(git_refspec* refSpec)
{
return NativeMethods.git_refspec_force(refSpec);
}
#endregion
#region git_remote_
public static unsafe TagFetchMode git_remote_autotag(RemoteHandle remote)
{
return (TagFetchMode)NativeMethods.git_remote_autotag(remote);
}
public static unsafe RemoteHandle git_remote_create(RepositoryHandle repo, string name, string url)
{
git_remote* handle;
int res = NativeMethods.git_remote_create(out handle, repo, name, url);
Ensure.ZeroResult(res);
return new RemoteHandle(handle, true);
}
public static unsafe RemoteHandle git_remote_create_with_fetchspec(RepositoryHandle repo, string name, string url, string refspec)
{
git_remote* handle;
int res = NativeMethods.git_remote_create_with_fetchspec(out handle, repo, name, url, refspec);
Ensure.ZeroResult(res);
return new RemoteHandle(handle, true);
}
public static unsafe RemoteHandle git_remote_create_anonymous(RepositoryHandle repo, string url)
{
git_remote* handle;
int res = NativeMethods.git_remote_create_anonymous(out handle, repo, url);
Ensure.ZeroResult(res);
return new RemoteHandle(handle, true);
}
public static unsafe void git_remote_connect(RemoteHandle remote, GitDirection direction, ref GitRemoteCallbacks remoteCallbacks)
{
GitStrArrayManaged customHeaders = new GitStrArrayManaged();
try
{
int res = NativeMethods.git_remote_connect(remote, direction, ref remoteCallbacks, ref customHeaders.Array);
Ensure.ZeroResult(res);
}
catch (Exception)
{
customHeaders.Dispose();
}
}
public static unsafe void git_remote_delete(RepositoryHandle repo, string name)
{
int res = NativeMethods.git_remote_delete(repo, name);
if (res == (int)GitErrorCode.NotFound)
{
return;
}
Ensure.ZeroResult(res);
}
public static unsafe git_refspec* git_remote_get_refspec(RemoteHandle remote, int n)
{
return NativeMethods.git_remote_get_refspec(remote, (UIntPtr)n);
}
public static unsafe int git_remote_refspec_count(RemoteHandle remote)
{
return (int)NativeMethods.git_remote_refspec_count(remote);
}
public static unsafe IList git_remote_get_fetch_refspecs(RemoteHandle remote)
{
var array = new GitStrArrayNative();
try
{
int res = NativeMethods.git_remote_get_fetch_refspecs(out array.Array, remote);
Ensure.ZeroResult(res);
return array.ReadStrings();
}
finally
{
array.Dispose();
}
}
public static unsafe IList git_remote_get_push_refspecs(RemoteHandle remote)
{
var array = new GitStrArrayNative();
try
{
int res = NativeMethods.git_remote_get_push_refspecs(out array.Array, remote);
Ensure.ZeroResult(res);
return array.ReadStrings();
}
finally
{
array.Dispose();
}
}
public static unsafe void git_remote_push(RemoteHandle remote, IEnumerable refSpecs, GitPushOptions opts)
{
var array = new GitStrArrayManaged();
try
{
array = GitStrArrayManaged.BuildFrom(refSpecs.ToArray());
int res = NativeMethods.git_remote_push(remote, ref array.Array, opts);
Ensure.ZeroResult(res);
}
finally
{
array.Dispose();
}
}
public static unsafe void git_remote_set_url(RepositoryHandle repo, string remote, string url)
{
int res = NativeMethods.git_remote_set_url(repo, remote, url);
Ensure.ZeroResult(res);
}
public static unsafe void git_remote_add_fetch(RepositoryHandle repo, string remote, string url)
{
int res = NativeMethods.git_remote_add_fetch(repo, remote, url);
Ensure.ZeroResult(res);
}
public static unsafe void git_remote_set_pushurl(RepositoryHandle repo, string remote, string url)
{
int res = NativeMethods.git_remote_set_pushurl(repo, remote, url);
Ensure.ZeroResult(res);
}
public static unsafe void git_remote_add_push(RepositoryHandle repo, string remote, string url)
{
int res = NativeMethods.git_remote_add_push(repo, remote, url);
Ensure.ZeroResult(res);
}
public static unsafe void git_remote_fetch(
RemoteHandle remote, IEnumerable refSpecs,
GitFetchOptions fetchOptions, string logMessage)
{
var array = new GitStrArrayManaged();
try
{
array = GitStrArrayManaged.BuildFrom(refSpecs.ToArray());
int res = NativeMethods.git_remote_fetch(remote, ref array.Array, fetchOptions, logMessage);
Ensure.ZeroResult(res);
}
finally
{
array.Dispose();
}
}
public static bool git_remote_is_valid_name(string refname)
{
int res = NativeMethods.git_remote_is_valid_name(refname);
Ensure.BooleanResult(res);
return (res == 1);
}
public static unsafe IList git_remote_list(RepositoryHandle repo)
{
var array = new GitStrArrayNative();
try
{
int res = NativeMethods.git_remote_list(out array.Array, repo);
Ensure.ZeroResult(res);
return array.ReadStrings();
}
finally
{
array.Dispose();
}
}
public static unsafe IEnumerable git_remote_ls(Repository repository, RemoteHandle remote)
{
git_remote_head** heads;
UIntPtr count;
int res = NativeMethods.git_remote_ls(out heads, out count, remote);
Ensure.ZeroResult(res);
var intCount = checked(count.ToUInt32());
var directRefs = new Dictionary();
var symRefs = new Dictionary();
for (int i = 0; i < intCount; i++)
{
git_remote_head* currentHead = heads[i];
string name = LaxUtf8Marshaler.FromNative(currentHead->Name);
string symRefTarget = LaxUtf8Marshaler.FromNative(currentHead->SymrefTarget);
// The name pointer should never be null - if it is,
// this indicates a bug somewhere (libgit2, server, etc).
if (string.IsNullOrEmpty(name))
{
throw new InvalidOperationException("Not expecting null value for reference name.");
}
if (!string.IsNullOrEmpty(symRefTarget))
{
symRefs.Add(name, symRefTarget);
}
else
{
directRefs.Add(name, new DirectReference(name, repository, new ObjectId(currentHead->Oid.Id)));
}
}
for (int i = 0; i < symRefs.Count; i++)
{
var symRef = symRefs.ElementAt(i);
if (!directRefs.ContainsKey(symRef.Value))
{
throw new InvalidOperationException("Symbolic reference target not found in direct reference results.");
}
directRefs.Add(symRef.Key, new SymbolicReference(repository, symRef.Key, symRef.Value, directRefs[symRef.Value]));
}
var refs = directRefs.Values.ToList();
refs.Sort((r1, r2) => String.CompareOrdinal(r1.CanonicalName, r2.CanonicalName));
return refs;
}
public static unsafe RemoteHandle git_remote_lookup(RepositoryHandle repo, string name, bool throwsIfNotFound)
{
git_remote* handle;
int res = NativeMethods.git_remote_lookup(out handle, repo, name);
if (res == (int)GitErrorCode.NotFound && !throwsIfNotFound)
{
return null;
}
Ensure.ZeroResult(res);
return new RemoteHandle(handle, true);
}
public static unsafe string git_remote_name(RemoteHandle remote)
{
return NativeMethods.git_remote_name(remote);
}
public static unsafe void git_remote_rename(RepositoryHandle repo, string name, string new_name, RemoteRenameFailureHandler callback)
{
if (callback == null)
{
callback = problem => { };
}
var array = new GitStrArrayNative();
try
{
int res = NativeMethods.git_remote_rename(ref array.Array,
repo,
name,
new_name);
if (res == (int)GitErrorCode.NotFound)
{
throw new NotFoundException("Remote '{0}' does not exist and cannot be renamed.", name);
}
Ensure.ZeroResult(res);
foreach (var item in array.ReadStrings())
{
callback(item);
}
}
finally
{
array.Dispose();
}
}
public static unsafe void git_remote_set_autotag(RepositoryHandle repo, string remote, TagFetchMode value)
{
NativeMethods.git_remote_set_autotag(repo, remote, value);
}
public static unsafe string git_remote_url(RemoteHandle remote)
{
return NativeMethods.git_remote_url(remote);
}
public static unsafe string git_remote_pushurl(RemoteHandle remote)
{
return NativeMethods.git_remote_pushurl(remote);
}
#endregion
#region git_repository_
public static FilePath git_repository_discover(FilePath start_path)
{
return ConvertPath(buf => NativeMethods.git_repository_discover(buf, start_path, false, null));
}
public static unsafe bool git_repository_head_detached(RepositoryHandle repo)
{
return RepositoryStateChecker(repo, NativeMethods.git_repository_head_detached);
}
public static unsafe ICollection git_repository_fetchhead_foreach(
RepositoryHandle repo,
Func resultSelector)
{
return git_foreach(resultSelector,
c => NativeMethods.git_repository_fetchhead_foreach(repo,
(IntPtr w, IntPtr x, ref GitOid y, bool z, IntPtr p)
=> c(LaxUtf8Marshaler.FromNative(w), LaxUtf8Marshaler.FromNative(x), y, z, p),
IntPtr.Zero),
GitErrorCode.NotFound);
}
public static bool git_repository_head_unborn(RepositoryHandle repo)
{
return RepositoryStateChecker(repo, NativeMethods.git_repository_head_unborn);
}
public static unsafe IndexHandle git_repository_index(RepositoryHandle repo)
{
git_index* handle;
int res = NativeMethods.git_repository_index(out handle, repo);
Ensure.ZeroResult(res);
return new IndexHandle(handle, true);
}
public static unsafe RepositoryHandle git_repository_init_ext(
FilePath workdirPath,
FilePath gitdirPath,
bool isBare)
{
using (var opts = GitRepositoryInitOptions.BuildFrom(workdirPath, isBare))
{
git_repository* repo;
int res = NativeMethods.git_repository_init_ext(out repo, gitdirPath, opts);
Ensure.ZeroResult(res);
return new RepositoryHandle(repo, true);
}
}
public static unsafe bool git_repository_is_bare(RepositoryHandle repo)
{
return RepositoryStateChecker(repo, NativeMethods.git_repository_is_bare);
}
public static unsafe bool git_repository_is_shallow(RepositoryHandle repo)
{
return RepositoryStateChecker(repo, NativeMethods.git_repository_is_shallow);
}
public static unsafe void git_repository_state_cleanup(RepositoryHandle repo)
{
int res = NativeMethods.git_repository_state_cleanup(repo);
Ensure.ZeroResult(res);
}
public static unsafe ICollection git_repository_mergehead_foreach(
RepositoryHandle repo,
Func resultSelector)
{
return git_foreach(resultSelector,
c => NativeMethods.git_repository_mergehead_foreach(repo,
(ref GitOid x, IntPtr p) => c(x, p), IntPtr.Zero),
GitErrorCode.NotFound);
}
public static unsafe string git_repository_message(RepositoryHandle repo)
{
using (var buf = new GitBuf())
{
int res = NativeMethods.git_repository_message(buf, repo);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return LaxUtf8Marshaler.FromNative(buf.ptr);
}
}
public static unsafe ObjectDatabaseHandle git_repository_odb(RepositoryHandle repo)
{
git_odb* handle;
int res = NativeMethods.git_repository_odb(out handle, repo);
Ensure.ZeroResult(res);
return new ObjectDatabaseHandle(handle, true);
}
public static unsafe RepositoryHandle git_repository_open(string path)
{
git_repository* repo;
int res = NativeMethods.git_repository_open(out repo, path);
if (res == (int)GitErrorCode.NotFound)
{
throw new RepositoryNotFoundException("Path '{0}' doesn't point at a valid Git repository or workdir.",
path);
}
Ensure.ZeroResult(res);
return new RepositoryHandle(repo, true);
}
public static unsafe RepositoryHandle git_repository_new()
{
git_repository* repo;
int res = NativeMethods.git_repository_new(out repo);
Ensure.ZeroResult(res);
return new RepositoryHandle(repo, true);
}
public static unsafe void git_repository_open_ext(string path, RepositoryOpenFlags flags, string ceilingDirs)
{
int res;
git_repository *repo;
res = NativeMethods.git_repository_open_ext(out repo, path, flags, ceilingDirs);
NativeMethods.git_repository_free(repo);
if (res == (int)GitErrorCode.NotFound)
{
throw new RepositoryNotFoundException("Path '{0}' doesn't point at a valid Git repository or workdir.",
path);
}
Ensure.ZeroResult(res);
}
public static unsafe FilePath git_repository_path(RepositoryHandle repo)
{
return NativeMethods.git_repository_path(repo);
}
public static unsafe void git_repository_set_config(RepositoryHandle repo, ConfigurationHandle config)
{
NativeMethods.git_repository_set_config(repo, config);
}
public static unsafe void git_repository_set_ident(RepositoryHandle repo, string name, string email)
{
int res = NativeMethods.git_repository_set_ident(repo, name, email);
Ensure.ZeroResult(res);
}
public static unsafe void git_repository_set_index(RepositoryHandle repo, IndexHandle index)
{
NativeMethods.git_repository_set_index(repo, index);
}
public static unsafe void git_repository_set_workdir(RepositoryHandle repo, FilePath workdir)
{
int res = NativeMethods.git_repository_set_workdir(repo, workdir, false);
Ensure.ZeroResult(res);
}
public static unsafe CurrentOperation git_repository_state(RepositoryHandle repo)
{
int res = NativeMethods.git_repository_state(repo);
Ensure.Int32Result(res);
return (CurrentOperation)res;
}
public static unsafe FilePath git_repository_workdir(RepositoryHandle repo)
{
return NativeMethods.git_repository_workdir(repo);
}
public static FilePath git_repository_workdir(IntPtr repo)
{
return NativeMethods.git_repository_workdir(repo);
}
public static unsafe void git_repository_set_head_detached(RepositoryHandle repo, ObjectId commitish)
{
GitOid oid = commitish.Oid;
int res = NativeMethods.git_repository_set_head_detached(repo, ref oid);
Ensure.ZeroResult(res);
}
public static unsafe void git_repository_set_head_detached_from_annotated(RepositoryHandle repo, AnnotatedCommitHandle commit)
{
int res = NativeMethods.git_repository_set_head_detached_from_annotated(repo, commit);
Ensure.ZeroResult(res);
}
public static unsafe void git_repository_set_head(RepositoryHandle repo, string refname)
{
int res = NativeMethods.git_repository_set_head(repo, refname);
Ensure.ZeroResult(res);
}
#endregion
#region git_reset_
public static unsafe void git_reset(
RepositoryHandle repo,
ObjectId committishId,
ResetMode resetKind,
ref GitCheckoutOpts checkoutOptions)
{
using (var osw = new ObjectSafeWrapper(committishId, repo))
{
int res = NativeMethods.git_reset(repo, osw.ObjectPtr, resetKind, ref checkoutOptions);
Ensure.ZeroResult(res);
}
}
#endregion
#region git_revert_
public static unsafe void git_revert(
RepositoryHandle repo,
ObjectId commit,
GitRevertOpts opts)
{
using (var nativeCommit = git_object_lookup(repo, commit, GitObjectType.Commit))
{
int res = NativeMethods.git_revert(repo, nativeCommit, opts);
Ensure.ZeroResult(res);
}
}
#endregion
#region git_revparse_
public static unsafe Tuple git_revparse_ext(RepositoryHandle repo, string objectish)
{
git_object* obj;
git_reference* reference;
int res = NativeMethods.git_revparse_ext(out obj, out reference, repo, objectish);
switch (res)
{
case (int)GitErrorCode.NotFound:
return null;
case (int)GitErrorCode.Ambiguous:
throw new AmbiguousSpecificationException("Provided abbreviated ObjectId '{0}' is too short.",
objectish);
default:
Ensure.ZeroResult(res);
break;
}
return new Tuple(new ObjectHandle(obj, true), new ReferenceHandle(reference, true));
}
public static ObjectHandle git_revparse_single(RepositoryHandle repo, string objectish)
{
var handles = git_revparse_ext(repo, objectish);
if (handles == null)
{
return null;
}
handles.Item2.Dispose();
return handles.Item1;
}
#endregion
#region git_revwalk_
public static unsafe void git_revwalk_hide(RevWalkerHandle walker, ObjectId commit_id)
{
GitOid oid = commit_id.Oid;
int res = NativeMethods.git_revwalk_hide(walker, ref oid);
Ensure.ZeroResult(res);
}
public static unsafe RevWalkerHandle git_revwalk_new(RepositoryHandle repo)
{
git_revwalk* handle;
int res = NativeMethods.git_revwalk_new(out handle, repo);
Ensure.ZeroResult(res);
return new RevWalkerHandle(handle, true);
}
public static unsafe ObjectId git_revwalk_next(RevWalkerHandle walker)
{
GitOid ret;
int res = NativeMethods.git_revwalk_next(out ret, walker);
if (res == (int)GitErrorCode.IterOver)
{
return null;
}
Ensure.ZeroResult(res);
return ret;
}
public static unsafe void git_revwalk_push(RevWalkerHandle walker, ObjectId id)
{
GitOid oid = id.Oid;
int res = NativeMethods.git_revwalk_push(walker, ref oid);
Ensure.ZeroResult(res);
}
public static unsafe void git_revwalk_reset(RevWalkerHandle walker)
{
NativeMethods.git_revwalk_reset(walker);
}
public static unsafe void git_revwalk_sorting(RevWalkerHandle walker, CommitSortStrategies options)
{
NativeMethods.git_revwalk_sorting(walker, options);
}
public static unsafe void git_revwalk_simplify_first_parent(RevWalkerHandle walker)
{
NativeMethods.git_revwalk_simplify_first_parent(walker);
}
#endregion
#region git_signature_
public static unsafe SignatureHandle git_signature_new(string name, string email, DateTimeOffset when)
{
git_signature* ptr;
int res = NativeMethods.git_signature_new(out ptr, name, email, when.ToSecondsSinceEpoch(),
(int)when.Offset.TotalMinutes);
Ensure.ZeroResult(res);
return new SignatureHandle(ptr, true);
}
public static unsafe SignatureHandle git_signature_now(string name, string email)
{
git_signature* ptr;
int res = NativeMethods.git_signature_now(out ptr, name, email);
Ensure.ZeroResult(res);
return new SignatureHandle(ptr, true);
}
public static unsafe git_signature* git_signature_dup(git_signature* sig)
{
git_signature* handle;
int res = NativeMethods.git_signature_dup(out handle, sig);
Ensure.ZeroResult(res);
return handle;
}
#endregion
#region git_stash_
public static unsafe ObjectId git_stash_save(
RepositoryHandle repo,
Signature stasher,
string prettifiedMessage,
StashModifiers options)
{
using (SignatureHandle sigHandle = stasher.BuildHandle())
{
GitOid stashOid;
int res = NativeMethods.git_stash_save(out stashOid, repo, sigHandle, prettifiedMessage, options);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.Int32Result(res);
return new ObjectId(stashOid);
}
}
public static unsafe ICollection git_stash_foreach(
RepositoryHandle repo,
Func resultSelector)
{
return git_foreach(resultSelector,
c => NativeMethods.git_stash_foreach(repo,
(UIntPtr i, IntPtr m, ref GitOid x, IntPtr p)
=> c((int)i, m, x, p),
IntPtr.Zero),
GitErrorCode.NotFound);
}
public static unsafe void git_stash_drop(RepositoryHandle repo, int index)
{
int res = NativeMethods.git_stash_drop(repo, (UIntPtr)index);
Ensure.BooleanResult(res);
}
private static StashApplyStatus get_stash_status(int res)
{
if (res == (int)GitErrorCode.Conflict)
{
return StashApplyStatus.Conflicts;
}
if (res == (int)GitErrorCode.Uncommitted)
{
return StashApplyStatus.UncommittedChanges;
}
if (res == (int)GitErrorCode.NotFound)
{
return StashApplyStatus.NotFound;
}
Ensure.ZeroResult(res);
return StashApplyStatus.Applied;
}
public static unsafe StashApplyStatus git_stash_apply(
RepositoryHandle repo,
int index,
GitStashApplyOpts opts)
{
return get_stash_status(NativeMethods.git_stash_apply(repo, (UIntPtr)index, opts));
}
public static unsafe StashApplyStatus git_stash_pop(
RepositoryHandle repo,
int index,
GitStashApplyOpts opts)
{
return get_stash_status(NativeMethods.git_stash_pop(repo, (UIntPtr)index, opts));
}
#endregion
#region git_status_
public static unsafe FileStatus git_status_file(RepositoryHandle repo, FilePath path)
{
FileStatus status;
int res = NativeMethods.git_status_file(out status, repo, path);
switch (res)
{
case (int)GitErrorCode.NotFound:
return FileStatus.Nonexistent;
case (int)GitErrorCode.Ambiguous:
throw new AmbiguousSpecificationException("More than one file matches the pathspec '{0}'. " +
"You can either force a literal path evaluation " +
"(GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH), or use git_status_foreach().",
path);
default:
Ensure.ZeroResult(res);
break;
}
return status;
}
public static unsafe StatusListHandle git_status_list_new(RepositoryHandle repo, GitStatusOptions options)
{
git_status_list* ptr;
int res = NativeMethods.git_status_list_new(out ptr, repo, options);
Ensure.ZeroResult(res);
return new StatusListHandle(ptr, true);
}
public static unsafe int git_status_list_entrycount(StatusListHandle list)
{
int res = NativeMethods.git_status_list_entrycount(list);
Ensure.Int32Result(res);
return res;
}
public static unsafe git_status_entry* git_status_byindex(StatusListHandle list, long idx)
{
return NativeMethods.git_status_byindex(list, (UIntPtr)idx);
}
#endregion
#region git_submodule_
///
/// Returns a handle to the corresponding submodule,
/// or an invalid handle if a submodule is not found.
///
public static unsafe SubmoduleHandle git_submodule_lookup(RepositoryHandle repo, FilePath name)
{
git_submodule* submodule;
var res = NativeMethods.git_submodule_lookup(out submodule, repo, name);
switch (res)
{
case (int)GitErrorCode.NotFound:
case (int)GitErrorCode.Exists:
case (int)GitErrorCode.OrphanedHead:
return null;
default:
Ensure.ZeroResult(res);
return new SubmoduleHandle(submodule, true);
}
}
public static unsafe string git_submodule_resolve_url(RepositoryHandle repo, string url)
{
using (var buf = new GitBuf())
{
int res = NativeMethods.git_submodule_resolve_url(buf, repo, url);
Ensure.ZeroResult(res);
return LaxUtf8Marshaler.FromNative(buf.ptr);
}
}
public static unsafe ICollection git_submodule_foreach(RepositoryHandle repo, Func resultSelector)
{
return git_foreach(resultSelector, c => NativeMethods.git_submodule_foreach(repo, (x, y, p) => c(x, y, p), IntPtr.Zero));
}
public static unsafe void git_submodule_add_to_index(SubmoduleHandle submodule, bool write_index)
{
var res = NativeMethods.git_submodule_add_to_index(submodule, write_index);
Ensure.ZeroResult(res);
}
public static unsafe void git_submodule_update(SubmoduleHandle submodule, bool init, ref GitSubmoduleOptions options)
{
var res = NativeMethods.git_submodule_update(submodule, init, ref options);
Ensure.ZeroResult(res);
}
public static unsafe string git_submodule_path(SubmoduleHandle submodule)
{
return NativeMethods.git_submodule_path(submodule);
}
public static unsafe string git_submodule_url(SubmoduleHandle submodule)
{
return NativeMethods.git_submodule_url(submodule);
}
public static unsafe ObjectId git_submodule_index_id(SubmoduleHandle submodule)
{
return ObjectId.BuildFromPtr(NativeMethods.git_submodule_index_id(submodule));
}
public static unsafe ObjectId git_submodule_head_id(SubmoduleHandle submodule)
{
Console.WriteLine("got git_oid for head {0}", NativeMethods.git_submodule_head_id(submodule) == null);
return ObjectId.BuildFromPtr(NativeMethods.git_submodule_head_id(submodule));
}
public static unsafe ObjectId git_submodule_wd_id(SubmoduleHandle submodule)
{
return ObjectId.BuildFromPtr(NativeMethods.git_submodule_wd_id(submodule));
}
public static unsafe SubmoduleIgnore git_submodule_ignore(SubmoduleHandle submodule)
{
return NativeMethods.git_submodule_ignore(submodule);
}
public static unsafe SubmoduleUpdate git_submodule_update_strategy(SubmoduleHandle submodule)
{
return NativeMethods.git_submodule_update_strategy(submodule);
}
public static unsafe SubmoduleRecurse git_submodule_fetch_recurse_submodules(SubmoduleHandle submodule)
{
return NativeMethods.git_submodule_fetch_recurse_submodules(submodule);
}
public static unsafe void git_submodule_reload(SubmoduleHandle submodule)
{
var res = NativeMethods.git_submodule_reload(submodule, false);
Ensure.ZeroResult(res);
}
public static unsafe SubmoduleStatus git_submodule_status(RepositoryHandle repo, string name)
{
SubmoduleStatus status;
var res = NativeMethods.git_submodule_status(out status, repo, name, GitSubmoduleIgnore.Unspecified);
Ensure.ZeroResult(res);
return status;
}
public static unsafe void git_submodule_init(SubmoduleHandle submodule, bool overwrite)
{
var res = NativeMethods.git_submodule_init(submodule, overwrite);
Ensure.ZeroResult(res);
}
#endregion
#region git_tag_
public static unsafe ObjectId git_tag_annotation_create(
RepositoryHandle repo,
string name,
GitObject target,
Signature tagger,
string message)
{
using (var objectPtr = new ObjectSafeWrapper(target.Id, repo))
using (SignatureHandle sigHandle = tagger.BuildHandle())
{
GitOid oid;
int res = NativeMethods.git_tag_annotation_create(out oid, repo, name, objectPtr.ObjectPtr, sigHandle, message);
Ensure.ZeroResult(res);
return oid;
}
}
public static unsafe ObjectId git_tag_create(
RepositoryHandle repo,
string name,
GitObject target,
Signature tagger,
string message,
bool allowOverwrite)
{
using (var objectPtr = new ObjectSafeWrapper(target.Id, repo))
using (SignatureHandle sigHandle = tagger.BuildHandle())
{
GitOid oid;
int res = NativeMethods.git_tag_create(out oid, repo, name, objectPtr.ObjectPtr, sigHandle, message, allowOverwrite);
Ensure.ZeroResult(res);
return oid;
}
}
public static unsafe ObjectId git_tag_create_lightweight(RepositoryHandle repo, string name, GitObject target, bool allowOverwrite)
{
using (var objectPtr = new ObjectSafeWrapper(target.Id, repo))
{
GitOid oid;
int res = NativeMethods.git_tag_create_lightweight(out oid, repo, name, objectPtr.ObjectPtr, allowOverwrite);
Ensure.ZeroResult(res);
return oid;
}
}
public static unsafe void git_tag_delete(RepositoryHandle repo, string name)
{
int res = NativeMethods.git_tag_delete(repo, name);
Ensure.ZeroResult(res);
}
public static unsafe IList git_tag_list(RepositoryHandle repo)
{
var array = new GitStrArrayNative();
try
{
int res = NativeMethods.git_tag_list(out array.Array, repo);
Ensure.ZeroResult(res);
return array.ReadStrings();
}
finally
{
array.Dispose();
}
}
public static unsafe string git_tag_message(ObjectHandle tag)
{
return NativeMethods.git_tag_message(tag);
}
public static unsafe string git_tag_name(ObjectHandle tag)
{
return NativeMethods.git_tag_name(tag);
}
public static unsafe Signature git_tag_tagger(ObjectHandle tag)
{
git_signature* taggerHandle = NativeMethods.git_tag_tagger(tag);
// Not all tags have a tagger signature - we need to handle
// this case.
Signature tagger = null;
if (taggerHandle != null)
{
tagger = new Signature(taggerHandle);
}
return tagger;
}
public static unsafe ObjectId git_tag_target_id(ObjectHandle tag)
{
return ObjectId.BuildFromPtr(NativeMethods.git_tag_target_id(tag));
}
public static unsafe GitObjectType git_tag_target_type(ObjectHandle tag)
{
return NativeMethods.git_tag_target_type(tag);
}
#endregion
#region git_trace_
///
/// Install/Enable logging inside of LibGit2 to send messages back to LibGit2Sharp.
///
/// Since the given callback will be passed into and retained by C code,
/// it is very important that you pass an actual delegate here (and don't
/// let the compiler create/cast a temporary one for you). Furthermore, you
/// must hold a reference to this delegate until you turn off logging.
///
/// This callback is unlike other callbacks because logging persists in the
/// process until disabled; in contrast, most callbacks are only defined for
/// the duration of the down-call.
///
public static void git_trace_set(LogLevel level, NativeMethods.git_trace_cb callback)
{
int res = NativeMethods.git_trace_set(level, callback);
Ensure.ZeroResult(res);
}
#endregion
#region git_transport_
public static void git_transport_register(String prefix, IntPtr transport_cb, IntPtr param)
{
int res = NativeMethods.git_transport_register(prefix, transport_cb, param);
if (res == (int)GitErrorCode.Exists)
{
throw new EntryExistsException("A custom transport for '{0}' is already registered",
prefix);
}
Ensure.ZeroResult(res);
}
public static void git_transport_unregister(String prefix)
{
int res = NativeMethods.git_transport_unregister(prefix);
if (res == (int)GitErrorCode.NotFound)
{
throw new NotFoundException("The given transport was not found");
}
Ensure.ZeroResult(res);
}
#endregion
#region git_tree_
public static unsafe Mode git_tree_entry_attributes(git_tree_entry* entry)
{
return (Mode)NativeMethods.git_tree_entry_filemode(entry);
}
public static unsafe TreeEntryHandle git_tree_entry_byindex(ObjectHandle tree, long idx)
{
var handle = NativeMethods.git_tree_entry_byindex(tree, (UIntPtr)idx);
if (handle == null)
{
return null;
}
return new TreeEntryHandle(handle, false);
}
public static unsafe TreeEntryHandle git_tree_entry_bypath(RepositoryHandle repo, ObjectId id, FilePath treeentry_path)
{
using (var obj = new ObjectSafeWrapper(id, repo))
{
git_tree_entry* treeEntryPtr;
int res = NativeMethods.git_tree_entry_bypath(out treeEntryPtr, obj.ObjectPtr, treeentry_path);
if (res == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(res);
return new TreeEntryHandle(treeEntryPtr, true);
}
}
public static unsafe ObjectId git_tree_entry_id(git_tree_entry* entry)
{
return ObjectId.BuildFromPtr(NativeMethods.git_tree_entry_id(entry));
}
public static unsafe string git_tree_entry_name(git_tree_entry* entry)
{
return NativeMethods.git_tree_entry_name(entry);
}
public static unsafe GitObjectType git_tree_entry_type(git_tree_entry* entry)
{
return NativeMethods.git_tree_entry_type(entry);
}
public static unsafe int git_tree_entrycount(ObjectHandle tree)
{
return (int)NativeMethods.git_tree_entrycount(tree);
}
#endregion
#region git_treebuilder_
public static unsafe TreeBuilderHandle git_treebuilder_new(RepositoryHandle repo)
{
git_treebuilder* builder;
int res = NativeMethods.git_treebuilder_new(out builder, repo, IntPtr.Zero);
Ensure.ZeroResult(res);
return new TreeBuilderHandle(builder, true);
}
public static unsafe void git_treebuilder_insert(TreeBuilderHandle builder, string treeentry_name, TreeEntryDefinition treeEntryDefinition)
{
GitOid oid = treeEntryDefinition.TargetId.Oid;
int res = NativeMethods.git_treebuilder_insert(IntPtr.Zero, builder, treeentry_name, ref oid,
(uint)treeEntryDefinition.Mode);
Ensure.ZeroResult(res);
}
public static unsafe ObjectId git_treebuilder_write(TreeBuilderHandle bld)
{
GitOid oid;
int res = NativeMethods.git_treebuilder_write(out oid, bld);
Ensure.ZeroResult(res);
return oid;
}
#endregion
#region git_libgit2_
///
/// Returns the features with which libgit2 was compiled.
///
public static BuiltInFeatures git_libgit2_features()
{
return (BuiltInFeatures)NativeMethods.git_libgit2_features();
}
// C# equivalent of libgit2's git_libgit2_opt_t
private enum LibGitOption
{
GetMWindowSize, // GIT_OPT_GET_MWINDOW_SIZE
SetMWindowSize, // GIT_OPT_SET_MWINDOW_SIZE
GetMWindowMappedLimit, // GIT_OPT_GET_MWINDOW_MAPPED_LIMIT
SetMWindowMappedLimit, // GIT_OPT_SET_MWINDOW_MAPPED_LIMIT
GetSearchPath, // GIT_OPT_GET_SEARCH_PATH
SetSearchPath, // GIT_OPT_SET_SEARCH_PATH
SetCacheObjectLimit, // GIT_OPT_SET_CACHE_OBJECT_LIMIT
SetCacheMaxSize, // GIT_OPT_SET_CACHE_MAX_SIZE
EnableCaching, // GIT_OPT_ENABLE_CACHING
GetCachedMemory, // GIT_OPT_GET_CACHED_MEMORY
GetTemplatePath, // GIT_OPT_GET_TEMPLATE_PATH
SetTemplatePath, // GIT_OPT_SET_TEMPLATE_PATH
SetSslCertLocations, // GIT_OPT_SET_SSL_CERT_LOCATIONS
}
///
/// Get the paths under which libgit2 searches for the configuration file of a given level.
///
/// The level (global/system/XDG) of the config.
///
/// The paths delimited by 'GIT_PATH_LIST_SEPARATOR'.
///
public static string git_libgit2_opts_get_search_path(ConfigurationLevel level)
{
string path;
using (var buf = new GitBuf())
{
var res = NativeMethods.git_libgit2_opts((int)LibGitOption.GetSearchPath, (uint)level, buf);
Ensure.ZeroResult(res);
path = LaxUtf8Marshaler.FromNative(buf.ptr) ?? string.Empty;
}
return path;
}
///
/// Set the path(s) under which libgit2 searches for the configuration file of a given level.
///
/// The level (global/system/XDG) of the config.
///
/// A string of paths delimited by 'GIT_PATH_LIST_SEPARATOR'.
/// Pass null to reset the search path to the default.
///
public static void git_libgit2_opts_set_search_path(ConfigurationLevel level, string path)
{
var res = NativeMethods.git_libgit2_opts((int)LibGitOption.SetSearchPath, (uint)level, path);
Ensure.ZeroResult(res);
}
#endregion
private static ICollection git_foreach(
Func resultSelector,
Func, int> iterator,
params GitErrorCode[] ignoredErrorCodes)
{
var result = new List();
var res = iterator((x, payload) =>
{
result.Add(resultSelector(x));
return 0;
});
if (ignoredErrorCodes != null && ignoredErrorCodes.Contains((GitErrorCode)res))
{
return new TResult[0];
}
Ensure.ZeroResult(res);
return result;
}
private static ICollection git_foreach(
Func resultSelector,
Func, int> iterator,
params GitErrorCode[] ignoredErrorCodes)
{
var result = new List();
var res = iterator((x, y, payload) =>
{
result.Add(resultSelector(x, y));
return 0;
});
if (ignoredErrorCodes != null && ignoredErrorCodes.Contains((GitErrorCode)res))
{
return new TResult[0];
}
Ensure.ZeroResult(res);
return result;
}
private static ICollection git_foreach(
Func resultSelector,
Func, int> iterator,
params GitErrorCode[] ignoredErrorCodes)
{
var result = new List();
var res = iterator((w, x, y, payload) =>
{
result.Add(resultSelector(w, x, y));
return 0;
});
if (ignoredErrorCodes != null && ignoredErrorCodes.Contains((GitErrorCode)res))
{
return new TResult[0];
}
Ensure.ZeroResult(res);
return result;
}
public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
private static ICollection git_foreach(
Func resultSelector,
Func, int> iterator,
params GitErrorCode[] ignoredErrorCodes)
{
var result = new List();
var res = iterator((w, x, y, z, payload) =>
{
result.Add(resultSelector(w, x, y, z));
return 0;
});
if (ignoredErrorCodes != null && ignoredErrorCodes.Contains((GitErrorCode)res))
{
return new TResult[0];
}
Ensure.ZeroResult(res);
return result;
}
private static unsafe bool RepositoryStateChecker(RepositoryHandle repo, Func checker)
{
int res = checker(repo.AsIntPtr());
Ensure.BooleanResult(res);
return (res == 1);
}
private static FilePath ConvertPath(Func pathRetriever)
{
using (var buf = new GitBuf())
{
int result = pathRetriever(buf);
if (result == (int)GitErrorCode.NotFound)
{
return null;
}
Ensure.ZeroResult(result);
return LaxFilePathMarshaler.FromNative(buf.ptr);
}
}
private static readonly IDictionary> configurationParser = new Dictionary>
{
{ typeof(int), value => git_config_parse_int32(value) },
{ typeof(long), value => git_config_parse_int64(value) },
{ typeof(bool), value => git_config_parse_bool(value) },
{ typeof(string), value => value },
};
///
/// Helper method for consistent conversion of return value on
/// Callbacks that support cancellation from bool to native type.
/// True indicates that function should continue, false indicates
/// user wants to cancel.
///
///
///
internal static int ConvertResultToCancelFlag(bool result)
{
return result ? 0 : (int)GitErrorCode.User;
}
}
///
/// Class to hold extension methods used by the proxy class.
///
static class ProxyExtensions
{
///
/// Convert a UIntPtr to a int value. Will throw
/// exception if there is an overflow.
///
///
///
public static int ConvertToInt(this UIntPtr input)
{
ulong ulongValue = (ulong)input;
if (ulongValue > int.MaxValue)
{
throw new LibGit2SharpException("value exceeds size of an int");
}
return (int)input;
}
///
/// Convert a UIntPtr to a long value. Will throw
/// exception if there is an overflow.
///
///
///
public static long ConvertToLong(this UIntPtr input)
{
ulong ulongValue = (ulong)input;
if (ulongValue > long.MaxValue)
{
throw new LibGit2SharpException("value exceeds size of long");
}
return (long)input;
}
}
}
// ReSharper restore InconsistentNaming