From 23bb3576abaf03847ffff1fad97e5d4c1de5663c Mon Sep 17 00:00:00 2001 From: nulltoken Date: Sat, 14 May 2011 19:09:59 +0200 Subject: [PATCH 01/21] Update libgit2 binaries to f02f4b5 Fix implementation to cope with improved reference resolving. --- Lib/git2.dll | Bin 137728 -> 149504 bytes LibGit2Sharp/Reference.cs | 12 +++++++++++- libgit2 | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Lib/git2.dll b/Lib/git2.dll index 969786a29610cf2d9c1c55d220f48665bcf30b34..3b2f252ea0937f4964be959df5a939f34905448e 100644 GIT binary patch delta 46266 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 delta 38035 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 z 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 diff --git a/LibGit2Sharp/Reference.cs b/LibGit2Sharp/Reference.cs index d37cb9444..ec71e7e7a 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. internal static T BuildFromPtr(IntPtr ptr, Repository repo) where T : class { if (ptr == IntPtr.Zero) @@ -35,7 +36,16 @@ internal static T BuildFromPtr(IntPtr ptr, Repository repo) where T : class case GitReferenceType.Symbolic: IntPtr resolveRef; var targetName = NativeMethods.git_reference_target(ptr); - NativeMethods.git_reference_resolve(out resolveRef, ptr); + int res = NativeMethods.git_reference_resolve(out resolveRef, ptr); + + if (res == (int) GitErrorCode.GIT_ENOTFOUND) + { + reference = new SymbolicReference { CanonicalName = name, Target = null, TargetIdentifier = targetName }; + break; + } + + Ensure.Success(res); + var targetRef = BuildFromPtr(resolveRef, repo); reference = new SymbolicReference { CanonicalName = name, Target = targetRef, TargetIdentifier = targetName}; break; diff --git a/libgit2 b/libgit2 index 2571cc3cf..f02f4b536 160000 --- a/libgit2 +++ b/libgit2 @@ -1 +1 @@ -Subproject commit 2571cc3cff67fe958727496bb1d660e5810bd8e1 +Subproject commit f02f4b536cfb5170a8ddc6d0e3b47631defd55ef From a6abf7d883d4f4c4c79dc0aee61ed5778f57c2ed Mon Sep 17 00:00:00 2001 From: nulltoken Date: Sat, 14 May 2011 23:17:39 +0200 Subject: [PATCH 02/21] Improve error handling mechanism Removed SetLastError decorator from bound methods as libigit2 doesn't rely on this mechanism (and probably won't, as there's no POSIX equivalent) --- LibGit2Sharp/Core/Ensure.cs | 7 +- LibGit2Sharp/Core/GitErrorCode.cs | 20 ++++++ LibGit2Sharp/Core/NativeMethods.cs | 108 +++++++++++++++-------------- 3 files changed, 80 insertions(+), 55 deletions(-) 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/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 61d8cd7bc..2d84aae47 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -7,26 +7,26 @@ internal class NativeMethods { private const string libgit2 = "git2.dll"; - [DllImport(libgit2, SetLastError = true)] + [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 +36,74 @@ 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)] 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 +125,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 +138,19 @@ 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)] + [DllImport(libgit2)] public static extern int git_repository_init(out RepositorySafeHandle repository, string path, bool isBare); - [DllImport(libgit2, SetLastError = true)] + [DllImport(libgit2)] 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)] @@ -175,55 +179,55 @@ internal class NativeMethods [DllImport(libgit2)] public static extern void git_revwalk_sorting(IntPtr 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 From a375658e36a8b519facb53383de4628d49894f5d Mon Sep 17 00:00:00 2001 From: nulltoken Date: Sun, 15 May 2011 14:35:29 +0200 Subject: [PATCH 03/21] Reduce public API exposure --- LibGit2Sharp/Index.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index a0d6a56eb..6e5c85ffb 100644 --- a/LibGit2Sharp/Index.cs +++ b/LibGit2Sharp/Index.cs @@ -11,7 +11,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); From 3db11df298f7cc1767fe177364eab6806e3233b8 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Sun, 15 May 2011 14:37:33 +0200 Subject: [PATCH 04/21] Refactor SelfCleaningDirectory and TemporaryCloneOfTestRepo test helpers --- LibGit2Sharp.Tests/IndexFixture.cs | 8 +++----- LibGit2Sharp.Tests/RepositoryFixture.cs | 14 ++++++------- LibGit2Sharp.Tests/TagFixture.cs | 14 ++++++------- .../TestHelpers/SelfCleaningDirectory.cs | 20 +++++++++++-------- .../TestHelpers/TemporaryCloneOfTestRepo.cs | 13 +++--------- 5 files changed, 30 insertions(+), 39 deletions(-) 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/RepositoryFixture.cs b/LibGit2Sharp.Tests/RepositoryFixture.cs index d88334736..497e370ca 100644 --- a/LibGit2Sharp.Tests/RepositoryFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryFixture.cs @@ -8,17 +8,15 @@ 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(); @@ -35,9 +33,9 @@ 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(); @@ -238,9 +236,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..d84258570 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); @@ -159,9 +157,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 +172,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)) { @@ -520,9 +518,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..26f7cf99a 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,28 @@ public SelfCleaningDirectory(string path) throw new InvalidOperationException("Directory '{0}' already exists."); } - this.path = path; + DirectoryPath = path; } - protected string DirectoryPath - { - get { return path; } - } + public string DirectoryPath { 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 From ec2924874bd03868db870075eb91d1a3f2141b1b Mon Sep 17 00:00:00 2001 From: nulltoken Date: Sun, 15 May 2011 14:37:53 +0200 Subject: [PATCH 05/21] Update backlog --- backlog.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/backlog.md b/backlog.md index a0e159518..bf2a58466 100644 --- a/backlog.md +++ b/backlog.md @@ -2,18 +2,14 @@ ### LibGit2Sharp - - Add a Path property to SelfCleaningDirectory - - Set up a Assembly versioning strategy - 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/) From 9202e915f5cc6a974de25fffc6bd3629567bbe99 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Sun, 15 May 2011 21:39:10 +0200 Subject: [PATCH 06/21] Fix some issues pinpointed by Code Analysis --- LibGit2Sharp.Tests/CommitFixture.cs | 4 ++-- LibGit2Sharp/Core/NativeMethods.cs | 10 ++++++--- LibGit2Sharp/Core/UnSafeNativeMethods.cs | 2 ++ LibGit2Sharp/CustomDictionary.xml | 27 ++++++++++++++++++++++++ LibGit2Sharp/GitSortOptions.cs | 2 +- LibGit2Sharp/Index.cs | 5 +++-- LibGit2Sharp/LibGit2Sharp.csproj | 1 + LibGit2Sharp/TagCollection.cs | 10 ++++----- 8 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 LibGit2Sharp/CustomDictionary.xml diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index c1cb68f9b..c37f2c30f 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -74,7 +74,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 +108,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/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 2d84aae47..9c5f129e1 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -5,8 +5,10 @@ namespace LibGit2Sharp.Core { internal class NativeMethods { - private const string libgit2 = "git2.dll"; - + const string libgit2 = "git2.dll"; + + private NativeMethods() { } + [DllImport(libgit2)] public static extern IntPtr git_blob_rawcontent(IntPtr blob); @@ -77,6 +79,7 @@ internal class NativeMethods public static extern GitObjectType git_object_type(IntPtr obj); [DllImport(libgit2)] + [return: MarshalAs(UnmanagedType.Bool)] public static extern bool git_odb_exists(IntPtr db, ref GitOid id); [DllImport(libgit2)] @@ -145,9 +148,10 @@ internal class NativeMethods public static extern void git_repository_free(IntPtr repository); [DllImport(libgit2)] - public static extern int git_repository_init(out RepositorySafeHandle repository, string path, bool isBare); + public static extern int git_repository_init(out RepositorySafeHandle repository, string path, [MarshalAs(UnmanagedType.Bool)] bool isBare); [DllImport(libgit2)] + [return: MarshalAs(UnmanagedType.Bool)] public static extern bool git_repository_is_empty(RepositorySafeHandle repo); [DllImport(libgit2)] 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..3bf38841b 100644 --- a/LibGit2Sharp/GitSortOptions.cs +++ b/LibGit2Sharp/GitSortOptions.cs @@ -6,7 +6,7 @@ namespace LibGit2Sharp public enum GitSortOptions { None = 0, - Topo = (1 << 0), + Topological = (1 << 0), Time = (1 << 1), Reverse = (1 << 2) } diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index 6e5c85ffb..bf84882e1 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; @@ -125,9 +126,9 @@ private string BuildRelativePathFrom(string path) //TODO: To be removed when l var normalizedPath = new DirectoryInfo(path).FullName; - 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..099248edc 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -98,6 +98,7 @@ git2.dll PreserveNewest + 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 From 02f414c97bde3d9563fcb381816f58b6793a3ed0 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Mon, 16 May 2011 21:35:37 +0200 Subject: [PATCH 07/21] Improve documentation and tests related to initialization and opening of a git repositories Credit goes to @yysun for having spotted these misleading areas --- LibGit2Sharp.Tests/RepositoryFixture.cs | 2 ++ .../TestHelpers/SelfCleaningDirectory.cs | 3 +++ LibGit2Sharp/Index.cs | 2 +- LibGit2Sharp/Repository.cs | 12 ++++-------- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/LibGit2Sharp.Tests/RepositoryFixture.cs b/LibGit2Sharp.Tests/RepositoryFixture.cs index 497e370ca..f69f99465 100644 --- a/LibGit2Sharp.Tests/RepositoryFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryFixture.cs @@ -23,6 +23,7 @@ public void CanCreateBareRepo() using (var repo = new Repository(dir)) { repo.Info.WorkingDirectory.ShouldBeNull(); + repo.Info.Path.ShouldEqual(scd.RootedDirectoryPath + @"\"); repo.Info.IsBare.ShouldBeTrue(); AssertInitializedRepository(repo); @@ -42,6 +43,7 @@ public void CanCreateStandardRepo() 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); diff --git a/LibGit2Sharp.Tests/TestHelpers/SelfCleaningDirectory.cs b/LibGit2Sharp.Tests/TestHelpers/SelfCleaningDirectory.cs index 26f7cf99a..c6576923c 100644 --- a/LibGit2Sharp.Tests/TestHelpers/SelfCleaningDirectory.cs +++ b/LibGit2Sharp.Tests/TestHelpers/SelfCleaningDirectory.cs @@ -17,9 +17,12 @@ public SelfCleaningDirectory(string path) } DirectoryPath = path; + RootedDirectoryPath = Path.GetFullPath(path); } + public string DirectoryPath { get; private set; } + public string RootedDirectoryPath { get; private set; } #region IDisposable Members diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index bf84882e1..cf1c811b0 100644 --- a/LibGit2Sharp/Index.cs +++ b/LibGit2Sharp/Index.cs @@ -124,7 +124,7 @@ 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, StringComparison.Ordinal)) { diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index c5bcf3c96..d4f68fd21 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) { From b81a2d135faffd0f7a34664ddd630fa838d3cbb8 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Tue, 17 May 2011 16:54:15 +0200 Subject: [PATCH 08/21] Add UnknownSha to test helper Constants --- LibGit2Sharp.Tests/Constants.cs | 1 + LibGit2Sharp.Tests/RepositoryFixture.cs | 7 +++---- LibGit2Sharp.Tests/TagFixture.cs | 5 ++--- 3 files changed, 6 insertions(+), 7 deletions(-) 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/RepositoryFixture.cs b/LibGit2Sharp.Tests/RepositoryFixture.cs index f69f99465..9a3c91dd3 100644 --- a/LibGit2Sharp.Tests/RepositoryFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryFixture.cs @@ -9,7 +9,6 @@ namespace LibGit2Sharp.Tests public class RepositoryFixture { private const string commitSha = "8496071c1b46c854b31185ea97743be6a8774479"; - private const string notFoundSha = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; [Test] public void CanCreateBareRepo() @@ -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(); } } diff --git a/LibGit2Sharp.Tests/TagFixture.cs b/LibGit2Sharp.Tests/TagFixture.cs index d84258570..4299556d5 100644 --- a/LibGit2Sharp.Tests/TagFixture.cs +++ b/LibGit2Sharp.Tests/TagFixture.cs @@ -17,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() @@ -201,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)); } } @@ -397,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")); } } From 6cdd3014a17a292a26ba19f2b3536e4a1492387e Mon Sep 17 00:00:00 2001 From: nulltoken Date: Tue, 17 May 2011 17:03:54 +0200 Subject: [PATCH 09/21] Fix default CommitCollection sorting behavior According to git log man page, by default, the commits are ordered in reverse chronological order. --- LibGit2Sharp/CommitCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibGit2Sharp/CommitCollection.cs b/LibGit2Sharp/CommitCollection.cs index 15c0fa0f7..24e07022e 100644 --- a/LibGit2Sharp/CommitCollection.cs +++ b/LibGit2Sharp/CommitCollection.cs @@ -12,7 +12,7 @@ public class CommitCollection : IEnumerable { private readonly Repository repo; private string pushedSha; - private GitSortOptions sortOptions = GitSortOptions.None; + private GitSortOptions sortOptions = GitSortOptions.Time; /// /// Initializes a new instance of the class. From 3e2535d2a34d4256426c33480a98172cc6380963 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Tue, 17 May 2011 17:18:54 +0200 Subject: [PATCH 10/21] Update backlog --- backlog.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/backlog.md b/backlog.md index bf2a58466..8a82dfc8d 100644 --- a/backlog.md +++ b/backlog.md @@ -2,6 +2,14 @@ ### LibGit2Sharp + - 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() + - Throw when revwalker is being passed an unknown object + - Change CommitCollection.StartingAt(string sha) into CommitCollection.StartingAt(string referenceNameOrsha) + - Fix FluentInterface .StartingAt() and .Until() in order to prevent .StartIngAt().StartingAt(), .Until().Until() and .Until().StartingAt() + - Push StartingAt() overloads into extension methods + - 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) @@ -14,6 +22,11 @@ - 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 From 2a529521cad768dedb88f358d5ad59d6ac03eeaa Mon Sep 17 00:00:00 2001 From: nulltoken Date: Wed, 18 May 2011 22:12:41 +0200 Subject: [PATCH 11/21] Add a corrupted branch to the test repository The branch "deadbeef" points to a object which doesn't exist in the repository. --- Resources/testrepo.git/refs/heads/deadbeef | 1 + 1 file changed, 1 insertion(+) create mode 100644 Resources/testrepo.git/refs/heads/deadbeef 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 From 1047733668f011a3dc89f6e675e9d2ced40bf083 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Wed, 18 May 2011 22:19:22 +0200 Subject: [PATCH 12/21] Fix creation of reference to prevent it from choking on corrupted ones --- LibGit2Sharp.Tests/BranchFixture.cs | 4 ++-- LibGit2Sharp.Tests/ReferenceFixture.cs | 5 +++-- LibGit2Sharp/Reference.cs | 14 ++++++++------ 3 files changed, 13 insertions(+), 10 deletions(-) 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/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/Reference.cs b/LibGit2Sharp/Reference.cs index ec71e7e7a..442f5367d 100644 --- a/LibGit2Sharp/Reference.cs +++ b/LibGit2Sharp/Reference.cs @@ -18,7 +18,7 @@ public abstract class Reference : IEquatable /// public string CanonicalName { get; protected set; } - //TODO: Cries for refactoring. + //TODO: Cries for refactoring... really! internal static T BuildFromPtr(IntPtr ptr, Repository repo) where T : class { if (ptr == IntPtr.Zero) @@ -30,33 +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); + 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 = targetName }; + 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: @@ -68,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))) { From 5ea4866a1ffdf491bba09925366cc95a95bd2266 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 19 May 2011 11:25:06 +0200 Subject: [PATCH 13/21] Add some documentation --- LibGit2Sharp/GitSortOptions.cs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/LibGit2Sharp/GitSortOptions.cs b/LibGit2Sharp/GitSortOptions.cs index 3bf38841b..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, + + /// + /// 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 From 6b8b8a25d9b096d1a3e4fa3e58261a37d9a8bbbb Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 19 May 2011 11:53:48 +0200 Subject: [PATCH 14/21] Refactor SafeHandles --- LibGit2Sharp/Core/IndexSafeHandle.cs | 17 ++--------------- LibGit2Sharp/Core/RepositorySafeHandle.cs | 16 ++-------------- LibGit2Sharp/Core/SafeHandleBase.cs | 20 ++++++++++++++++++++ LibGit2Sharp/LibGit2Sharp.csproj | 1 + 4 files changed, 25 insertions(+), 29 deletions(-) create mode 100644 LibGit2Sharp/Core/SafeHandleBase.cs 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/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/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/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 099248edc..d81fb4d76 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -62,6 +62,7 @@ Code + From 4e90db86beeeee4b4c8b1653e8a90685e9144b20 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 19 May 2011 11:57:22 +0200 Subject: [PATCH 15/21] Add RevWalkerSafeHandle to ensure proper release of non managed resources --- LibGit2Sharp/CommitCollection.cs | 42 +++++++----------------- LibGit2Sharp/Core/NativeMethods.cs | 10 +++--- LibGit2Sharp/Core/RevWalkerSafeHandle.cs | 11 +++++++ LibGit2Sharp/LibGit2Sharp.csproj | 3 ++ 4 files changed, 30 insertions(+), 36 deletions(-) create mode 100644 LibGit2Sharp/Core/RevWalkerSafeHandle.cs diff --git a/LibGit2Sharp/CommitCollection.cs b/LibGit2Sharp/CommitCollection.cs index 24e07022e..480b78152 100644 --- a/LibGit2Sharp/CommitCollection.cs +++ b/LibGit2Sharp/CommitCollection.cs @@ -60,8 +60,8 @@ public IEnumerator GetEnumerator() if (string.IsNullOrEmpty(pushedSha)) { throw new NotImplementedException(); - } - + } + var enumerator = new CommitEnumerator(repo); enumerator.Sort(sortOptions); enumerator.Push(pushedSha); @@ -131,14 +131,13 @@ 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; public CommitEnumerator(Repository repo, bool forCountOnly = false) { 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); } @@ -160,7 +159,7 @@ object IEnumerator.Current public bool MoveNext() { GitOid oid; - var res = NativeMethods.git_revwalk_next(out oid, walker); + var res = NativeMethods.git_revwalk_next(out oid, handle); if (res == (int)GitErrorCode.GIT_EREVWALKOVER) return false; if (!forCountOnly) @@ -172,51 +171,32 @@ public bool MoveNext() public void Reset() { - NativeMethods.git_revwalk_reset(walker); + NativeMethods.git_revwalk_reset(handle); } #endregion 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) { var id = new ObjectId(sha); var oid = id.Oid; - int res = NativeMethods.git_revwalk_push(walker, ref oid); + int res = NativeMethods.git_revwalk_push(handle, ref oid); Ensure.Success(res); } public void Sort(GitSortOptions options) { - NativeMethods.git_revwalk_sorting(walker, options); + NativeMethods.git_revwalk_sorting(handle, options); } } diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 9c5f129e1..5ac4ff051 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -169,19 +169,19 @@ private 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)] public static extern void git_signature_free(IntPtr signature); 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/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index d81fb4d76..86a5f7efe 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -62,6 +62,9 @@ Code + + Code + From 548b8d9c45063ac197047a68abedd8c88039f970 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 19 May 2011 14:39:11 +0200 Subject: [PATCH 16/21] Unify the behavior of CommitEnumerator --- LibGit2Sharp/CommitCollection.cs | 41 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/LibGit2Sharp/CommitCollection.cs b/LibGit2Sharp/CommitCollection.cs index 480b78152..7c74da7c7 100644 --- a/LibGit2Sharp/CommitCollection.cs +++ b/LibGit2Sharp/CommitCollection.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -39,7 +40,7 @@ public int Count get { var count = 0; - using (var enumerator = new CommitEnumerator(repo, true)) + using (var enumerator = new CommitEnumerator(repo)) { enumerator.Sort(sortOptions); enumerator.Push(pushedSha); @@ -129,26 +130,30 @@ public CommitCollection StartingAt(string sha) private class CommitEnumerator : IEnumerator { - private readonly bool forCountOnly; private readonly Repository repo; private readonly RevWalkerSafeHandle handle; + private ObjectId currentOid; - public CommitEnumerator(Repository repo, bool forCountOnly = false) + public CommitEnumerator(Repository repo) { this.repo = repo; - this.forCountOnly = forCountOnly; int res = NativeMethods.git_revwalk_new(out handle, repo.Handle); Ensure.Success(res); } #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,12 +165,16 @@ public bool MoveNext() { GitOid oid; var res = NativeMethods.git_revwalk_next(out oid, handle); - if (res == (int)GitErrorCode.GIT_EREVWALKOVER) return false; - - if (!forCountOnly) + + if (res == (int)GitErrorCode.GIT_EREVWALKOVER) { - Current = repo.Lookup(new ObjectId(oid)); + return false; } + + Ensure.Success(res); + + currentOid = new ObjectId(oid); + return true; } @@ -176,6 +185,12 @@ public void Reset() #endregion + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + private void Dispose(bool disposing) { if (handle == null || handle.IsInvalid) From 4322bd76853054cd60601629ac239654ae89c220 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 19 May 2011 17:05:37 +0200 Subject: [PATCH 17/21] Enforce CommitEnumerator immutability --- LibGit2Sharp/CommitCollection.cs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/LibGit2Sharp/CommitCollection.cs b/LibGit2Sharp/CommitCollection.cs index 7c74da7c7..85bdad14f 100644 --- a/LibGit2Sharp/CommitCollection.cs +++ b/LibGit2Sharp/CommitCollection.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.IO; using LibGit2Sharp.Core; namespace LibGit2Sharp @@ -40,10 +39,8 @@ public int Count get { var count = 0; - using (var enumerator = new CommitEnumerator(repo)) + using (var enumerator = new CommitEnumerator(repo, new ObjectId(pushedSha), sortOptions)) { - enumerator.Sort(sortOptions); - enumerator.Push(pushedSha); while (enumerator.MoveNext()) count++; } return count; @@ -63,10 +60,7 @@ public IEnumerator GetEnumerator() throw new NotImplementedException(); } - var enumerator = new CommitEnumerator(repo); - enumerator.Sort(sortOptions); - enumerator.Push(pushedSha); - return enumerator; + return new CommitEnumerator(repo, new ObjectId(pushedSha), sortOptions); } /// @@ -134,11 +128,14 @@ private class CommitEnumerator : IEnumerator private readonly RevWalkerSafeHandle handle; private ObjectId currentOid; - public CommitEnumerator(Repository repo) + public CommitEnumerator(Repository repo, ObjectId pushedOid, GitSortOptions sortingStrategy) { this.repo = repo; int res = NativeMethods.git_revwalk_new(out handle, repo.Handle); Ensure.Success(res); + + Sort(sortingStrategy); + Push(pushedOid); } #region IEnumerator Members @@ -201,15 +198,14 @@ private void Dispose(bool disposing) handle.Dispose(); } - public void Push(string sha) + private void Push(ObjectId pushedOid) { - var id = new ObjectId(sha); - var oid = id.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(handle, options); } From 65de100acff6a2b2d2556258cc12d02e0f3fbd14 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 19 May 2011 17:20:02 +0200 Subject: [PATCH 18/21] Fix Repository.Info.IsEmpty --- LibGit2Sharp/RepositoryInformation.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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. From cf9dbed776f4f2a7bd2af346fbf3b5b2229058c9 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 19 May 2011 18:18:02 +0200 Subject: [PATCH 19/21] Convert CommitCollection.StartingAt() overloads as extension methods --- LibGit2Sharp/CommitCollection.cs | 61 ++++++++++------------ LibGit2Sharp/CommitCollectionExtensions.cs | 33 ++++++++++++ LibGit2Sharp/LibGit2Sharp.csproj | 1 + 3 files changed, 62 insertions(+), 33 deletions(-) create mode 100644 LibGit2Sharp/CommitCollectionExtensions.cs diff --git a/LibGit2Sharp/CommitCollection.cs b/LibGit2Sharp/CommitCollection.cs index 85bdad14f..ee92f7073 100644 --- a/LibGit2Sharp/CommitCollection.cs +++ b/LibGit2Sharp/CommitCollection.cs @@ -12,15 +12,26 @@ public class CommitCollection : IEnumerable { private readonly Repository repo; private string pushedSha; - private GitSortOptions sortOptions = GitSortOptions.Time; + 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,7 +43,7 @@ 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 { @@ -47,6 +58,14 @@ public int Count } } + /// + /// Gets the current sorting strategy applied when enumerating the collection + /// + public GitSortOptions SortedBy + { + get { return sortOptions; } + } + #region IEnumerable Members /// @@ -75,37 +94,13 @@ 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. - /// - /// The branch. - /// - public CommitCollection StartingAt(Branch branch) - { - Ensure.ArgumentNotNull(branch, "branch"); - - return new CommitCollection(repo) { sortOptions = sortOptions, pushedSha = branch.Tip.Sha }; - } - - /// - /// Starts enumeratoring the at the specified reference. + /// Sorts according to the specified strategy. /// - /// The reference. + /// The sorting strategy to be applied when enumerating the commits. /// - public CommitCollection StartingAt(Reference reference) + public CommitCollection SortBy(GitSortOptions sortingStrategy) { - Ensure.ArgumentNotNull(reference, "reference"); - - return new CommitCollection(repo) { sortOptions = sortOptions, pushedSha = reference.ResolveToDirectReference().Target.Sha }; + return new CommitCollection(repo, sortingStrategy) { pushedSha = pushedSha }; } /// @@ -117,7 +112,7 @@ public CommitCollection StartingAt(string sha) { Ensure.ArgumentNotNullOrEmptyString(sha, "sha"); - return new CommitCollection(repo) { sortOptions = sortOptions, pushedSha = sha }; + return new CommitCollection(repo, sortOptions) { pushedSha = sha }; } #region Nested type: CommitEnumerator diff --git a/LibGit2Sharp/CommitCollectionExtensions.cs b/LibGit2Sharp/CommitCollectionExtensions.cs new file mode 100644 index 000000000..7771af39b --- /dev/null +++ b/LibGit2Sharp/CommitCollectionExtensions.cs @@ -0,0 +1,33 @@ +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"); + + return commitCollection.StartingAt(branch.Tip.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().Target.Sha); + } + } +} diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 86a5f7efe..4579d277f 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -47,6 +47,7 @@ + From 8720df7b9ac3abd546308c6d8674aaafa406a180 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 19 May 2011 18:18:46 +0200 Subject: [PATCH 20/21] Enforce CommitCollection test coverage --- LibGit2Sharp.Tests/CommitFixture.cs | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index c37f2c30f..5a4d57ede 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] + [Ignore("Not implemented yet.")] + 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"])); + } + } + [Test] public void CanEnumerateCommitsWithReverseTimeSorting() { From 2785f5364abed63397fcc9e7ba84781a84cd543d Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 19 May 2011 22:41:10 +0200 Subject: [PATCH 21/21] Ensure a CommitCollection can not be built from an unknown sha or a corrupted reference --- LibGit2Sharp.Tests/CommitFixture.cs | 8 +++---- LibGit2Sharp/CommitCollection.cs | 25 ++++++++++++++-------- LibGit2Sharp/CommitCollectionExtensions.cs | 14 +++++++++--- LibGit2Sharp/Repository.cs | 2 +- backlog.md | 3 --- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index 5a4d57ede..e3effe9fc 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -77,14 +77,14 @@ public void CanEnumerateCommitsFromSha() } [Test] - [Ignore("Not implemented yet.")] 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(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"])); } } diff --git a/LibGit2Sharp/CommitCollection.cs b/LibGit2Sharp/CommitCollection.cs index ee92f7073..7be815047 100644 --- a/LibGit2Sharp/CommitCollection.cs +++ b/LibGit2Sharp/CommitCollection.cs @@ -11,7 +11,7 @@ namespace LibGit2Sharp public class CommitCollection : IEnumerable { private readonly Repository repo; - private string pushedSha; + private ObjectId pushedObjectId; private readonly GitSortOptions sortOptions; /// @@ -50,7 +50,7 @@ public int Count get { var count = 0; - using (var enumerator = new CommitEnumerator(repo, new ObjectId(pushedSha), sortOptions)) + using (var enumerator = new CommitEnumerator(repo, pushedObjectId, sortOptions)) { while (enumerator.MoveNext()) count++; } @@ -74,12 +74,12 @@ public GitSortOptions SortedBy /// An object that can be used to iterate through the collection. public IEnumerator GetEnumerator() { - if (string.IsNullOrEmpty(pushedSha)) + if (pushedObjectId == null) { throw new NotImplementedException(); } - return new CommitEnumerator(repo, new ObjectId(pushedSha), sortOptions); + return new CommitEnumerator(repo, pushedObjectId, sortOptions); } /// @@ -100,19 +100,26 @@ IEnumerator IEnumerable.GetEnumerator() /// public CommitCollection SortBy(GitSortOptions sortingStrategy) { - return new CommitCollection(repo, sortingStrategy) { pushedSha = pushedSha }; + return new CommitCollection(repo, sortingStrategy) { pushedObjectId = pushedObjectId }; } /// /// Starts enumeratoring the at the specified sha. /// - /// The sha. + /// The sha or reference canonical name to use. /// - public CommitCollection StartingAt(string sha) + public CommitCollection StartingAt(string shaOrReferenceName) { - Ensure.ArgumentNotNullOrEmptyString(sha, "sha"); + Ensure.ArgumentNotNullOrEmptyString(shaOrReferenceName, "shaOrReferenceName"); - return new CommitCollection(repo, sortOptions) { pushedSha = sha }; + GitObject gitObj = repo.Lookup(shaOrReferenceName); + + 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) { pushedObjectId = gitObj.Id }; } #region Nested type: CommitEnumerator diff --git a/LibGit2Sharp/CommitCollectionExtensions.cs b/LibGit2Sharp/CommitCollectionExtensions.cs index 7771af39b..cde489a61 100644 --- a/LibGit2Sharp/CommitCollectionExtensions.cs +++ b/LibGit2Sharp/CommitCollectionExtensions.cs @@ -1,4 +1,5 @@ -using LibGit2Sharp.Core; +using System; +using LibGit2Sharp.Core; namespace LibGit2Sharp { @@ -14,7 +15,14 @@ public static CommitCollection StartingAt(this CommitCollection commitCollection { Ensure.ArgumentNotNull(branch, "branch"); - return commitCollection.StartingAt(branch.Tip.Sha); + 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); } /// @@ -27,7 +35,7 @@ public static CommitCollection StartingAt(this CommitCollection commitCollection { Ensure.ArgumentNotNull(reference, "reference"); - return commitCollection.StartingAt(reference.ResolveToDirectReference().Target.Sha); + return commitCollection.StartingAt(reference.ResolveToDirectReference().CanonicalName); } } } diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index d4f68fd21..f1671e6f2 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -214,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/backlog.md b/backlog.md index 8a82dfc8d..2f6074ce8 100644 --- a/backlog.md +++ b/backlog.md @@ -5,10 +5,7 @@ - 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() - - Throw when revwalker is being passed an unknown object - - Change CommitCollection.StartingAt(string sha) into CommitCollection.StartingAt(string referenceNameOrsha) - Fix FluentInterface .StartingAt() and .Until() in order to prevent .StartIngAt().StartingAt(), .Until().Until() and .Until().StartingAt() - - Push StartingAt() overloads into extension methods - 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