diff --git a/Lib/git2.dll b/Lib/git2.dll index 969786a29..3b2f252ea 100644 Binary files a/Lib/git2.dll and b/Lib/git2.dll differ diff --git a/LibGit2Sharp.Tests/BranchFixture.cs b/LibGit2Sharp.Tests/BranchFixture.cs index ea4daae66..45c5636a3 100644 --- a/LibGit2Sharp.Tests/BranchFixture.cs +++ b/LibGit2Sharp.Tests/BranchFixture.cs @@ -9,7 +9,7 @@ namespace LibGit2Sharp.Tests [TestFixture] public class BranchFixture { - private readonly List expectedBranches = new List {"packed-test", "packed", "br2", "master", "test"}; + private readonly List expectedBranches = new List {"packed-test", "packed", "br2", "master", "test", "deadbeef"}; [Test] public void CanCheckoutAnExistingBranch() @@ -76,7 +76,7 @@ public void CanListAllBranches() Assert.Contains(r.Name, expectedBranches); } - repo.Branches.Count().ShouldEqual(5); + repo.Branches.Count().ShouldEqual(6); } } diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index c1cb68f9b..e3effe9fc 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -22,6 +22,21 @@ public void CanCountCommits() } } + [Test] + public void CanCorrectlyCountCommitsWhenSwitchingToAnotherBranch() + { + using (var repo = new Repository(Constants.TestRepoPath)) + { + repo.Branches.Checkout("test"); + repo.Commits.Count.ShouldEqual(2); + repo.Commits.First().Id.Sha.ShouldEqual("e90810b8df3e80c413d903f631643c716887138d"); + + repo.Branches.Checkout("master"); + repo.Commits.Count.ShouldEqual(7); + repo.Commits.First().Id.Sha.ShouldEqual("4c062a6361ae6959e06292c1fa5e2822d9c96345"); + } + } + [Test] public void CanEnumerateCommits() { @@ -37,6 +52,15 @@ public void CanEnumerateCommits() count.ShouldEqual(7); } + [Test] + public void DefaultOrderingWhenEnumeratingCommitsIsTimeBased() + { + using (var repo = new Repository(Constants.TestRepoPath)) + { + repo.Commits.SortedBy.ShouldEqual(GitSortOptions.Time); + } + } + [Test] public void CanEnumerateCommitsFromSha() { @@ -52,6 +76,18 @@ public void CanEnumerateCommitsFromSha() count.ShouldEqual(6); } + [Test] + public void BuildingACommitCollectionFromUnknownShaOrInvalidReferenceThrows() + { + using (var repo = new Repository(Constants.TestRepoPath)) + { + Assert.Throws(() => repo.Commits.StartingAt(Constants.UnknownSha)); + Assert.Throws(() => repo.Commits.StartingAt("refs/heads/deadbeef")); + Assert.Throws(() => repo.Commits.StartingAt(repo.Branches["deadbeef"])); + Assert.Throws(() => repo.Commits.StartingAt(repo.Refs["refs/heads/deadbeef"])); + } + } + [Test] public void CanEnumerateCommitsWithReverseTimeSorting() { @@ -74,7 +110,7 @@ public void CanEnumerateCommitsWithReverseTopoSorting() { using (var repo = new Repository(Constants.TestRepoPath)) { - var commits = repo.Commits.StartingAt("a4a7dce85cf63874e984719f4fdd239f5145052f").SortBy(GitSortOptions.Topo | GitSortOptions.Reverse).ToList(); + var commits = repo.Commits.StartingAt("a4a7dce85cf63874e984719f4fdd239f5145052f").SortBy(GitSortOptions.Topological | GitSortOptions.Reverse).ToList(); foreach (var commit in commits) { commit.ShouldNotBeNull(); @@ -108,7 +144,7 @@ public void CanEnumerateCommitsWithTopoSorting() { using (var repo = new Repository(Constants.TestRepoPath)) { - var commits = repo.Commits.StartingAt("a4a7dce85cf63874e984719f4fdd239f5145052f").SortBy(GitSortOptions.Topo).ToList(); + var commits = repo.Commits.StartingAt("a4a7dce85cf63874e984719f4fdd239f5145052f").SortBy(GitSortOptions.Topological).ToList(); foreach (var commit in commits) { commit.ShouldNotBeNull(); diff --git a/LibGit2Sharp.Tests/Constants.cs b/LibGit2Sharp.Tests/Constants.cs index c05e3e384..757b1a667 100644 --- a/LibGit2Sharp.Tests/Constants.cs +++ b/LibGit2Sharp.Tests/Constants.cs @@ -5,5 +5,6 @@ public static class Constants public const string TestRepoPath = "./Resources/testrepo.git"; public const string TestRepoWithWorkingDirPath = "./Resources/testrepo_wd/.git"; public const string TemporaryReposPath = "TestRepos"; + public const string UnknownSha = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; } } \ No newline at end of file diff --git a/LibGit2Sharp.Tests/IndexFixture.cs b/LibGit2Sharp.Tests/IndexFixture.cs index cec992763..ed8cfa480 100644 --- a/LibGit2Sharp.Tests/IndexFixture.cs +++ b/LibGit2Sharp.Tests/IndexFixture.cs @@ -139,16 +139,14 @@ public void CanStageANewFileWithAFullPath() [Test] public void StagingANewFileWithAFullPathWhichEscapesOutOfTheWorkingDirThrows() { - string tempPath = new DirectoryInfo("./temp").FullName; - - using (new SelfCleaningDirectory(tempPath)) + using (var scd = new SelfCleaningDirectory()) using (var path = new TemporaryCloneOfTestRepo(Constants.TestRepoWithWorkingDirPath)) using (var repo = new Repository(path.RepositoryPath)) { - Directory.CreateDirectory(tempPath); + var di = Directory.CreateDirectory(scd.DirectoryPath); const string filename = "unit_test.txt"; - string fullPath = Path.Combine(tempPath, filename); + string fullPath = Path.Combine(di.FullName, filename); File.WriteAllText(fullPath, "some contents"); Assert.Throws(() => repo.Index.Stage(fullPath)); diff --git a/LibGit2Sharp.Tests/ReferenceFixture.cs b/LibGit2Sharp.Tests/ReferenceFixture.cs index ab13754d0..62db480fc 100644 --- a/LibGit2Sharp.Tests/ReferenceFixture.cs +++ b/LibGit2Sharp.Tests/ReferenceFixture.cs @@ -9,7 +9,8 @@ namespace LibGit2Sharp.Tests [TestFixture] public class ReferenceFixture { - private readonly List expectedRefs = new List {"refs/heads/packed-test", "refs/heads/packed", "refs/heads/br2", "refs/heads/master", "refs/heads/test", "refs/tags/test", "refs/tags/e90810b", "refs/tags/lw"}; + private readonly List expectedRefs = new List { "refs/heads/packed-test", "refs/heads/packed", "refs/heads/br2", "refs/heads/master", "refs/heads/test", + "refs/heads/deadbeef", "refs/tags/test", "refs/tags/e90810b", "refs/tags/lw" }; [Test] public void CanCreateADirectReference() @@ -211,7 +212,7 @@ public void CanListAllReferences() Assert.Contains(r.CanonicalName, expectedRefs); } - repo.Refs.Count().ShouldEqual(8); + repo.Refs.Count().ShouldEqual(9); } } diff --git a/LibGit2Sharp.Tests/RepositoryFixture.cs b/LibGit2Sharp.Tests/RepositoryFixture.cs index d88334736..9a3c91dd3 100644 --- a/LibGit2Sharp.Tests/RepositoryFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryFixture.cs @@ -8,23 +8,21 @@ namespace LibGit2Sharp.Tests [TestFixture] public class RepositoryFixture { - private const string newRepoPath = "new_repo"; - private const string commitSha = "8496071c1b46c854b31185ea97743be6a8774479"; - private const string notFoundSha = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; [Test] public void CanCreateBareRepo() { - using (new SelfCleaningDirectory(newRepoPath)) + using (var scd = new SelfCleaningDirectory()) { - var dir = Repository.Init(newRepoPath, true); + var dir = Repository.Init(scd.DirectoryPath, true); Path.IsPathRooted(dir).ShouldBeTrue(); Directory.Exists(dir).ShouldBeTrue(); using (var repo = new Repository(dir)) { repo.Info.WorkingDirectory.ShouldBeNull(); + repo.Info.Path.ShouldEqual(scd.RootedDirectoryPath + @"\"); repo.Info.IsBare.ShouldBeTrue(); AssertInitializedRepository(repo); @@ -35,15 +33,16 @@ public void CanCreateBareRepo() [Test] public void CanCreateStandardRepo() { - using (new SelfCleaningDirectory(newRepoPath)) + using (var scd = new SelfCleaningDirectory()) { - var dir = Repository.Init(newRepoPath); + var dir = Repository.Init(scd.DirectoryPath); Path.IsPathRooted(dir).ShouldBeTrue(); Directory.Exists(dir).ShouldBeTrue(); using (var repo = new Repository(dir)) { repo.Info.WorkingDirectory.ShouldNotBeNull(); + repo.Info.Path.ShouldEqual(Path.Combine(scd.RootedDirectoryPath, ".git" + @"\")); repo.Info.IsBare.ShouldBeFalse(); AssertInitializedRepository(repo); @@ -137,8 +136,8 @@ public void LookupObjectByWrongShaReturnsNull() { using (var repo = new Repository(Constants.TestRepoPath)) { - repo.Lookup(notFoundSha).ShouldBeNull(); - repo.Lookup(notFoundSha).ShouldBeNull(); + repo.Lookup(Constants.UnknownSha).ShouldBeNull(); + repo.Lookup(Constants.UnknownSha).ShouldBeNull(); } } @@ -159,7 +158,7 @@ public void LookupObjectByUnknownReferenceNameReturnsNull() using (var repo = new Repository(Constants.TestRepoPath)) { repo.Lookup("refs/heads/chopped/off").ShouldBeNull(); - repo.Lookup(notFoundSha).ShouldBeNull(); + repo.Lookup(Constants.UnknownSha).ShouldBeNull(); } } @@ -238,9 +237,9 @@ public void CheckingForObjectExistenceWithBadParamsThrows() [Test] public void CheckForDetachedHeadOnNewRepo() { - using (new SelfCleaningDirectory(newRepoPath)) + using (var scd = new SelfCleaningDirectory()) { - var dir = Repository.Init(newRepoPath, true); + var dir = Repository.Init(scd.DirectoryPath, true); Path.IsPathRooted(dir).ShouldBeTrue(); Directory.Exists(dir).ShouldBeTrue(); diff --git a/LibGit2Sharp.Tests/TagFixture.cs b/LibGit2Sharp.Tests/TagFixture.cs index 4d121b901..4299556d5 100644 --- a/LibGit2Sharp.Tests/TagFixture.cs +++ b/LibGit2Sharp.Tests/TagFixture.cs @@ -10,8 +10,6 @@ namespace LibGit2Sharp.Tests [TestFixture] public class TagFixture { - private const string newRepoPath = "new_repo"; - private readonly List expectedTags = new List {"test", "e90810b", "lw"}; private static readonly Signature signatureTim = new Signature("Tim Clem", "timothy.clem@gmail.com", DateTimeOffset.UtcNow); @@ -19,7 +17,6 @@ public class TagFixture private const string tagTestSha = "b25fa35b38051e4ae45d4222e795f9df2e43f1d1"; private const string commitE90810BSha = "e90810b8df3e80c413d903f631643c716887138d"; private const string tagE90810BSha = "7b4384978d2493e851f9cca7858815fac9b10980"; - const string invalidTargetId = "deadbeef1b46c854b31185ea97743be6a8774479"; [Test] public void CanCreateALightWeightTagFromSha() @@ -159,9 +156,9 @@ public void CreatingAnAnnotatedTagIsDeterministic() [Description("Ported from cgit (https://github.com/git/git/blob/1c08bf50cfcf924094eca56c2486a90e2bf1e6e2/t/t7004-tag.sh#L32)")] public void CreatingATagInAEmptyRepositoryThrows() { - using (new SelfCleaningDirectory(newRepoPath)) + using (var scd = new SelfCleaningDirectory()) { - var dir = Repository.Init(newRepoPath); + var dir = Repository.Init(scd.DirectoryPath); using (var repo = new Repository(dir)) { @@ -174,9 +171,9 @@ public void CreatingATagInAEmptyRepositoryThrows() [Description("Ported from cgit (https://github.com/git/git/blob/1c08bf50cfcf924094eca56c2486a90e2bf1e6e2/t/t7004-tag.sh#L37)")] public void CreatingATagForHeadInAEmptyRepositoryThrows() { - using (new SelfCleaningDirectory(newRepoPath)) + using (var scd = new SelfCleaningDirectory()) { - var dir = Repository.Init(newRepoPath); + var dir = Repository.Init(scd.DirectoryPath); using (var repo = new Repository(dir)) { @@ -203,7 +200,7 @@ public void CreatingATagForAnUnknowObjectIdShouldFail() using (var path = new TemporaryCloneOfTestRepo()) using (var repo = new Repository(path.RepositoryPath)) { - Assert.Throws(() => repo.ApplyTag("mytagnorev", invalidTargetId)); + Assert.Throws(() => repo.ApplyTag("mytagnorev", Constants.UnknownSha)); } } @@ -399,7 +396,7 @@ public void CreateTagWithNotExistingTargetThrows() { using (var repo = new Repository(Constants.TestRepoPath)) { - Assert.Throws(() => repo.Tags.Create("test_tag", invalidTargetId, signatureTim, "message")); + Assert.Throws(() => repo.Tags.Create("test_tag", Constants.UnknownSha, signatureTim, "message")); } } @@ -520,9 +517,9 @@ public void CanListTags() [Description("Ported from cgit (https://github.com/git/git/blob/1c08bf50cfcf924094eca56c2486a90e2bf1e6e2/t/t7004-tag.sh#L24)")] public void CanListAllTagsInAEmptyRepository() { - using (new SelfCleaningDirectory(newRepoPath)) + using (var scd = new SelfCleaningDirectory()) { - var dir = Repository.Init(newRepoPath); + var dir = Repository.Init(scd.DirectoryPath); using (var repo = new Repository(dir)) { diff --git a/LibGit2Sharp.Tests/TestHelpers/SelfCleaningDirectory.cs b/LibGit2Sharp.Tests/TestHelpers/SelfCleaningDirectory.cs index 62f1cb1f0..c6576923c 100644 --- a/LibGit2Sharp.Tests/TestHelpers/SelfCleaningDirectory.cs +++ b/LibGit2Sharp.Tests/TestHelpers/SelfCleaningDirectory.cs @@ -5,7 +5,9 @@ namespace LibGit2Sharp.Tests.TestHelpers { public class SelfCleaningDirectory : IDisposable { - private readonly string path; + public SelfCleaningDirectory() : this(BuildTempPath()) + { + } public SelfCleaningDirectory(string path) { @@ -14,26 +16,31 @@ public SelfCleaningDirectory(string path) throw new InvalidOperationException("Directory '{0}' already exists."); } - this.path = path; + DirectoryPath = path; + RootedDirectoryPath = Path.GetFullPath(path); } - protected string DirectoryPath - { - get { return path; } - } + + public string DirectoryPath { get; private set; } + public string RootedDirectoryPath { get; private set; } #region IDisposable Members public void Dispose() { - if (!Directory.Exists(path)) + if (!Directory.Exists(DirectoryPath)) { throw new InvalidOperationException("Directory '{0}' doesn't exist any longer."); } - DirectoryHelper.DeleteDirectory(path); + DirectoryHelper.DeleteDirectory(DirectoryPath); } #endregion + + protected static string BuildTempPath() + { + return Path.Combine(Constants.TemporaryReposPath, Guid.NewGuid().ToString().Substring(0, 8)); + } } } \ No newline at end of file diff --git a/LibGit2Sharp.Tests/TestHelpers/TemporaryCloneOfTestRepo.cs b/LibGit2Sharp.Tests/TestHelpers/TemporaryCloneOfTestRepo.cs index 4b61460bd..9725b7e65 100644 --- a/LibGit2Sharp.Tests/TestHelpers/TemporaryCloneOfTestRepo.cs +++ b/LibGit2Sharp.Tests/TestHelpers/TemporaryCloneOfTestRepo.cs @@ -1,14 +1,12 @@ -using System; -using System.IO; +using System.IO; namespace LibGit2Sharp.Tests.TestHelpers { public class TemporaryCloneOfTestRepo : SelfCleaningDirectory { - public TemporaryCloneOfTestRepo(string path = Constants.TestRepoPath) - : base(BuildTempPath()) + public TemporaryCloneOfTestRepo(string sourceDirectoryPath = Constants.TestRepoPath) { - var source = new DirectoryInfo(path); + var source = new DirectoryInfo(sourceDirectoryPath); var tempRepository = new DirectoryInfo(Path.Combine(DirectoryPath, source.Name)); RepositoryPath = tempRepository.FullName; @@ -16,10 +14,5 @@ public TemporaryCloneOfTestRepo(string path = Constants.TestRepoPath) } public string RepositoryPath { get; private set; } - - private static string BuildTempPath() - { - return Path.Combine(Constants.TemporaryReposPath, Guid.NewGuid().ToString().Substring(0, 8)); - } } } \ No newline at end of file diff --git a/LibGit2Sharp/CommitCollection.cs b/LibGit2Sharp/CommitCollection.cs index 15c0fa0f7..7be815047 100644 --- a/LibGit2Sharp/CommitCollection.cs +++ b/LibGit2Sharp/CommitCollection.cs @@ -11,16 +11,27 @@ namespace LibGit2Sharp public class CommitCollection : IEnumerable { private readonly Repository repo; - private string pushedSha; - private GitSortOptions sortOptions = GitSortOptions.None; + private ObjectId pushedObjectId; + private readonly GitSortOptions sortOptions; + + /// + /// Initializes a new instance of the class. + /// The commits will be enumerated according in reverse chronological order. + /// + /// The repository. + internal CommitCollection(Repository repo) : this (repo, GitSortOptions.Time) + { + } /// /// Initializes a new instance of the class. /// - /// The repo. - internal CommitCollection(Repository repo) + /// The repository. + /// The sorting strategy which should be applied when enumerating the commits. + internal CommitCollection(Repository repo, GitSortOptions sortingStrategy) { this.repo = repo; + sortOptions = sortingStrategy; } /// @@ -32,23 +43,29 @@ public Commit this[string sha] } /// - /// Gets the Count of commits (This is a fast count that does not hydrate real commit objects) + /// Gets the count of commits (This is a fast count that does not hydrate real commit objects) /// public int Count { get { var count = 0; - using (var enumerator = new CommitEnumerator(repo, true)) + using (var enumerator = new CommitEnumerator(repo, pushedObjectId, sortOptions)) { - enumerator.Sort(sortOptions); - enumerator.Push(pushedSha); while (enumerator.MoveNext()) count++; } return count; } } + /// + /// Gets the current sorting strategy applied when enumerating the collection + /// + public GitSortOptions SortedBy + { + get { return sortOptions; } + } + #region IEnumerable Members /// @@ -57,15 +74,12 @@ public int Count /// An object that can be used to iterate through the collection. public IEnumerator GetEnumerator() { - if (string.IsNullOrEmpty(pushedSha)) + if (pushedObjectId == null) { throw new NotImplementedException(); - } - - var enumerator = new CommitEnumerator(repo); - enumerator.Sort(sortOptions); - enumerator.Push(pushedSha); - return enumerator; + } + + return new CommitEnumerator(repo, pushedObjectId, sortOptions); } /// @@ -80,76 +94,65 @@ IEnumerator IEnumerable.GetEnumerator() #endregion /// - /// Sorts with the specified options. - /// - /// The options. - /// - public CommitCollection SortBy(GitSortOptions options) - { - return new CommitCollection(repo) { sortOptions = options, pushedSha = pushedSha }; - } - - /// - /// Starts enumeratoring the at the specified branch. + /// Sorts according to the specified strategy. /// - /// The branch. + /// The sorting strategy to be applied when enumerating the commits. /// - public CommitCollection StartingAt(Branch branch) + public CommitCollection SortBy(GitSortOptions sortingStrategy) { - Ensure.ArgumentNotNull(branch, "branch"); - - return new CommitCollection(repo) { sortOptions = sortOptions, pushedSha = branch.Tip.Sha }; + return new CommitCollection(repo, sortingStrategy) { pushedObjectId = pushedObjectId }; } /// - /// Starts enumeratoring the at the specified reference. + /// Starts enumeratoring the at the specified sha. /// - /// The reference. + /// The sha or reference canonical name to use. /// - public CommitCollection StartingAt(Reference reference) + public CommitCollection StartingAt(string shaOrReferenceName) { - Ensure.ArgumentNotNull(reference, "reference"); + Ensure.ArgumentNotNullOrEmptyString(shaOrReferenceName, "shaOrReferenceName"); - return new CommitCollection(repo) { sortOptions = sortOptions, pushedSha = reference.ResolveToDirectReference().Target.Sha }; - } + GitObject gitObj = repo.Lookup(shaOrReferenceName); - /// - /// Starts enumeratoring the at the specified sha. - /// - /// The sha. - /// - public CommitCollection StartingAt(string sha) - { - Ensure.ArgumentNotNullOrEmptyString(sha, "sha"); + if (gitObj == null) // TODO: Should we check the type? Git-log allows TagAnnotation oid as parameter. But what about Blobs and Trees? + { + throw new ArgumentException(string.Format("No valid object identified as '{0}' has been found in the repository.", shaOrReferenceName), "shaOrReferenceName"); + } - return new CommitCollection(repo) { sortOptions = sortOptions, pushedSha = sha }; + return new CommitCollection(repo, sortOptions) { pushedObjectId = gitObj.Id }; } #region Nested type: CommitEnumerator private class CommitEnumerator : IEnumerator { - private readonly bool forCountOnly; private readonly Repository repo; - private readonly IntPtr walker = IntPtr.Zero; //TODO: Convert to SafeHandle? - private bool disposed; + private readonly RevWalkerSafeHandle handle; + private ObjectId currentOid; - public CommitEnumerator(Repository repo, bool forCountOnly = false) + public CommitEnumerator(Repository repo, ObjectId pushedOid, GitSortOptions sortingStrategy) { this.repo = repo; - this.forCountOnly = forCountOnly; - int res = NativeMethods.git_revwalk_new(out walker, repo.Handle); + int res = NativeMethods.git_revwalk_new(out handle, repo.Handle); Ensure.Success(res); + + Sort(sortingStrategy); + Push(pushedOid); } #region IEnumerator Members - public Commit Current { get; private set; } - - public void Dispose() + public Commit Current { - Dispose(true); - GC.SuppressFinalize(this); + get + { + if (currentOid == null) + { + throw new InvalidOperationException(); + } + + return repo.Lookup(currentOid); + } } object IEnumerator.Current @@ -160,63 +163,53 @@ object IEnumerator.Current public bool MoveNext() { GitOid oid; - var res = NativeMethods.git_revwalk_next(out oid, walker); - if (res == (int)GitErrorCode.GIT_EREVWALKOVER) return false; - - if (!forCountOnly) + var res = NativeMethods.git_revwalk_next(out oid, handle); + + if (res == (int)GitErrorCode.GIT_EREVWALKOVER) { - Current = repo.Lookup(new ObjectId(oid)); + return false; } + + Ensure.Success(res); + + currentOid = new ObjectId(oid); + return true; } public void Reset() { - NativeMethods.git_revwalk_reset(walker); + NativeMethods.git_revwalk_reset(handle); } #endregion + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + private void Dispose(bool disposing) { - // Check to see if Dispose has already been called. - if (!disposed) + if (handle == null || handle.IsInvalid) { - // If disposing equals true, dispose all managed - // and unmanaged resources. - if (disposing) - { - // Dispose managed resources. - } - - // Call the appropriate methods to clean up - // unmanaged resources here. - NativeMethods.git_revwalk_free(walker); - - // Note disposing has been done. - disposed = true; + return; } - } - ~CommitEnumerator() - { - // Do not re-create Dispose clean-up code here. - // Calling Dispose(false) is optimal in terms of - // readability and maintainability. - Dispose(false); + handle.Dispose(); } - public void Push(string sha) + private void Push(ObjectId pushedOid) { - var id = new ObjectId(sha); - var oid = id.Oid; - int res = NativeMethods.git_revwalk_push(walker, ref oid); + var oid = pushedOid.Oid; + int res = NativeMethods.git_revwalk_push(handle, ref oid); Ensure.Success(res); } - public void Sort(GitSortOptions options) + private void Sort(GitSortOptions options) { - NativeMethods.git_revwalk_sorting(walker, options); + NativeMethods.git_revwalk_sorting(handle, options); } } diff --git a/LibGit2Sharp/CommitCollectionExtensions.cs b/LibGit2Sharp/CommitCollectionExtensions.cs new file mode 100644 index 000000000..cde489a61 --- /dev/null +++ b/LibGit2Sharp/CommitCollectionExtensions.cs @@ -0,0 +1,41 @@ +using System; +using LibGit2Sharp.Core; + +namespace LibGit2Sharp +{ + public static class CommitCollectionExtensions + { + /// + /// Starts enumerating the at the specified branch. + /// + /// The commit collection to enumerate. + /// The branch. + /// + public static CommitCollection StartingAt(this CommitCollection commitCollection, Branch branch) + { + Ensure.ArgumentNotNull(branch, "branch"); + + Commit commit = branch.Tip; + + if (commit == null) + { + throw new ArgumentException(string.Format("No valid object identified as '{0}' has been found in the repository.", branch.CanonicalName), "branch"); + } + + return commitCollection.StartingAt(commit.Sha); + } + + /// + /// Starts enumerating the at the specified reference. + /// + /// The commit collection to enumerate. + /// The reference. + /// + public static CommitCollection StartingAt(this CommitCollection commitCollection, Reference reference) + { + Ensure.ArgumentNotNull(reference, "reference"); + + return commitCollection.StartingAt(reference.ResolveToDirectReference().CanonicalName); + } + } +} diff --git a/LibGit2Sharp/Core/Ensure.cs b/LibGit2Sharp/Core/Ensure.cs index 88eb96908..4cbc60991 100644 --- a/LibGit2Sharp/Core/Ensure.cs +++ b/LibGit2Sharp/Core/Ensure.cs @@ -42,14 +42,15 @@ public static void ArgumentNotNullOrEmptyString(string argumentValue, string arg /// The result. public static void Success(int result) { - if (result == 0) + if (result == (int) GitErrorCode.GIT_SUCCESS) { return; } + string errorMessage = NativeMethods.git_lasterror(); + throw new ApplicationException( - String.Format(CultureInfo.InvariantCulture, "There was an error in libgit2, but error handling sucks right now, so I can't tell you what it was. Error code = {0} ({1})", Enum.GetName(typeof(GitErrorCode), result) -, result)); + String.Format(CultureInfo.InvariantCulture, "An error was raised by libgit2. Error code = {0} ({1}).{2}{3}", Enum.GetName(typeof(GitErrorCode), result), result, Environment.NewLine, errorMessage)); } /// diff --git a/LibGit2Sharp/Core/GitErrorCode.cs b/LibGit2Sharp/Core/GitErrorCode.cs index fe268e157..ef015a32b 100644 --- a/LibGit2Sharp/Core/GitErrorCode.cs +++ b/LibGit2Sharp/Core/GitErrorCode.cs @@ -129,5 +129,25 @@ internal enum GitErrorCode /// A reference with this name already exists /// GIT_EEXISTS = (GIT_ERROR - 23), + + /// + /// The given integer literal is too large to be parsed + /// + GIT_EOVERFLOW = (GIT_ERROR - 24), + + /// + /// The given literal is not a valid number + /// + GIT_ENOTNUM = (GIT_ERROR - 25), + + /// + /// Streaming error + /// + GIT_ESTREAM = (GIT_ERROR - 26), + + /// + /// invalid arguments to function + /// + GIT_EINVALIDARGS = (GIT_ERROR - 27), } } \ No newline at end of file diff --git a/LibGit2Sharp/Core/IndexSafeHandle.cs b/LibGit2Sharp/Core/IndexSafeHandle.cs index 08a67e0e0..a8daa12a9 100644 --- a/LibGit2Sharp/Core/IndexSafeHandle.cs +++ b/LibGit2Sharp/Core/IndexSafeHandle.cs @@ -1,20 +1,7 @@ -using System; -using System.Runtime.InteropServices; - -namespace LibGit2Sharp.Core +namespace LibGit2Sharp.Core { - internal class IndexSafeHandle : SafeHandle + internal class IndexSafeHandle : SafeHandleBase { - public IndexSafeHandle() - : base(IntPtr.Zero, true) - { - } - - public override bool IsInvalid - { - get { return (handle == IntPtr.Zero); } - } - protected override bool ReleaseHandle() { NativeMethods.git_index_free(handle); diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 61d8cd7bc..5ac4ff051 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -5,28 +5,30 @@ namespace LibGit2Sharp.Core { internal class NativeMethods { - private const string libgit2 = "git2.dll"; - - [DllImport(libgit2, SetLastError = true)] + const string libgit2 = "git2.dll"; + + private NativeMethods() { } + + [DllImport(libgit2)] public static extern IntPtr git_blob_rawcontent(IntPtr blob); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_blob_rawsize(IntPtr blob); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_commit_author(IntPtr commit); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_commit_committer(IntPtr commit); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_commit_create_o(out GitOid oid, RepositorySafeHandle repo, string updateRef, IntPtr author, IntPtr committer, string message, IntPtr tree, int parentCount, IntPtr parents); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] [return: MarshalAs(UnmanagedType.AnsiBStr)] public static extern string git_commit_message(IntPtr commit); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] [return: MarshalAs(UnmanagedType.AnsiBStr)] public static extern string git_commit_message_short(IntPtr commit); @@ -36,70 +38,75 @@ internal class NativeMethods [DllImport(libgit2)] public static extern uint git_commit_parentcount(IntPtr commit); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_commit_tree(out IntPtr tree, IntPtr commit); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_commit_tree_oid(IntPtr commit); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_index_add(IndexSafeHandle index, string path, int stage = 0); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern uint git_index_entrycount(IndexSafeHandle index); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_index_find(IndexSafeHandle index, string path); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern void git_index_free(IntPtr index); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_index_get(IndexSafeHandle index, int n); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_index_open_inrepo(out IndexSafeHandle index, RepositorySafeHandle repo); + + [DllImport(libgit2)] + [return: MarshalAs(UnmanagedType.AnsiBStr)] + public static extern string git_lasterror(); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern void git_object_close(IntPtr obj); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_object_id(IntPtr obj); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_object_lookup(out IntPtr obj, RepositorySafeHandle repo, ref GitOid id, GitObjectType type); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern GitObjectType git_object_type(IntPtr obj); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] + [return: MarshalAs(UnmanagedType.Bool)] public static extern bool git_odb_exists(IntPtr db, ref GitOid id); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern void git_odb_object_close(IntPtr obj); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_oid_cmp(ref GitOid a, ref GitOid b); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern void git_oid_fmt(byte[] str, ref GitOid oid); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_oid_mkstr(out GitOid oid, string str); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_reference_create_oid(out IntPtr reference, RepositorySafeHandle repo, string name, ref GitOid oid); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_reference_create_oid_f(out IntPtr reference, RepositorySafeHandle repo, string name, ref GitOid oid); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_reference_create_symbolic(out IntPtr reference, RepositorySafeHandle repo, string name, string target); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_reference_create_symbolic_f(out IntPtr reference, RepositorySafeHandle repo, string name, string target); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_reference_delete(IntPtr reference); [DllImport(libgit2)] @@ -121,10 +128,10 @@ internal class NativeMethods [DllImport(libgit2)] public static extern int git_reference_resolve(out IntPtr resolvedReference, IntPtr reference); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_reference_set_oid(IntPtr reference, ref GitOid id); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_reference_set_target(IntPtr reference, string target); [DllImport(libgit2)] @@ -134,19 +141,20 @@ internal class NativeMethods [DllImport(libgit2)] public static extern GitReferenceType git_reference_type(IntPtr reference); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_repository_database(RepositorySafeHandle repository); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern void git_repository_free(IntPtr repository); - [DllImport(libgit2, SetLastError = true)] - public static extern int git_repository_init(out RepositorySafeHandle repository, string path, bool isBare); + [DllImport(libgit2)] + public static extern int git_repository_init(out RepositorySafeHandle repository, string path, [MarshalAs(UnmanagedType.Bool)] bool isBare); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] + [return: MarshalAs(UnmanagedType.Bool)] public static extern bool git_repository_is_empty(RepositorySafeHandle repo); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_repository_open(out RepositorySafeHandle repository, string path); [DllImport(libgit2)] @@ -161,69 +169,69 @@ internal class NativeMethods public static extern void git_revwalk_free(IntPtr walker); [DllImport(libgit2)] - public static extern int git_revwalk_new(out IntPtr walker, RepositorySafeHandle repo); + public static extern int git_revwalk_new(out RevWalkerSafeHandle walker, RepositorySafeHandle repo); [DllImport(libgit2)] - public static extern int git_revwalk_next(out GitOid oid, IntPtr walker); + public static extern int git_revwalk_next(out GitOid oid, RevWalkerSafeHandle walker); [DllImport(libgit2)] - public static extern int git_revwalk_push(IntPtr walker, ref GitOid oid); + public static extern int git_revwalk_push(RevWalkerSafeHandle walker, ref GitOid oid); [DllImport(libgit2)] - public static extern void git_revwalk_reset(IntPtr walker); + public static extern void git_revwalk_reset(RevWalkerSafeHandle walker); [DllImport(libgit2)] - public static extern void git_revwalk_sorting(IntPtr walk, GitSortOptions sort); + public static extern void git_revwalk_sorting(RevWalkerSafeHandle walk, GitSortOptions sort); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern void git_signature_free(IntPtr signature); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_signature_new(string name, string email, long time, int offset); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_tag_create(out GitOid oid, RepositorySafeHandle repo, string name, ref GitOid target, GitObjectType type, GitSignature signature, string message); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_tag_create_f(out GitOid oid, RepositorySafeHandle repo, string name, ref GitOid target, GitObjectType type, GitSignature signature, string message); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_tag_delete(RepositorySafeHandle repo, string tagName); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] [return: MarshalAs(UnmanagedType.AnsiBStr)] public static extern string git_tag_message(IntPtr tag); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] [return: MarshalAs(UnmanagedType.AnsiBStr)] public static extern string git_tag_name(IntPtr tag); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_tag_tagger(IntPtr tag); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_tag_target_oid(IntPtr tag); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_tree_entry_2object(out IntPtr obj, RepositorySafeHandle repo, IntPtr entry); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_tree_entry_attributes(IntPtr entry); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_tree_entry_byindex(IntPtr tree, int idx); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_tree_entry_byname(IntPtr tree, string filename); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern IntPtr git_tree_entry_id(IntPtr tree); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] [return: MarshalAs(UnmanagedType.AnsiBStr)] public static extern string git_tree_entry_name(IntPtr entry); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] public static extern int git_tree_entrycount(IntPtr tree); } } \ No newline at end of file diff --git a/LibGit2Sharp/Core/RepositorySafeHandle.cs b/LibGit2Sharp/Core/RepositorySafeHandle.cs index a251181b8..be4709b98 100644 --- a/LibGit2Sharp/Core/RepositorySafeHandle.cs +++ b/LibGit2Sharp/Core/RepositorySafeHandle.cs @@ -1,19 +1,7 @@ -using System; -using System.Runtime.InteropServices; - -namespace LibGit2Sharp.Core +namespace LibGit2Sharp.Core { - internal class RepositorySafeHandle : SafeHandle + internal class RepositorySafeHandle : SafeHandleBase { - public RepositorySafeHandle() : base(IntPtr.Zero, true) - { - } - - public override bool IsInvalid - { - get { return (handle == IntPtr.Zero); } - } - protected override bool ReleaseHandle() { NativeMethods.git_repository_free(handle); diff --git a/LibGit2Sharp/Core/RevWalkerSafeHandle.cs b/LibGit2Sharp/Core/RevWalkerSafeHandle.cs new file mode 100644 index 000000000..d4adc77ce --- /dev/null +++ b/LibGit2Sharp/Core/RevWalkerSafeHandle.cs @@ -0,0 +1,11 @@ +namespace LibGit2Sharp.Core +{ + internal class RevWalkerSafeHandle : SafeHandleBase + { + protected override bool ReleaseHandle() + { + NativeMethods.git_revwalk_free(handle); + return true; + } + } +} \ No newline at end of file diff --git a/LibGit2Sharp/Core/SafeHandleBase.cs b/LibGit2Sharp/Core/SafeHandleBase.cs new file mode 100644 index 000000000..7ba4bc4fb --- /dev/null +++ b/LibGit2Sharp/Core/SafeHandleBase.cs @@ -0,0 +1,20 @@ +using System; +using System.Runtime.InteropServices; + +namespace LibGit2Sharp.Core +{ + internal abstract class SafeHandleBase : SafeHandle + { + protected SafeHandleBase() + : base(IntPtr.Zero, true) + { + } + + public override bool IsInvalid + { + get { return (handle == IntPtr.Zero); } + } + + protected abstract override bool ReleaseHandle(); + } +} \ No newline at end of file diff --git a/LibGit2Sharp/Core/UnSafeNativeMethods.cs b/LibGit2Sharp/Core/UnSafeNativeMethods.cs index 90fa10cc0..22c9ccf5a 100644 --- a/LibGit2Sharp/Core/UnSafeNativeMethods.cs +++ b/LibGit2Sharp/Core/UnSafeNativeMethods.cs @@ -7,6 +7,8 @@ internal unsafe class UnSafeNativeMethods { private const string libgit2 = "git2.dll"; + private UnSafeNativeMethods() { } + [DllImport(libgit2)] public static extern int git_reference_listall(git_strarray* array, RepositorySafeHandle repo, GitReferenceType flags); diff --git a/LibGit2Sharp/CustomDictionary.xml b/LibGit2Sharp/CustomDictionary.xml new file mode 100644 index 000000000..2def1ba88 --- /dev/null +++ b/LibGit2Sharp/CustomDictionary.xml @@ -0,0 +1,27 @@ + + + + + + + git + sha + unstage + unstaged + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LibGit2Sharp/GitSortOptions.cs b/LibGit2Sharp/GitSortOptions.cs index e6e0d2ce4..0330db99c 100644 --- a/LibGit2Sharp/GitSortOptions.cs +++ b/LibGit2Sharp/GitSortOptions.cs @@ -5,9 +5,32 @@ namespace LibGit2Sharp [Flags] public enum GitSortOptions { + /// + /// Sort the repository contents in no particular ordering; + /// this sorting is arbitrary, implementation-specific + /// and subject to change at any time. + /// None = 0, - Topo = (1 << 0), + + /// + /// Sort the repository contents in topological order + /// (parents before children); this sorting mode + /// can be combined with time sorting. + /// + Topological = (1 << 0), + + /// + /// Sort the repository contents by commit time; + /// this sorting mode can be combined with + /// topological sorting. + /// Time = (1 << 1), + + /// + /// Iterate through the repository contents in reverse + /// order; this sorting mode can be combined with + /// any of the above. + /// Reverse = (1 << 2) } } \ No newline at end of file diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index a0d6a56eb..cf1c811b0 100644 --- a/LibGit2Sharp/Index.cs +++ b/LibGit2Sharp/Index.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Globalization; using System.IO; using LibGit2Sharp.Core; @@ -11,7 +12,7 @@ public class Index : IEnumerable, IDisposable private readonly IndexSafeHandle handle; private readonly Repository repo; - public Index(Repository repo) + internal Index(Repository repo) { this.repo = repo; var res = NativeMethods.git_index_open_inrepo(out handle, repo.Handle); @@ -123,11 +124,11 @@ private string BuildRelativePathFrom(string path) //TODO: To be removed when l return path; } - var normalizedPath = new DirectoryInfo(path).FullName; + var normalizedPath = Path.GetFullPath(path); - if (!normalizedPath.StartsWith(repo.Info.WorkingDirectory)) + if (!normalizedPath.StartsWith(repo.Info.WorkingDirectory, StringComparison.Ordinal)) { - throw new ArgumentException(string.Format("Unable to stage file '{0}'. This file is not located under the working directory of the repository ('{1}').", normalizedPath, repo.Info.WorkingDirectory)); + throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Unable to stage file '{0}'. This file is not located under the working directory of the repository ('{1}').", normalizedPath, repo.Info.WorkingDirectory)); } return normalizedPath.Substring(repo.Info.WorkingDirectory.Length); diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 7ff8e63c8..4579d277f 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -47,6 +47,7 @@ + @@ -62,6 +63,10 @@ Code + + Code + + @@ -98,6 +103,7 @@ git2.dll PreserveNewest + diff --git a/LibGit2Sharp/Reference.cs b/LibGit2Sharp/Reference.cs index d37cb9444..442f5367d 100644 --- a/LibGit2Sharp/Reference.cs +++ b/LibGit2Sharp/Reference.cs @@ -18,6 +18,7 @@ public abstract class Reference : IEquatable /// public string CanonicalName { get; protected set; } + //TODO: Cries for refactoring... really! internal static T BuildFromPtr(IntPtr ptr, Repository repo) where T : class { if (ptr == IntPtr.Zero) @@ -29,24 +30,35 @@ internal static T BuildFromPtr(IntPtr ptr, Repository repo) where T : class var type = NativeMethods.git_reference_type(ptr); Reference reference; + string targetIdentifier; switch (type) { case GitReferenceType.Symbolic: IntPtr resolveRef; - var targetName = NativeMethods.git_reference_target(ptr); - NativeMethods.git_reference_resolve(out resolveRef, ptr); + targetIdentifier = NativeMethods.git_reference_target(ptr); + int res = NativeMethods.git_reference_resolve(out resolveRef, ptr); + + if (res == (int) GitErrorCode.GIT_ENOTFOUND) + { + reference = new SymbolicReference { CanonicalName = name, Target = null, TargetIdentifier = targetIdentifier }; + break; + } + + Ensure.Success(res); + var targetRef = BuildFromPtr(resolveRef, repo); - reference = new SymbolicReference { CanonicalName = name, Target = targetRef, TargetIdentifier = targetName}; + reference = new SymbolicReference { CanonicalName = name, Target = targetRef, TargetIdentifier = targetIdentifier}; break; case GitReferenceType.Oid: var oidPtr = NativeMethods.git_reference_oid(ptr); var oid = (GitOid)Marshal.PtrToStructure(oidPtr, typeof(GitOid)); var targetId = new ObjectId(oid); + targetIdentifier = targetId.Sha; var target = repo.Lookup(targetId); - reference = new DirectReference { CanonicalName = name, Target = target, TargetIdentifier = targetId.Sha}; + reference = new DirectReference { CanonicalName = name, Target = target, TargetIdentifier = targetIdentifier}; break; default: @@ -58,7 +70,7 @@ internal static T BuildFromPtr(IntPtr ptr, Repository repo) where T : class return reference as T; } - GitObject targetGitObject = repo.Lookup(reference.ResolveToDirectReference().Target.Id); + GitObject targetGitObject = repo.Lookup(targetIdentifier); if (Equals(typeof(T), typeof(Tag))) { diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index c5bcf3c96..f1671e6f2 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -17,11 +17,7 @@ public class Repository : IDisposable /// /// Initializes a new instance of the class. - /// - /// Exceptions: - /// ArgumentException - /// ArgumentNullException - /// TODO: ApplicationException is thrown for all git errors right now + /// 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) @@ -155,10 +151,10 @@ public bool HasObject(string sha) } /// - /// Init a repo at the specified path + /// Init a repo at the specified . /// - /// The path. - /// + /// 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) { @@ -218,7 +214,7 @@ public GitObject Lookup(string shaOrReferenceName, GitObjectType type = GitObjec return null; } - return Lookup(reference.ResolveToDirectReference().Target.Id, type); + return Lookup(reference.ResolveToDirectReference().TargetIdentifier, type); } private static bool IsReferencePeelable(Reference reference) diff --git a/LibGit2Sharp/RepositoryInformation.cs b/LibGit2Sharp/RepositoryInformation.cs index de070a971..975880705 100644 --- a/LibGit2Sharp/RepositoryInformation.cs +++ b/LibGit2Sharp/RepositoryInformation.cs @@ -15,7 +15,6 @@ internal RepositoryInformation(Repository repo, string posixPath, string posixWo Path = PosixPathHelper.ToNative(posixPath); IsBare = isBare; WorkingDirectory = PosixPathHelper.ToNative(posixWorkingDirectoryPath); - IsEmpty = NativeMethods.git_repository_is_empty(repo.Handle); } /// @@ -42,7 +41,10 @@ internal RepositoryInformation(Repository repo, string posixPath, string posixWo /// /// true if this repository is empty; otherwise, false. /// - public bool IsEmpty { get; private set; } + public bool IsEmpty + { + get { return NativeMethods.git_repository_is_empty(repo.Handle); } + } /// /// Indicates whether the Head points to an arbitrary commit instead of the tip of a local banch. diff --git a/LibGit2Sharp/TagCollection.cs b/LibGit2Sharp/TagCollection.cs index f8693b539..0baeec647 100644 --- a/LibGit2Sharp/TagCollection.cs +++ b/LibGit2Sharp/TagCollection.cs @@ -13,7 +13,7 @@ namespace LibGit2Sharp public class TagCollection : IEnumerable { private readonly Repository repo; - private static readonly string RefsTagsPrefix = "refs/tags/"; + private const string refsTagsPrefix = "refs/tags/"; /// /// Initializes a new instance of the class. @@ -142,24 +142,24 @@ private static string NormalizeToCanonicalName(string name) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); - if (name.StartsWith(RefsTagsPrefix, StringComparison.Ordinal)) + if (name.StartsWith(refsTagsPrefix, StringComparison.Ordinal)) { return name; } - return string.Concat(RefsTagsPrefix, name); + return string.Concat(refsTagsPrefix, name); } private static string UnCanonicalizeName(string name) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); - if (!name.StartsWith(RefsTagsPrefix, StringComparison.Ordinal)) + if (!name.StartsWith(refsTagsPrefix, StringComparison.Ordinal)) { return name; } - return name.Substring(RefsTagsPrefix.Length); + return name.Substring(refsTagsPrefix.Length); } } } \ No newline at end of file diff --git a/Resources/testrepo.git/refs/heads/deadbeef b/Resources/testrepo.git/refs/heads/deadbeef new file mode 100644 index 000000000..aa3a3b099 --- /dev/null +++ b/Resources/testrepo.git/refs/heads/deadbeef @@ -0,0 +1 @@ +deadbeefdeadbeefdeadbeefdeadbeefdeadbeef diff --git a/backlog.md b/backlog.md index a0e159518..2f6074ce8 100644 --- a/backlog.md +++ b/backlog.md @@ -2,22 +2,28 @@ ### LibGit2Sharp - - Add a Path property to SelfCleaningDirectory - - Set up a Assembly versioning strategy + - Build a LibGit2Sharp.Sample NuGet package + - Publish source and PDBs at symbolsource.org (cf. http://blog.davidebbo.com/2011/04/easy-way-to-publish-nuget-packages-with.html and http://nuget.codeplex.com/discussions/257709) + - Bind git_revwalk_hide() as CommitCollection.Until() + - Fix FluentInterface .StartingAt() and .Until() in order to prevent .StartIngAt().StartingAt(), .Until().Until() and .Until().StartingAt() + - Add to Epoch a DateTimeOffset extension method ToRelativeFormat() in order to show dates relative to the current time, e.g. "2 hours ago". (cf. https://github.com/git/git/blob/master/date.c#L89) - Add branch renaming (public Branch Move(string oldName, string newName, bool allowOverwrite = false)) - Turn duplicated strings "refs/xxx" into properties of a generic Constants helper type - Refactor the error handling (OutputResult -> Exceptions) - Launch Code Analysis (Issues related to interop and marshaling will be worked on once we're able to succesffully exchange non ascii encoded data with libgit2) - - When properly exported use git_strerror() to feed raised exceptions with a meaningful message. - Remove usage of ApplicationException - https://bugzilla.novell.com/show_bug.cgi?id=566247 prevents MonoDevelop users from benefiting from optional parameters while still target at 3.5 - https://bugzilla.novell.com/show_bug.cgi?id=324680 generates false-positive warnings regarding xml documentation when LibGit2Sharp is built with xbuild - The freeing of a newly created signature pointer doesn't "feel" to be done at the right place. - - Should we throw when trying to delete a reference which can not be found? - Favor overloads over optional parameters (http://msdn.microsoft.com/en-us/library/ms182135.aspx) - Ensure that types that are not supposed to be built by the Consumer do not expose a constructor. - Escape as early as possible from a method. Fight against the arrowhead effect (cf. http://elegantcode.com/2009/08/14/observations-on-the-if-statement/) +### Wiki + + - How to integrate LibGit2Sharp in an application? + - How do I do 'git xxx' with LibGit2Sharp? (cf. https://github.com/libgit2/libgit2sharp/wiki/What's-the-equivalent-to-'git-xxx'%3F) + ### Tests - Add tests ensuring the behavior of indexers when being passed unknown sha and refs diff --git a/libgit2 b/libgit2 index 2571cc3cf..f02f4b536 160000 --- a/libgit2 +++ b/libgit2 @@ -1 +1 @@ -Subproject commit 2571cc3cff67fe958727496bb1d660e5810bd8e1 +Subproject commit f02f4b536cfb5170a8ddc6d0e3b47631defd55ef