using System; using LibGit2Sharp.Core; namespace LibGit2Sharp { /// /// A Repository is the primary interface into a git repository /// public class Repository : IDisposable { private readonly BranchCollection branches; private readonly CommitCollection commits; private readonly RepositorySafeHandle handle; private readonly Index index; private readonly ReferenceCollection refs; private readonly TagCollection tags; /// /// Initializes a new instance of the class. /// For a standard repository, should point to the ".git" folder. For a bare repository, should directly point to the repository folder. /// /// The path to the git repository to open. public Repository(string path) { Ensure.ArgumentNotNullOrEmptyString(path, "path"); var res = NativeMethods.git_repository_open(out handle, PosixPathHelper.ToPosix(path)); Ensure.Success(res); string normalizedPath = NativeMethods.git_repository_path(handle); string normalizedWorkDir = NativeMethods.git_repository_workdir(handle); Info = new RepositoryInformation(this, normalizedPath, normalizedWorkDir, normalizedWorkDir == null); if (!Info.IsBare) index = new Index(this); commits = new CommitCollection(this); refs = new ReferenceCollection(this); branches = new BranchCollection(this); tags = new TagCollection(this); } internal RepositorySafeHandle Handle { get { return handle; } } /// /// Shortcut to return the reference to HEAD /// /// public Reference Head { get { return Refs["HEAD"]; } } /// /// Gets the index. /// public Index Index { get { return index; } } /// /// Lookup and enumerate references in the repository. /// public ReferenceCollection Refs { get { return refs; } } /// /// Lookup and enumerate commits in the repository. /// Iterating this collection directly starts walking from the HEAD. /// public CommitCollection Commits { get { return commits.StartingAt(Head); } } /// /// Lookup and enumerate branches in the repository. /// public BranchCollection Branches { get { return branches; } } /// /// Lookup and enumerate tags in the repository. /// public TagCollection Tags { get { return tags; } } /// /// Provides high level information about this repository. /// public RepositoryInformation Info { get; set; } #region IDisposable Members /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// protected virtual void Dispose(bool disposing) { if (handle != null && !handle.IsInvalid) { handle.Dispose(); } if (index != null) { index.Dispose(); } } #endregion /// /// Tells if the specified sha exists in the repository. /// /// Exceptions: /// ArgumentException /// ArgumentNullException /// /// The sha. /// public bool HasObject(string sha) { Ensure.ArgumentNotNullOrEmptyString(sha, "sha"); var id = new ObjectId(sha); var odb = NativeMethods.git_repository_database(handle); var oid = id.Oid; return NativeMethods.git_odb_exists(odb, ref oid); } /// /// Init a repo at the specified . /// /// The path to the working folder when initializing a standard ".git" repository. Otherwise, when initializing a bare repository, the path to the expected location of this later. /// true to initialize a bare repository. False otherwise, to initialize a standard ".git" repository. /// Path the git repository. public static string Init(string path, bool bare = false) { Ensure.ArgumentNotNullOrEmptyString(path, "path"); RepositorySafeHandle repo; var res = NativeMethods.git_repository_init(out repo, PosixPathHelper.ToPosix(path), bare); Ensure.Success(res); string normalizedPath = NativeMethods.git_repository_path(repo); repo.Dispose(); return PosixPathHelper.ToNative(normalizedPath); } /// /// Try to lookup an object by its and . If no matching object is found, null will be returned. /// /// The id to lookup. /// The kind of GitObject being looked up /// The or null if it was not found. public GitObject Lookup(ObjectId id, GitObjectType type = GitObjectType.Any) { Ensure.ArgumentNotNull(id, "id"); var oid = id.Oid; IntPtr obj; var res = NativeMethods.git_object_lookup(out obj, handle, ref oid, type); if (res == (int)GitErrorCode.GIT_ENOTFOUND || res == (int)GitErrorCode.GIT_EINVALIDTYPE) { return null; } Ensure.Success(res); return GitObject.CreateFromPtr(obj, id, this); } /// /// Try to lookup an object by its sha or a reference canonical name and . If no matching object is found, null will be returned. /// /// The sha or reference canonical name to lookup. /// The kind of being looked up /// The or null if it was not found. public GitObject Lookup(string shaOrReferenceName, GitObjectType type = GitObjectType.Any) { ObjectId id = ObjectId.CreateFromMaybeSha(shaOrReferenceName); if (id != null) { return Lookup(id, type); } var reference = Refs[shaOrReferenceName]; if (!IsReferencePeelable(reference)) { return null; } return Lookup(reference.ResolveToDirectReference().TargetIdentifier, type); } private static bool IsReferencePeelable(Reference reference) { return reference != null && ((reference is DirectReference) ||(reference is SymbolicReference && ((SymbolicReference)reference).Target != null)); } } }