Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'origin/vNext' into error-handling-refactor

Conflicts:
	LibGit2Sharp/LibGit2SharpException.cs
  • Loading branch information...
commit 55ee014f5e30c6ff059774be8c70abeb1b0206ea 2 parents 08374d7 + f8f29a9
@tclem authored
Showing with 6,900 additions and 243 deletions.
  1. BIN  Lib/MoQ/Moq.dll
  2. +5,768 −0 Lib/MoQ/Moq.xml
  3. BIN  Lib/NativeBinaries/amd64/git2.dll
  4. BIN  Lib/NativeBinaries/amd64/git2.pdb
  5. BIN  Lib/NativeBinaries/x86/git2.dll
  6. BIN  Lib/NativeBinaries/x86/git2.pdb
  7. +2 −2 LibGit2Sharp.Tests/AttributesFixture.cs
  8. +1 −1  LibGit2Sharp.Tests/CommitFixture.cs
  9. +140 −0 LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs
  10. +39 −0 LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs
  11. +1 −0  LibGit2Sharp.Tests/IndexFixture.cs
  12. +0 −1  LibGit2Sharp.Tests/LazyFixture.cs
  13. +7 −0 LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj
  14. +89 −0 LibGit2Sharp.Tests/MetaFixture.cs
  15. +71 −0 LibGit2Sharp.Tests/MockedRepositoryFixture.cs
  16. +37 −0 LibGit2Sharp.Tests/ObjectDatabaseFixture.cs
  17. +1 −3 LibGit2Sharp.Tests/ObjectIdFixture.cs
  18. +2 −4 LibGit2Sharp.Tests/RemoteFixture.cs
  19. +1 −1  LibGit2Sharp.Tests/ResetIndexFixture.cs
  20. +1 −1  LibGit2Sharp.Tests/StatusFixture.cs
  21. +0 −1  LibGit2Sharp.Tests/TupleFixture.cs
  22. +9 −22 LibGit2Sharp/Blob.cs
  23. +35 −0 LibGit2Sharp/BlobExtensions.cs
  24. +14 −8 LibGit2Sharp/Branch.cs
  25. +26 −8 LibGit2Sharp/BranchCollection.cs
  26. +4 −4 LibGit2Sharp/Changes.cs
  27. +16 −10 LibGit2Sharp/Commit.cs
  28. +12 −5 LibGit2Sharp/CommitLog.cs
  29. +14 −8 LibGit2Sharp/Configuration.cs
  30. +6 −0 LibGit2Sharp/ContentChanges.cs
  31. +1 −1  LibGit2Sharp/Core/GitDiff.cs
  32. +2 −1  LibGit2Sharp/Core/Handles/SafeHandleBase.cs
  33. +28 −1 LibGit2Sharp/Core/NativeMethods.cs
  34. +1 −2  LibGit2Sharp/Core/UnSafeNativeMethods.cs
  35. +2 −2 LibGit2Sharp/Core/Utf8Marshaler.cs
  36. +2 −0  LibGit2Sharp/CustomDictionary.xml
  37. +84 −3 LibGit2Sharp/Diff.cs
  38. +11 −1 LibGit2Sharp/DiffTarget.cs
  39. +7 −1 LibGit2Sharp/DirectReference.cs
  40. +8 −2 LibGit2Sharp/GitObject.cs
  41. +104 −0 LibGit2Sharp/IRepository.cs
  42. +24 −18 LibGit2Sharp/Index.cs
  43. +2 −0  LibGit2Sharp/LibGit2Sharp.csproj
  44. +1 −1  LibGit2Sharp/Mode.cs
  45. +12 −6 LibGit2Sharp/Note.cs
  46. +18 −12 LibGit2Sharp/NoteCollection.cs
  47. +65 −5 LibGit2Sharp/ObjectDatabase.cs
  48. +2 −2 LibGit2Sharp/Reference.cs
  49. +14 −8 LibGit2Sharp/ReferenceCollection.cs
  50. +15 −5 LibGit2Sharp/ReferenceWrapper.cs
  51. +8 −2 LibGit2Sharp/Remote.cs
  52. +22 −8 LibGit2Sharp/RemoteCollection.cs
  53. +8 −3 LibGit2Sharp/Repository.cs
  54. +12 −12 LibGit2Sharp/RepositoryExtensions.cs
  55. +12 −6 LibGit2Sharp/RepositoryInformation.cs
  56. +15 −9 LibGit2Sharp/RepositoryStatus.cs
  57. +8 −2 LibGit2Sharp/StatusEntry.cs
  58. +9 −3 LibGit2Sharp/Tag.cs
  59. +10 −4 LibGit2Sharp/TagAnnotation.cs
  60. +26 −9 LibGit2Sharp/TagCollection.cs
  61. +11 −5 LibGit2Sharp/Tree.cs
  62. +18 −8 LibGit2Sharp/TreeChanges.cs
  63. +8 −4 LibGit2Sharp/TreeDefinition.cs
  64. +13 −6 LibGit2Sharp/TreeEntry.cs
  65. +13 −7 LibGit2Sharp/TreeEntryChanges.cs
  66. +6 −3 LibGit2Sharp/TreeEntryDefinition.cs
  67. +1 −1  LibGit2Sharp/libgit2_hash.txt
  68. +1 −1  libgit2
View
BIN  Lib/MoQ/Moq.dll
Binary file not shown
View
5,768 Lib/MoQ/Moq.xml
5,768 additions, 0 deletions not shown
View
BIN  Lib/NativeBinaries/amd64/git2.dll
Binary file not shown
View
BIN  Lib/NativeBinaries/amd64/git2.pdb
Binary file not shown
View
BIN  Lib/NativeBinaries/x86/git2.dll
Binary file not shown
View
BIN  Lib/NativeBinaries/x86/git2.pdb
Binary file not shown
View
4 LibGit2Sharp.Tests/AttributesFixture.cs
@@ -21,7 +21,7 @@ public void StagingHonorsTheAttributesFiles()
}
}
- private void AssertNormalization(Repository repo, string filename, bool shouldHaveBeenNormalized, string expectedSha)
+ private static void AssertNormalization(Repository repo, string filename, bool shouldHaveBeenNormalized, string expectedSha)
{
var sb = new StringBuilder();
sb.Append("I'm going to be dynamically processed\r\n");
@@ -44,7 +44,7 @@ private void AssertNormalization(Repository repo, string filename, bool shouldHa
Assert.Equal(!shouldHaveBeenNormalized, blob.ContentAsUtf8().Contains("\r"));
}
- private void CreateAttributesFile(Repository repo)
+ private static void CreateAttributesFile(Repository repo)
{
const string relativePath = ".gitattributes";
string fullFilePath = Path.Combine(repo.Info.WorkingDirectory, relativePath);
View
2  LibGit2Sharp.Tests/CommitFixture.cs
@@ -631,7 +631,7 @@ private static void CreateAndStageANewFile(Repository repo)
repo.Index.Stage(relativeFilepath);
}
- private void AssertCommitHasBeenAmended(Repository repo, Commit amendedCommit, Commit originalCommit)
+ private static void AssertCommitHasBeenAmended(Repository repo, Commit amendedCommit, Commit originalCommit)
{
Commit headCommit = repo.Head.Tip;
Assert.Equal(amendedCommit, headCommit);
View
140 LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs
@@ -25,6 +25,146 @@ private static void SetUpSimpleDiffContext(Repository repo)
[Fact]
/*
+ * No direct git equivalent but should output
+ *
+ * diff --git a/file.txt b/file.txt
+ * index ce01362..4f125e3 100644
+ * --- a/file.txt
+ * +++ b/file.txt
+ * @@ -1 +1,3 @@
+ * hello
+ * +world
+ * +!!!
+ */
+ public void CanCompareASimpleTreeAgainstTheWorkDir()
+ {
+ var scd = BuildSelfCleaningDirectory();
+
+ using (var repo = Repository.Init(scd.RootedDirectoryPath))
+ {
+ SetUpSimpleDiffContext(repo);
+
+ TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTarget.WorkingDirectory);
+
+ var expected = new StringBuilder()
+ .Append("diff --git a/file.txt b/file.txt\n")
+ .Append("index ce01362..4f125e3 100644\n")
+ .Append("--- a/file.txt\n")
+ .Append("+++ b/file.txt\n")
+ .Append("@@ -1 +1,3 @@\n")
+ .Append(" hello\n")
+ .Append("+world\n")
+ .Append("+!!!\n");
+
+ Assert.Equal(expected.ToString(), changes.Patch);
+ }
+ }
+
+ [Fact]
+ /*
+ * $ git diff HEAD
+ * diff --git a/file.txt b/file.txt
+ * index ce01362..4f125e3 100644
+ * --- a/file.txt
+ * +++ b/file.txt
+ * @@ -1 +1,3 @@
+ * hello
+ * +world
+ * +!!!
+ */
+ public void CanCompareASimpleTreeAgainstTheWorkDirAndTheIndex()
+ {
+ var scd = BuildSelfCleaningDirectory();
+
+ using (var repo = Repository.Init(scd.RootedDirectoryPath))
+ {
+ SetUpSimpleDiffContext(repo);
+
+ TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTarget.BothWorkingDirectoryAndIndex);
+
+ var expected = new StringBuilder()
+ .Append("diff --git a/file.txt b/file.txt\n")
+ .Append("index ce01362..4f125e3 100644\n")
+ .Append("--- a/file.txt\n")
+ .Append("+++ b/file.txt\n")
+ .Append("@@ -1 +1,3 @@\n")
+ .Append(" hello\n")
+ .Append("+world\n")
+ .Append("+!!!\n");
+
+ Assert.Equal(expected.ToString(), changes.Patch);
+ }
+ }
+
+
+ [Fact]
+ /*
+ * $ git diff
+ *
+ * $ git diff HEAD
+ * diff --git a/file.txt b/file.txt
+ * deleted file mode 100644
+ * index ce01362..0000000
+ * --- a/file.txt
+ * +++ /dev/null
+ * @@ -1 +0,0 @@
+ * -hello
+ *
+ * $ git diff --cached
+ * diff --git a/file.txt b/file.txt
+ * deleted file mode 100644
+ * index ce01362..0000000
+ * --- a/file.txt
+ * +++ /dev/null
+ * @@ -1 +0,0 @@
+ * -hello
+ */
+ public void ShowcaseTheDifferenceBetweenTheTwoKindOfComparison()
+ {
+ var scd = BuildSelfCleaningDirectory();
+
+ using (var repo = Repository.Init(scd.RootedDirectoryPath))
+ {
+ SetUpSimpleDiffContext(repo);
+
+ var fullpath = Path.Combine(repo.Info.WorkingDirectory, "file.txt");
+ File.Move(fullpath, fullpath + ".bak");
+ repo.Index.Stage(fullpath);
+ File.Move(fullpath + ".bak", fullpath);
+
+ FileStatus state = repo.Index.RetrieveStatus("file.txt");
+ Assert.Equal(FileStatus.Removed | FileStatus.Untracked, state);
+
+
+ TreeChanges wrkDirToIdxToTree = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTarget.BothWorkingDirectoryAndIndex);
+ var expected = new StringBuilder()
+ .Append("diff --git a/file.txt b/file.txt\n")
+ .Append("deleted file mode 100644\n")
+ .Append("index ce01362..0000000\n")
+ .Append("--- a/file.txt\n")
+ .Append("+++ /dev/null\n")
+ .Append("@@ -1 +0,0 @@\n")
+ .Append("-hello\n");
+
+ Assert.Equal(expected.ToString(), wrkDirToIdxToTree.Patch);
+
+ TreeChanges wrkDirToTree = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTarget.WorkingDirectory);
+ expected = new StringBuilder()
+ .Append("diff --git a/file.txt b/file.txt\n")
+ .Append("index ce01362..4f125e3 100644\n")
+ .Append("--- a/file.txt\n")
+ .Append("+++ b/file.txt\n")
+ .Append("@@ -1 +1,3 @@\n")
+ .Append(" hello\n")
+ .Append("+world\n")
+ .Append("+!!!\n");
+
+ Assert.Equal(expected.ToString(), wrkDirToTree.Patch);
+ }
+ }
+
+ [Fact]
+ /*
* $ git diff --cached
* diff --git a/file.txt b/file.txt
* index ce01362..94954ab 100644
View
39 LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs
@@ -0,0 +1,39 @@
+using System.Linq;
+using LibGit2Sharp.Tests.TestHelpers;
+using Xunit;
+
+namespace LibGit2Sharp.Tests
+{
+ public class DiffWorkdirToIndexFixture : BaseFixture
+ {
+ /*
+ * $ git diff
+ * diff --git a/deleted_unstaged_file.txt b/deleted_unstaged_file.txt
+ * deleted file mode 100644
+ * index f2e4113..0000000
+ * --- a/deleted_unstaged_file.txt
+ * +++ /dev/null
+ * @@ -1 +0,0 @@
+ * -stuff
+ * diff --git a/modified_unstaged_file.txt b/modified_unstaged_file.txt
+ * index 9217230..da6fd65 100644
+ * --- a/modified_unstaged_file.txt
+ * +++ b/modified_unstaged_file.txt
+ * @@ -1 +1,2 @@
+ * +some more text
+ * more files! more files!
+ */
+ [Fact]
+ public void CanCompareTheWorkDirAgainstTheIndex()
+ {
+ using (var repo = new Repository(StandardTestRepoPath))
+ {
+ TreeChanges changes = repo.Diff.Compare();
+
+ Assert.Equal(2, changes.Count());
+ Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path);
+ Assert.Equal("modified_unstaged_file.txt", changes.Modified.Single().Path);
+ }
+ }
+ }
+}
View
1  LibGit2Sharp.Tests/IndexFixture.cs
@@ -84,6 +84,7 @@ public void ReadIndexWithBadParamsFails()
[Theory]
[InlineData("1/branch_file.txt", FileStatus.Unaltered, true, FileStatus.Unaltered, true, 0)]
+ [InlineData("README", FileStatus.Unaltered, true, FileStatus.Unaltered, true, 0)]
[InlineData("deleted_unstaged_file.txt", FileStatus.Missing, true, FileStatus.Removed, false, -1)]
[InlineData("modified_unstaged_file.txt", FileStatus.Modified, true, FileStatus.Staged, true, 0)]
[InlineData("new_untracked_file.txt", FileStatus.Untracked, false, FileStatus.Added, true, 1)]
View
1  LibGit2Sharp.Tests/LazyFixture.cs
@@ -1,6 +1,5 @@
using System;
using LibGit2Sharp.Core.Compat;
-using LibGit2Sharp.Tests.TestHelpers;
using Xunit;
namespace LibGit2Sharp.Tests
View
7 LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj
@@ -43,6 +43,10 @@
<DocumentationFile />
</PropertyGroup>
<ItemGroup>
+ <Reference Include="Moq, Version=4.0.10827.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Lib\MoQ\Moq.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="xunit">
@@ -53,12 +57,15 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="MetaFixture.cs" />
+ <Compile Include="MockedRepositoryFixture.cs" />
<Compile Include="ConfigurationFixture.cs" />
<Compile Include="AttributesFixture.cs" />
<Compile Include="CommitAncestorFixture.cs" />
<Compile Include="NoteFixture.cs" />
<Compile Include="DiffBlobToBlobFixture.cs" />
<Compile Include="DiffTreeToTargetFixture.cs" />
+ <Compile Include="DiffWorkdirToIndexFixture.cs" />
<Compile Include="ObjectDatabaseFixture.cs" />
<Compile Include="DiffTreeToTreeFixture.cs" />
<Compile Include="RepositoryOptionsFixture.cs" />
View
89 LibGit2Sharp.Tests/MetaFixture.cs
@@ -0,0 +1,89 @@
+using System.Text;
+using Xunit;
+using System.Reflection;
+using System;
+using System.Linq;
+using System.Collections.Generic;
+
+namespace LibGit2Sharp.Tests
+{
+ public class MetaFixture
+ {
+ private static readonly Type[] excludedTypes = new[] { typeof(Repository) };
+
+ // Related to https://github.com/libgit2/libgit2sharp/pull/185
+ [Fact]
+ public void TypesInLibGit2SharpMustBeExtensibleInATestingContext()
+ {
+ var nonTestableTypes = new Dictionary<Type, IEnumerable<string>>();
+
+ IEnumerable<Type> libGit2SharpTypes = Assembly.GetAssembly(typeof(Repository)).GetExportedTypes().Where(t => !excludedTypes.Contains(t) && t.Namespace == typeof(Repository).Namespace);
+
+ foreach (Type type in libGit2SharpTypes)
+ {
+ if (type.IsInterface || type.IsEnum || IsStatic(type))
+ continue;
+
+ ConstructorInfo[] publicConstructor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
+ if (publicConstructor.Any())
+ {
+ continue;
+ }
+
+ var nonVirtualMethodNamesForType = GetNonVirtualPublicMethodsNames(type).ToList();
+ if (nonVirtualMethodNamesForType.Any())
+ {
+ nonTestableTypes.Add(type, nonVirtualMethodNamesForType);
+ continue;
+ }
+
+ if (!HasEmptyProtectedConstructor(type))
+ {
+ nonTestableTypes.Add(type, new List<string>());
+ }
+ }
+
+ if (nonTestableTypes.Any())
+ {
+ Assert.True(false, Environment.NewLine + BuildNonTestableTypesMessage(nonTestableTypes));
+ }
+ }
+
+ private static string BuildNonTestableTypesMessage(Dictionary<Type, IEnumerable<string>> nonTestableTypes)
+ {
+ var sb = new StringBuilder();
+
+ foreach (var kvp in nonTestableTypes)
+ {
+ sb.AppendFormat("'{0}' cannot be easily abstracted in a testing context. Please make sure it either has a public constructor, or an empty protected constructor.{1}",
+ kvp.Key, Environment.NewLine);
+
+ foreach (string methodName in kvp.Value)
+ {
+ sb.AppendFormat(" - Method '{0}' must be virtual{1}", methodName, Environment.NewLine);
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ private static IEnumerable<string> GetNonVirtualPublicMethodsNames(Type type)
+ {
+ var publicMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
+
+ return from mi in publicMethods where !mi.IsVirtual && !mi.IsStatic select mi.ToString();
+ }
+
+ private static bool HasEmptyProtectedConstructor(Type type)
+ {
+ ConstructorInfo[] nonPublicConstructors = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
+
+ return nonPublicConstructors.Any(ci => !ci.IsPrivate && !ci.IsAssembly && !ci.IsFinal && !ci.GetParameters().Any());
+ }
+
+ private static bool IsStatic(Type type)
+ {
+ return type.IsAbstract && type.IsSealed;
+ }
+ }
+}
View
71 LibGit2Sharp.Tests/MockedRepositoryFixture.cs
@@ -0,0 +1,71 @@
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using LibGit2Sharp.Tests.TestHelpers;
+using Xunit;
+using Moq;
+
+namespace LibGit2Sharp.Tests
+{
+ // This fixture shows how one can mock the IRepository when writing an application against LibGit2Sharp.
+ // The application we want to test is simulated by the CommitCounter class (see below), which takes an IRepository,
+ // and whose role is to compute and return the number of commits in the given repository.
+ public class MockedRepositoryFixture : BaseFixture
+ {
+ // In this test, we pass to CommitCounter a concrete instance of the Repository. It means we will end up calling the concrete Repository
+ // during the test run.
+ [Fact]
+ public void CanCountCommitsWithConcreteRepository()
+ {
+ using (var repo = new Repository(BareTestRepoPath))
+ {
+ var commitCounter = new CommitCounter(repo);
+ Assert.Equal(7, commitCounter.NumberOfCommits);
+ }
+ }
+
+ // This test shows that CommitCounter can take a mocked instance of IRepository. It means we can test CommitCounter without
+ // relying on the concrete repository. We are testing CommitCounter in isolation.
+ [Fact]
+ public void CanCountCommitsWithMockedRepository()
+ {
+ var commitLog = Mock.Of<CommitLog>(cl => cl.GetEnumerator() == FakeCommitLog(17));
+ var repo = Mock.Of<IRepository>(r => r.Commits == commitLog);
+
+ var commitCounter = new CommitCounter(repo);
+ Assert.Equal(17, commitCounter.NumberOfCommits);
+ }
+
+ private static IEnumerator<Commit> FakeCommitLog(int size)
+ {
+ for (int i = 0; i < size; i++)
+ {
+ yield return FakeCommit(Guid.NewGuid().ToString());
+ }
+ }
+
+ private static Commit FakeCommit(string sha)
+ {
+ var commitMock = new Mock<Commit>();
+ commitMock.SetupGet(x => x.Sha).Returns(sha);
+
+ return commitMock.Object;
+ }
+
+ // Simulated external application ;)
+ private class CommitCounter
+ {
+ private readonly IRepository repo;
+
+ public CommitCounter(IRepository repo)
+ {
+ this.repo = repo;
+ }
+
+ public int NumberOfCommits
+ {
+ get { return repo.Commits.Count(); }
+ }
+ }
+ }
+}
View
37 LibGit2Sharp.Tests/ObjectDatabaseFixture.cs
@@ -1,4 +1,5 @@
using System.IO;
+using System.Text;
using LibGit2Sharp.Tests.TestHelpers;
using Xunit;
using Xunit.Extensions;
@@ -77,6 +78,42 @@ public void CanCreateABlobIntoTheDatabaseOfABareRepository()
}
[Theory]
+ [InlineData("321cbdf08803c744082332332838df6bd160f8f9", null)]
+ [InlineData("321cbdf08803c744082332332838df6bd160f8f9", "dummy.data")]
+ [InlineData("e9671e138a780833cb689753570fd10a55be84fb", "dummy.txt")]
+ [InlineData("e9671e138a780833cb689753570fd10a55be84fb", "dummy.guess")]
+ public void CanCreateABlobFromABinaryReader(string expectedSha, string hintPath)
+ {
+ TemporaryCloneOfTestRepo scd = BuildTemporaryCloneOfTestRepo();
+
+ var sb = new StringBuilder();
+ for (int i = 0; i < 6; i++)
+ {
+ sb.Append("libgit2\n\r\n");
+ }
+
+ using (var repo = new Repository(scd.RepositoryPath))
+ {
+ CreateAttributesFiles(Path.Combine(repo.Info.Path, "info"), "attributes");
+
+ using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(sb.ToString())))
+ using (var binReader = new BinaryReader(stream))
+ {
+ Blob blob = repo.ObjectDatabase.CreateBlob(binReader, hintPath);
+ Assert.Equal(expectedSha, blob.Sha);
+ }
+ }
+ }
+
+ private static void CreateAttributesFiles(string where, string filename)
+ {
+ const string attributes = "* text=auto\n*.txt text\n*.data binary\n";
+
+ Directory.CreateDirectory(where);
+ File.WriteAllText(Path.Combine(where, filename), attributes);
+ }
+
+ [Theory]
[InlineData("README")]
[InlineData("README AS WELL")]
[InlineData("2/README AS WELL")]
View
4 LibGit2Sharp.Tests/ObjectIdFixture.cs
@@ -1,6 +1,4 @@
using System;
-using System.Linq;
-using LibGit2Sharp.Tests.TestHelpers;
using Xunit;
using Xunit.Extensions;
@@ -11,7 +9,7 @@ public class ObjectIdFixture
private const string validSha1 = "ce08fe4884650f067bd5703b6a59a8b3b3c99a09";
private const string validSha2 = "de08fe4884650f067bd5703b6a59a8b3b3c99a09";
- private static byte[] bytes = new byte[] { 206, 8, 254, 72, 132, 101, 15, 6, 123, 213, 112, 59, 106, 89, 168, 179, 179, 201, 154, 9 };
+ private static readonly byte[] bytes = new byte[] { 206, 8, 254, 72, 132, 101, 15, 6, 123, 213, 112, 59, 106, 89, 168, 179, 179, 201, 154, 9 };
[Theory]
[InlineData("Dummy", typeof(ArgumentException))]
View
6 LibGit2Sharp.Tests/RemoteFixture.cs
@@ -86,8 +86,7 @@ public void CreatingANewRemoteAddsADefaultRefSpec()
var refSpec = repo.Config.Get<string>("remote", remote.Name, "fetch", null);
Assert.NotNull(refSpec);
- //TODO: Uncomment the line below once https://github.com/libgit2/libgit2/pull/737 is merged
- //Assert.Equal("+refs/heads/*:refs/remotes/upstream/*", refSpec);
+ Assert.Equal("+refs/heads/*:refs/remotes/upstream/*", refSpec);
}
}
@@ -107,8 +106,7 @@ public void CanAddANewRemoteWithAFetchRefSpec()
var refSpec = repo.Config.Get<string>("remote", name, "fetch", null);
Assert.NotNull(refSpec);
- //TODO: Uncomment the line below once https://github.com/libgit2/libgit2/pull/737 is merged
- //Assert.Equal(fetchRefSpec, refSpec);
+ Assert.Equal(fetchRefSpec, refSpec);
}
}
}
View
2  LibGit2Sharp.Tests/ResetIndexFixture.cs
@@ -30,7 +30,7 @@ public void ResettingInABareRepositoryThrows()
}
}
- private bool IsStaged(StatusEntry entry)
+ private static bool IsStaged(StatusEntry entry)
{
if ((entry.State & FileStatus.Added) == FileStatus.Added)
{
View
2  LibGit2Sharp.Tests/StatusFixture.cs
@@ -133,7 +133,7 @@ public void RetrievingTheStatusOfAnEmptyRepositoryHonorsTheGitIgnoreDirectives()
using (Repository repo = Repository.Init(scd.DirectoryPath))
{
- string relativePath = "look-ma.txt";
+ const string relativePath = "look-ma.txt";
string fullFilePath = Path.Combine(repo.Info.WorkingDirectory, relativePath);
File.WriteAllText(fullFilePath, "I'm going to be ignored!");
View
1  LibGit2Sharp.Tests/TupleFixture.cs
@@ -1,5 +1,4 @@
using LibGit2Sharp.Core.Compat;
-using LibGit2Sharp.Tests.TestHelpers;
using Xunit;
namespace LibGit2Sharp.Tests
View
31 LibGit2Sharp/Blob.cs
@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
-using System.Text;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Handles;
@@ -14,6 +13,12 @@ public class Blob : GitObject
{
private readonly Repository repo;
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected Blob()
+ { }
+
internal Blob(Repository repo, ObjectId id)
: base(id)
{
@@ -23,12 +28,12 @@ internal Blob(Repository repo, ObjectId id)
/// <summary>
/// Gets the size in bytes of the contents of a blob
/// </summary>
- public int Size { get; set; }
+ public virtual int Size { get; set; }
/// <summary>
/// Gets the blob content in a <see cref="byte" /> array.
/// </summary>
- public byte[] Content
+ public virtual byte[] Content
{
get
{
@@ -44,7 +49,7 @@ public byte[] Content
/// <summary>
/// Gets the blob content in a <see cref="Stream" />.
/// </summary>
- public Stream ContentStream
+ public virtual Stream ContentStream
{
get
{
@@ -59,24 +64,6 @@ public Stream ContentStream
}
}
- /// <summary>
- /// Gets the blob content decoded as UTF-8.
- /// </summary>
- /// <returns></returns>
- public string ContentAsUtf8()
- {
- return Encoding.UTF8.GetString(Content);
- }
-
- /// <summary>
- /// Gets the blob content decoded as Unicode.
- /// </summary>
- /// <returns></returns>
- public string ContentAsUnicode()
- {
- return Encoding.Unicode.GetString(Content);
- }
-
internal static Blob BuildFromPtr(GitObjectSafeHandle obj, ObjectId id, Repository repo)
{
var blob = new Blob(repo, id)
View
35 LibGit2Sharp/BlobExtensions.cs
@@ -0,0 +1,35 @@
+using System.Text;
+using LibGit2Sharp.Core;
+
+namespace LibGit2Sharp
+{
+ /// <summary>
+ /// Provides helper overloads to a <see cref = "Blob" />.
+ /// </summary>
+ public static class BlobExtensions
+ {
+ /// <summary>
+ /// Gets the blob content decoded as UTF-8.
+ /// </summary>
+ /// <param name="blob">The blob for which the content will be returned.</param>
+ /// <returns>Blob content as UTF-8</returns>
+ public static string ContentAsUtf8(this Blob blob)
+ {
+ Ensure.ArgumentNotNull(blob, "blob");
+
+ return Encoding.UTF8.GetString(blob.Content);
+ }
+
+ /// <summary>
+ /// Gets the blob content decoded as Unicode.
+ /// </summary>
+ /// <param name="blob">The blob for which the content will be returned.</param>
+ /// <returns>Blob content as unicode.</returns>
+ public static string ContentAsUnicode(this Blob blob)
+ {
+ Ensure.ArgumentNotNull(blob, "blob");
+
+ return Encoding.Unicode.GetString(blob.Content);
+ }
+ }
+}
View
22 LibGit2Sharp/Branch.cs
@@ -13,6 +13,12 @@ public class Branch : ReferenceWrapper<Commit>
private readonly Lazy<Branch> trackedBranch;
/// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected Branch()
+ { }
+
+ /// <summary>
/// Initializes a new instance of the <see cref = "Branch" /> class.
/// </summary>
/// <param name = "repo">The repo.</param>
@@ -47,7 +53,7 @@ private Branch(Repository repo, Reference reference, Func<Reference, string> can
/// </summary>
/// <param name = "relativePath">The relative path to the <see cref = "TreeEntry" /> from the <see cref = "Tip" /> working directory.</param>
/// <returns><c>null</c> if nothing has been found, the <see cref = "TreeEntry" /> otherwise.</returns>
- public TreeEntry this[string relativePath]
+ public virtual TreeEntry this[string relativePath]
{
get
{
@@ -74,7 +80,7 @@ public virtual bool IsRemote
/// <summary>
/// Gets the remote branch which is connected to this local one.
/// </summary>
- public Branch TrackedBranch
+ public virtual Branch TrackedBranch
{
get { return trackedBranch.Value; }
}
@@ -82,7 +88,7 @@ public Branch TrackedBranch
/// <summary>
/// Determines if this local branch is connected to a remote one.
/// </summary>
- public bool IsTracking
+ public virtual bool IsTracking
{
get { return TrackedBranch != null; }
}
@@ -90,7 +96,7 @@ public bool IsTracking
/// <summary>
/// Gets the number of commits, starting from the <see cref="Tip"/>, that have been performed on this local branch and aren't known from the remote one.
/// </summary>
- public int AheadBy
+ public virtual int AheadBy
{
get { return IsTracking ? repo.Commits.QueryBy(new Filter { Since = Tip, Until = TrackedBranch }).Count() : 0; }
}
@@ -98,7 +104,7 @@ public int AheadBy
/// <summary>
/// Gets the number of commits that exist in the remote branch, on top of <see cref="Tip"/>, and aren't known from the local one.
/// </summary>
- public int BehindBy
+ public virtual int BehindBy
{
get { return IsTracking ? repo.Commits.QueryBy(new Filter { Since = TrackedBranch, Until = Tip }).Count() : 0; }
}
@@ -109,7 +115,7 @@ public int BehindBy
/// <value>
/// <c>true</c> if this instance is the current branch; otherwise, <c>false</c>.
/// </value>
- public bool IsCurrentRepositoryHead
+ public virtual bool IsCurrentRepositoryHead
{
get { return repo.Head == this; }
}
@@ -117,7 +123,7 @@ public bool IsCurrentRepositoryHead
/// <summary>
/// Gets the <see cref="Commit"/> that this branch points to.
/// </summary>
- public Commit Tip
+ public virtual Commit Tip
{
get { return TargetObject; }
}
@@ -125,7 +131,7 @@ public Commit Tip
/// <summary>
/// Gets the commits on this branch. (Starts walking from the References's target).
/// </summary>
- public ICommitLog Commits
+ public virtual ICommitLog Commits
{
get { return repo.Commits.QueryBy(new Filter { Since = this }); }
}
View
34 LibGit2Sharp/BranchCollection.cs
@@ -15,6 +15,12 @@ public class BranchCollection : IEnumerable<Branch>
private readonly Repository repo;
/// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected BranchCollection()
+ { }
+
+ /// <summary>
/// Initializes a new instance of the <see cref = "BranchCollection" /> class.
/// </summary>
/// <param name = "repo">The repo.</param>
@@ -26,7 +32,7 @@ internal BranchCollection(Repository repo)
/// <summary>
/// Gets the <see cref = "LibGit2Sharp.Branch" /> with the specified name.
/// </summary>
- public Branch this[string name]
+ public virtual Branch this[string name]
{
get
{
@@ -43,7 +49,13 @@ internal BranchCollection(Repository repo)
return branch;
}
- return BuildFromReferenceName(ShortToRemoteName(name));
+ branch = BuildFromReferenceName(ShortToRemoteName(name));
+ if (branch != null)
+ {
+ return branch;
+ }
+
+ return BuildFromReferenceName(ShortToRefName(name));
}
}
@@ -57,6 +69,11 @@ private static string ShortToRemoteName(string name)
return string.Format(CultureInfo.InvariantCulture, "{0}{1}", "refs/remotes/", name);
}
+ private static string ShortToRefName(string name)
+ {
+ return string.Format(CultureInfo.InvariantCulture, "{0}{1}", "refs/", name);
+ }
+
private Branch BuildFromReferenceName(string canonicalName)
{
var reference = repo.Refs.Resolve<Reference>(canonicalName);
@@ -69,11 +86,12 @@ private Branch BuildFromReferenceName(string canonicalName)
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>An <see cref = "IEnumerator{T}" /> object that can be used to iterate through the collection.</returns>
- public IEnumerator<Branch> GetEnumerator()
+ public virtual IEnumerator<Branch> GetEnumerator()
{
return Libgit2UnsafeHelper
.ListAllBranchNames(repo.Handle, GitBranchType.GIT_BRANCH_LOCAL | GitBranchType.GIT_BRANCH_REMOTE)
.Select(n => this[n])
+ .OrderBy(b => b.CanonicalName, StringComparer.Ordinal)
.GetEnumerator();
}
@@ -95,7 +113,7 @@ IEnumerator IEnumerable.GetEnumerator()
/// <param name = "shaOrReferenceName">The target which can be sha or a canonical reference name.</param>
/// <param name = "allowOverwrite">True to allow silent overwriting a potentially existing branch, false otherwise.</param>
/// <returns></returns>
- public Branch Add(string name, string shaOrReferenceName, bool allowOverwrite = false)
+ public virtual Branch Add(string name, string shaOrReferenceName, bool allowOverwrite = false)
{
Ensure.ArgumentNotNullOrEmptyString(name, "name");
@@ -118,7 +136,7 @@ public Branch Add(string name, string shaOrReferenceName, bool allowOverwrite =
/// <param name = "allowOverwrite">True to allow silent overwriting a potentially existing branch, false otherwise.</param>
/// <returns></returns>
[Obsolete("This method will be removed in the next release. Please use Add() instead.")]
- public Branch Create(string name, string shaOrReferenceName, bool allowOverwrite = false)
+ public virtual Branch Create(string name, string shaOrReferenceName, bool allowOverwrite = false)
{
return Add(name, shaOrReferenceName, allowOverwrite);
}
@@ -128,7 +146,7 @@ public Branch Create(string name, string shaOrReferenceName, bool allowOverwrite
/// </summary>
/// <param name = "name">The name of the branch to delete.</param>
/// <param name = "isRemote">True if the provided <paramref name="name"/> is the name of a remote branch, false otherwise.</param>
- public void Remove(string name, bool isRemote = false)
+ public virtual void Remove(string name, bool isRemote = false)
{
Ensure.ArgumentNotNullOrEmptyString(name, "name");
@@ -148,7 +166,7 @@ public void Remove(string name, bool isRemote = false)
/// <param name = "name">The name of the branch to delete.</param>
/// <param name = "isRemote">True if the provided <paramref name="name"/> is the name of a remote branch, false otherwise.</param>
[Obsolete("This method will be removed in the next release. Please use Remove() instead.")]
- public void Delete(string name, bool isRemote = false)
+ public virtual void Delete(string name, bool isRemote = false)
{
Remove(name, isRemote);
}
@@ -160,7 +178,7 @@ public void Delete(string name, bool isRemote = false)
///<param name = "newName">The new name of the existing branch should bear.</param>
///<param name = "allowOverwrite">True to allow silent overwriting a potentially existing branch, false otherwise.</param>
///<returns></returns>
- public Branch Move(string currentName, string newName, bool allowOverwrite = false)
+ public virtual Branch Move(string currentName, string newName, bool allowOverwrite = false)
{
Ensure.ArgumentNotNullOrEmptyString(currentName, "currentName");
Ensure.ArgumentNotNullOrEmptyString(newName, "name");
View
8 LibGit2Sharp/Changes.cs
@@ -17,17 +17,17 @@ internal void AppendToPatch(string patch)
/// <summary>
/// The number of lines added.
/// </summary>
- public int LinesAdded { get; internal set; }
+ public virtual int LinesAdded { get; internal set; }
/// <summary>
/// The number of lines deleted.
/// </summary>
- public int LinesDeleted { get; internal set; }
+ public virtual int LinesDeleted { get; internal set; }
/// <summary>
/// The patch corresponding to these changes.
/// </summary>
- public string Patch
+ public virtual string Patch
{
get { return patchBuilder.ToString(); }
}
@@ -35,6 +35,6 @@ public string Patch
/// <summary>
/// Determines if at least one side of the comparison holds binary content.
/// </summary>
- public bool IsBinaryComparison { get; protected set; }
+ public virtual bool IsBinaryComparison { get; protected set; }
}
}
View
26 LibGit2Sharp/Commit.cs
@@ -17,6 +17,12 @@ public class Commit : GitObject
private readonly Lazy<string> shortMessage;
private readonly Lazy<IEnumerable<Note>> notes;
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected Commit()
+ { }
+
internal Commit(ObjectId id, ObjectId treeId, Repository repo)
: base(id)
{
@@ -32,7 +38,7 @@ internal Commit(ObjectId id, ObjectId treeId, Repository repo)
/// </summary>
/// <param name = "relativePath">The relative path to the <see cref = "TreeEntry" /> from the <see cref = "Commit" /> working directory.</param>
/// <returns><c>null</c> if nothing has been found, the <see cref = "TreeEntry" /> otherwise.</returns>
- public TreeEntry this[string relativePath]
+ public virtual TreeEntry this[string relativePath]
{
get { return Tree[relativePath]; }
}
@@ -40,12 +46,12 @@ internal Commit(ObjectId id, ObjectId treeId, Repository repo)
/// <summary>
/// Gets the commit message.
/// </summary>
- public string Message { get; private set; }
+ public virtual string Message { get; private set; }
/// <summary>
/// Gets the short commit message which is usually the first line of the commit.
/// </summary>
- public string MessageShort
+ public virtual string MessageShort
{
get { return shortMessage.Value; }
}
@@ -63,22 +69,22 @@ private string ExtractShortMessage()
/// <summary>
/// Gets the encoding of the message.
/// </summary>
- public string Encoding { get; private set; }
+ public virtual string Encoding { get; private set; }
/// <summary>
/// Gets the author of this commit.
/// </summary>
- public Signature Author { get; private set; }
+ public virtual Signature Author { get; private set; }
/// <summary>
/// Gets the committer.
/// </summary>
- public Signature Committer { get; private set; }
+ public virtual Signature Committer { get; private set; }
/// <summary>
/// Gets the Tree associated to this commit.
/// </summary>
- public Tree Tree
+ public virtual Tree Tree
{
get { return tree.Value; }
}
@@ -86,7 +92,7 @@ public Tree Tree
/// <summary>
/// Gets the parents of this commit. This property is lazy loaded and can throw an exception if the commit no longer exists in the repo.
/// </summary>
- public IEnumerable<Commit> Parents
+ public virtual IEnumerable<Commit> Parents
{
get { return parents.Value; }
}
@@ -94,7 +100,7 @@ public IEnumerable<Commit> Parents
/// <summary>
/// Gets The count of parent commits.
/// </summary>
- public int ParentsCount
+ public virtual int ParentsCount
{
get
{
@@ -108,7 +114,7 @@ public int ParentsCount
/// <summary>
/// Gets the notes of this commit.
/// </summary>
- public IEnumerable<Note> Notes
+ public virtual IEnumerable<Note> Notes
{
get { return notes.Value; }
}
View
17 LibGit2Sharp/CommitLog.cs
@@ -19,6 +19,12 @@ public class CommitLog : IQueryableCommitLog
private readonly GitSortOptions sortOptions;
/// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected CommitLog()
+ { }
+
+ /// <summary>
/// Initializes a new instance of the <see cref = "CommitLog" /> class.
/// The commits will be enumerated according in reverse chronological order.
/// </summary>
@@ -42,7 +48,7 @@ internal CommitLog(Repository repo, GitSortOptions sortingStrategy)
/// <summary>
/// Gets the current sorting strategy applied when enumerating the log
/// </summary>
- public GitSortOptions SortedBy
+ public virtual GitSortOptions SortedBy
{
get { return sortOptions; }
}
@@ -53,7 +59,7 @@ public GitSortOptions SortedBy
/// Returns an enumerator that iterates through the log.
/// </summary>
/// <returns>An <see cref = "IEnumerator{T}" /> object that can be used to iterate through the log.</returns>
- public IEnumerator<Commit> GetEnumerator()
+ public virtual IEnumerator<Commit> GetEnumerator()
{
if ((repo.Info.IsEmpty) && includedIdentifier.Any(o => PointsAtTheHead(o.ToString()))) // TODO: ToString() == fragile
{
@@ -79,7 +85,7 @@ IEnumerator IEnumerable.GetEnumerator()
/// </summary>
/// <param name = "filter">The options used to control which commits will be returned.</param>
/// <returns>A list of commits, ready to be enumerated.</returns>
- public ICommitLog QueryBy(Filter filter)
+ public virtual ICommitLog QueryBy(Filter filter)
{
Ensure.ArgumentNotNull(filter, "filter");
Ensure.ArgumentNotNull(filter.Since, "filter.Since");
@@ -130,7 +136,7 @@ private static bool PointsAtTheHead(string shaOrRefName)
/// <param name = "first">The first <see cref = "Commit"/>.</param>
/// <param name = "second">The second <see cref = "Commit"/>.</param>
/// <returns>The common ancestor or null if none found.</returns>
- public Commit FindCommonAncestor(Commit first, Commit second)
+ public virtual Commit FindCommonAncestor(Commit first, Commit second)
{
Ensure.ArgumentNotNull(first, "first");
Ensure.ArgumentNotNull(second, "second");
@@ -157,9 +163,10 @@ public Commit FindCommonAncestor(Commit first, Commit second)
/// </summary>
/// <param name = "commits">The <see cref = "Commit"/>s for which to find the common ancestor.</param>
/// <returns>The common ancestor or null if none found.</returns>
- public Commit FindCommonAncestor(IEnumerable<Commit> commits)
+ public virtual Commit FindCommonAncestor(IEnumerable<Commit> commits)
{
Ensure.ArgumentNotNull(commits, "commits");
+
Commit ret = null;
int count = 0;
View
22 LibGit2Sharp/Configuration.cs
@@ -21,6 +21,12 @@ public class Configuration : IDisposable
private ConfigurationSafeHandle globalHandle;
private ConfigurationSafeHandle localHandle;
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected Configuration()
+ { }
+
internal Configuration(Repository repository, string globalConfigurationFileLocation, string systemConfigurationFileLocation)
{
this.repository = repository;
@@ -90,7 +96,7 @@ private bool HasLocalConfig
/// <summary>
/// Determines if a Git configuration file specific to the current interactive user has been found.
/// </summary>
- public bool HasGlobalConfig
+ public virtual bool HasGlobalConfig
{
get { return globalConfigPath != null; }
}
@@ -98,7 +104,7 @@ public bool HasGlobalConfig
/// <summary>
/// Determines if a system-wide Git configuration file has been found.
/// </summary>
- public bool HasSystemConfig
+ public virtual bool HasSystemConfig
{
get { return systemConfigPath != null; }
}
@@ -143,7 +149,7 @@ public void Dispose()
/// </summary>
/// <param name = "key">The key to unset.</param>
/// <param name = "level">The configuration file which should be considered as the target of this operation</param>
- public void Unset(string key, ConfigurationLevel level = ConfigurationLevel.Local)
+ public virtual void Unset(string key, ConfigurationLevel level = ConfigurationLevel.Local)
{
ConfigurationSafeHandle h = RetrieveConfigurationHandle(level);
@@ -200,7 +206,7 @@ protected virtual void Dispose(bool disposing)
/// <param name = "key">The key</param>
/// <param name = "defaultValue">The default value</param>
/// <returns>The configuration value, or <c>defaultValue</c> if not set</returns>
- public T Get<T>(string key, T defaultValue)
+ public virtual T Get<T>(string key, T defaultValue)
{
Ensure.ArgumentNotNullOrEmptyString(key, "key");
@@ -240,7 +246,7 @@ public T Get<T>(string key, T defaultValue)
/// <param name = "secondKeyPart">The second key part</param>
/// <param name = "defaultValue">The default value</param>
/// <returns>The configuration value, or <c>defaultValue</c> if not set</returns>
- public T Get<T>(string firstKeyPart, string secondKeyPart, T defaultValue)
+ public virtual T Get<T>(string firstKeyPart, string secondKeyPart, T defaultValue)
{
Ensure.ArgumentNotNull(firstKeyPart, "firstKeyPart");
Ensure.ArgumentNotNull(secondKeyPart, "secondKeyPart");
@@ -271,7 +277,7 @@ public T Get<T>(string firstKeyPart, string secondKeyPart, T defaultValue)
/// <param name = "thirdKeyPart">The third key part</param>
/// <param name = "defaultValue">The default value</param>
/// <returns>The configuration value, or <c>defaultValue</c> if not set</returns>
- public T Get<T>(string firstKeyPart, string secondKeyPart, string thirdKeyPart, T defaultValue)
+ public virtual T Get<T>(string firstKeyPart, string secondKeyPart, string thirdKeyPart, T defaultValue)
{
Ensure.ArgumentNotNull(firstKeyPart, "firstKeyPart");
Ensure.ArgumentNotNull(secondKeyPart, "secondKeyPart");
@@ -301,7 +307,7 @@ public T Get<T>(string firstKeyPart, string secondKeyPart, string thirdKeyPart,
/// <param name = "keyParts">The key parts</param>
/// <param name = "defaultValue">The default value</param>
/// <returns>The configuration value, or <c>defaultValue</c> if not set</returns>
- public T Get<T>(string[] keyParts, T defaultValue)
+ public virtual T Get<T>(string[] keyParts, T defaultValue)
{
Ensure.ArgumentNotNull(keyParts, "keyParts");
@@ -331,7 +337,7 @@ private void Save()
/// <param name = "key">The key parts</param>
/// <param name = "value">The default value</param>
/// <param name = "level">The configuration file which should be considered as the target of this operation</param>
- public void Set<T>(string key, T value, ConfigurationLevel level = ConfigurationLevel.Local)
+ public virtual void Set<T>(string key, T value, ConfigurationLevel level = ConfigurationLevel.Local)
{
Ensure.ArgumentNotNullOrEmptyString(key, "key");
View
6 LibGit2Sharp/ContentChanges.cs
@@ -9,6 +9,12 @@ namespace LibGit2Sharp
/// </summary>
public class ContentChanges : Changes
{
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected ContentChanges()
+ { }
+
internal ContentChanges(Repository repo, Blob oldBlob, Blob newBlob, GitDiffOptions options)
{
using (var osw1 = new ObjectSafeWrapper(oldBlob.Id, repo))
View
2  LibGit2Sharp/Core/GitDiff.cs
@@ -106,9 +106,9 @@ internal class GitDiffFile
{
public GitOid Oid;
public IntPtr Path;
- public ushort Mode;
public long Size;
public GitDiffFileFlags Flags;
+ public ushort Mode;
}
[StructLayout(LayoutKind.Sequential)]
View
3  LibGit2Sharp/Core/Handles/SafeHandleBase.cs
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
+using System.Globalization;
using System.Runtime.InteropServices;
namespace LibGit2Sharp.Core.Handles
@@ -23,7 +24,7 @@ protected override void Dispose(bool disposing)
#if DEBUG
if (!disposing && !IsInvalid)
{
- Trace.WriteLine(string.Format("A {0} handle wrapper has not been properly disposed.", GetType().Name));
+ Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "A {0} handle wrapper has not been properly disposed.", GetType().Name));
#if LEAKS
Trace.WriteLine(trace);
#endif
View
29 LibGit2Sharp/Core/NativeMethods.cs
@@ -80,6 +80,19 @@ public static bool RepositoryStateChecker(RepositorySafeHandle repositoryPtr, Fu
RepositorySafeHandle repo,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath path);
+ internal delegate int source_callback(
+ IntPtr content,
+ int max_length,
+ IntPtr data);
+
+ [DllImport(libgit2)]
+ public static extern int git_blob_create_fromchunks(
+ ref GitOid oid,
+ RepositorySafeHandle repositoryPtr,
+ [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath hintpath,
+ source_callback fileCallback,
+ IntPtr data);
+
[DllImport(libgit2)]
public static extern IntPtr git_blob_rawcontent(GitObjectSafeHandle blob);
@@ -350,6 +363,13 @@ public static bool RepositoryStateChecker(RepositorySafeHandle repositoryPtr, Fu
GitObjectSafeHandle two);
[DllImport(libgit2)]
+ public static extern int git_message_prettify(
+ byte[] message_out, // NB: This is more properly a StringBuilder, but it's UTF8
+ int buffer_size,
+ string message,
+ bool strip_comments);
+
+ [DllImport(libgit2)]
public static extern int git_note_create(
out GitOid noteOid,
RepositorySafeHandle repo,
@@ -497,6 +517,13 @@ public static bool RepositoryStateChecker(RepositorySafeHandle repositoryPtr, Fu
public static extern string git_remote_name(RemoteSafeHandle remote);
[DllImport(libgit2)]
+ public static extern int git_remote_add(
+ out RemoteSafeHandle remote,
+ RepositorySafeHandle repo,
+ [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string name,
+ [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string url);
+
+ [DllImport(libgit2)]
public static extern int git_remote_new(
out RemoteSafeHandle remote,
RepositorySafeHandle repo,
@@ -719,6 +746,6 @@ public static bool RepositoryStateChecker(RepositorySafeHandle repositoryPtr, Fu
public static extern int git_treebuilder_write(out GitOid oid, RepositorySafeHandle repo, TreeBuilderSafeHandle bld);
[DllImport(libgit2)]
- public static extern int git_treebuilder_free(IntPtr bld);
+ public static extern void git_treebuilder_free(IntPtr bld);
}
}
View
3  LibGit2Sharp/Core/UnSafeNativeMethods.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices;
using LibGit2Sharp.Core.Handles;
namespace LibGit2Sharp.Core
View
4 LibGit2Sharp/Core/Utf8Marshaler.cs
@@ -31,7 +31,7 @@ public virtual IntPtr MarshalManagedToNative(object managedObj)
return StringToNative((string)managedObj);
}
- protected unsafe IntPtr StringToNative(string value)
+ protected static unsafe IntPtr StringToNative(string value)
{
// not null terminated
byte[] strbuf = Encoding.UTF8.GetBytes(value);
@@ -50,7 +50,7 @@ public virtual object MarshalNativeToManaged(IntPtr pNativeData)
return NativeToString(pNativeData);
}
- protected unsafe string NativeToString(IntPtr pNativeData)
+ protected static unsafe string NativeToString(IntPtr pNativeData)
{
var walk = (byte*)pNativeData;
View
2  LibGit2Sharp/CustomDictionary.xml
@@ -8,6 +8,8 @@
<Word>sha</Word>
<Word>unstage</Word>
<Word>unstaged</Word>
+ <Word>compat</Word>
+ <Word>oid</Word>
</Recognized>
<Deprecated>
<Term PreferredAlternate=""></Term>
View
87 LibGit2Sharp/Diff.cs
@@ -50,6 +50,12 @@ private static FilePath[] ToFilePaths(IEnumerable<string> paths)
return filePaths.ToArray();
}
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected Diff()
+ { }
+
internal Diff(Repository repo)
{
this.repo = repo;
@@ -62,8 +68,11 @@ internal Diff(Repository repo)
/// <param name = "newTree">The <see cref = "Tree"/> you want to compare to.</param>
/// <param name = "paths">The list of paths (either files or directories) that should be compared.</param>
/// <returns>A <see cref = "TreeChanges"/> containing the changes between the <paramref name = "oldTree"/> and the <paramref name = "newTree"/>.</returns>
- public TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable<string> paths = null)
+ public virtual TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable<string> paths = null)
{
+ Ensure.ArgumentNotNull(oldTree, "oldTree");
+ Ensure.ArgumentNotNull(oldTree, "newTree");
+
using(GitDiffOptions options = BuildOptions(paths))
using (DiffListSafeHandle diff = BuildDiffListFromTrees(oldTree.Id, newTree.Id, options))
{
@@ -89,7 +98,7 @@ private DiffListSafeHandle BuildDiffListFromTrees(ObjectId oldTree, ObjectId new
/// <param name = "oldBlob">The <see cref = "Blob"/> you want to compare from.</param>
/// <param name = "newBlob">The <see cref = "Blob"/> you want to compare to.</param>
/// <returns>A <see cref = "ContentChanges"/> containing the changes between the <paramref name = "oldBlob"/> and the <paramref name = "newBlob"/>.</returns>
- public ContentChanges Compare(Blob oldBlob, Blob newBlob)
+ public virtual ContentChanges Compare(Blob oldBlob, Blob newBlob)
{
using (GitDiffOptions options = BuildOptions())
{
@@ -104,6 +113,8 @@ public ContentChanges Compare(Blob oldBlob, Blob newBlob)
return new Dictionary<DiffTarget, Func<Repository, TreeComparisonHandleRetriever>>
{
{ DiffTarget.Index, r => IndexToTree(r) },
+ { DiffTarget.WorkingDirectory, r => WorkdirToTree(r) },
+ { DiffTarget.BothWorkingDirectoryAndIndex, r => WorkdirAndIndexToTree(r) },
};
}
@@ -114,8 +125,10 @@ public ContentChanges Compare(Blob oldBlob, Blob newBlob)
/// <param name = "diffTarget">The target to compare to.</param>
/// <param name = "paths">The list of paths (either files or directories) that should be compared.</param>
/// <returns>A <see cref = "TreeChanges"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns>
- public TreeChanges Compare(Tree oldTree, DiffTarget diffTarget, IEnumerable<string> paths = null)
+ public virtual TreeChanges Compare(Tree oldTree, DiffTarget diffTarget, IEnumerable<string> paths = null)
{
+ Ensure.ArgumentNotNull(oldTree, "oldTree");
+
var comparer = handleRetrieverDispatcher[diffTarget](repo);
using (GitDiffOptions options = BuildOptions(paths))
@@ -125,8 +138,76 @@ public TreeChanges Compare(Tree oldTree, DiffTarget diffTarget, IEnumerable<stri
}
}
+ /// <summary>
+ /// Show changes between the working directory and the index.
+ /// </summary>
+ /// <param name = "paths">The list of paths (either files or directories) that should be compared.</param>
+ /// <returns>A <see cref = "TreeChanges"/> containing the changes between the working directory and the index.</returns>
+ public virtual TreeChanges Compare(IEnumerable<string> paths = null)
+ {
+ var comparer = WorkdirToIndex(repo);
+
+ using (GitDiffOptions options = BuildOptions(paths))
+ using (DiffListSafeHandle dl = BuildDiffListFromComparer(null, comparer, options))
+ {
+ return new TreeChanges(dl);
+ }
+ }
+
private delegate DiffListSafeHandle TreeComparisonHandleRetriever(GitObjectSafeHandle treeHandle, GitDiffOptions options);
+ private static TreeComparisonHandleRetriever WorkdirToIndex(Repository repo)
+ {
+ TreeComparisonHandleRetriever comparisonHandleRetriever = (h, o) =>
+ {
+ DiffListSafeHandle diff;
+ Ensure.Success(NativeMethods.git_diff_workdir_to_index(repo.Handle, o, out diff));
+ return diff;
+ };
+
+ return comparisonHandleRetriever;
+ }
+
+ private static TreeComparisonHandleRetriever WorkdirToTree(Repository repo)
+ {
+ TreeComparisonHandleRetriever comparisonHandleRetriever = (h, o) =>
+ {
+ DiffListSafeHandle diff;
+ Ensure.Success(NativeMethods.git_diff_workdir_to_tree(repo.Handle, o, h, out diff));
+ return diff;
+ };
+
+ return comparisonHandleRetriever;
+ }
+
+ private static TreeComparisonHandleRetriever WorkdirAndIndexToTree(Repository repo)
+ {
+ TreeComparisonHandleRetriever comparisonHandleRetriever = (h, o) =>
+ {
+ DiffListSafeHandle diff = null, diff2 = null;
+
+ try
+ {
+ Ensure.Success(NativeMethods.git_diff_index_to_tree(repo.Handle, o, h, out diff));
+ Ensure.Success(NativeMethods.git_diff_workdir_to_index(repo.Handle, o, out diff2));
+ Ensure.Success(NativeMethods.git_diff_merge(diff, diff2));
+ }
+ catch
+ {
+ diff.SafeDispose();
+ throw;
+ }
+ finally
+ {
+ diff2.SafeDispose();
+ }
+
+ return diff;
+ };
+
+ return comparisonHandleRetriever;
+ }
+
private static TreeComparisonHandleRetriever IndexToTree(Repository repo)
{
TreeComparisonHandleRetriever comparisonHandleRetriever = (h, o) =>
View
12 LibGit2Sharp/DiffTarget.cs
@@ -1,13 +1,23 @@
namespace LibGit2Sharp
{
/// <summary>
- /// The target for a diff comparison.
+ /// The target of a Tree based diff comparison.
/// </summary>
public enum DiffTarget
{
/// <summary>
+ /// The working directory.
+ /// </summary>
+ WorkingDirectory,
+
+ /// <summary>
/// The repository index.
/// </summary>
Index,
+
+ /// <summary>
+ /// Both the working directory and the repository index.
+ /// </summary>
+ BothWorkingDirectoryAndIndex,
}
}
View
8 LibGit2Sharp/DirectReference.cs
@@ -9,6 +9,12 @@ public class DirectReference : Reference
{
private readonly Lazy<GitObject> targetBuilder;
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected DirectReference()
+ { }
+
internal DirectReference(Lazy<GitObject> targetBuilder)
{
this.targetBuilder = targetBuilder;
@@ -17,7 +23,7 @@ internal DirectReference(Lazy<GitObject> targetBuilder)
/// <summary>
/// Gets the target of this <see cref = "DirectReference" />
/// </summary>
- public GitObject Target
+ public virtual GitObject Target
{
get { return targetBuilder.Value; }
}
View
10 LibGit2Sharp/GitObject.cs
@@ -24,6 +24,12 @@ public class GitObject : IEquatable<GitObject>
new LambdaEqualityHelper<GitObject>(new Func<GitObject, object>[] { x => x.Id });
/// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected GitObject()
+ { }
+
+ /// <summary>
/// Initializes a new instance of the <see cref = "GitObject" /> class.
/// </summary>
/// <param name = "id">The <see cref = "ObjectId" /> it should be identified by.</param>
@@ -35,12 +41,12 @@ protected GitObject(ObjectId id)
/// <summary>
/// Gets the id of this object
/// </summary>
- public ObjectId Id { get; private set; }
+ public virtual ObjectId Id { get; private set; }
/// <summary>
/// Gets the 40 character sha1 of this object.
/// </summary>
- public string Sha
+ public virtual string Sha
{
get { return Id.Sha; }
}
View
104 LibGit2Sharp/IRepository.cs
@@ -0,0 +1,104 @@
+using System;
+
+namespace LibGit2Sharp
+{
+ /// <summary>
+ /// A Repository is the primary interface into a git repository
+ /// </summary>
+ public interface IRepository : IDisposable
+ {
+ /// <summary>
+ /// Shortcut to return the branch pointed to by HEAD
+ /// </summary>
+ /// <returns></returns>
+ Branch Head { get; }
+
+ /// <summary>
+ /// Provides access to the configuration settings for this repository.
+ /// </summary>
+ Configuration Config { get; }
+
+ /// <summary>
+ /// Gets the index.
+ /// </summary>
+ Index Index { get; }
+
+ /// <summary>
+ /// Lookup and enumerate references in the repository.
+ /// </summary>
+ ReferenceCollection Refs { get; }
+
+ /// <summary>
+ /// Lookup and manage remotes in the repository.
+ /// </summary>
+ RemoteCollection Remotes { get; }
+
+ /// <summary>
+ /// Lookup and enumerate commits in the repository.
+ /// Iterating this collection directly starts walking from the HEAD.
+ /// </summary>
+ IQueryableCommitLog Commits { get; }
+
+ /// <summary>
+ /// Lookup and enumerate branches in the repository.
+ /// </summary>
+ BranchCollection Branches { get; }
+
+ /// <summary>
+ /// Lookup and enumerate tags in the repository.
+ /// </summary>
+ TagCollection Tags { get; }
+
+ /// <summary>
+ /// Provides high level information about this repository.
+ /// </summary>
+ RepositoryInformation Info { get; }
+
+ /// <summary>
+ /// Provides access to diffing functionalities to show changes between the working tree and the index or a tree, changes between the index and a tree, changes between two trees, or changes between two files on disk.
+ /// </summary>
+ Diff Diff {get;}
+
+ /// <summary>
+ /// Checkout the specified branch.
+ /// </summary>
+ /// <param name="branch">The branch to checkout.</param>
+ /// <returns>The branch.</returns>
+ Branch Checkout(Branch branch);
+
+ /// <summary>
+ /// Checkout the specified branch, reference or SHA.
+ /// </summary>
+ /// <param name = "shaOrReferenceName">The sha of the commit, a canonical reference name or the name of the branch to checkout.</param>
+ /// <returns>The new HEAD.</returns>
+ Branch Checkout(string shaOrReferenceName);
+
+ /// <summary>
+ /// Try to lookup an object by its <see cref = "ObjectId" /> and <see cref = "GitObjectType" />. If no matching object is found, null will be returned.
+ /// </summary>
+ /// <param name = "id">The id to lookup.</param>
+ /// <param name = "type">The kind of GitObject being looked up</param>
+ /// <returns>The <see cref = "GitObject" /> or null if it was not found.</returns>
+ GitObject Lookup(ObjectId id, GitObjectType type = GitObjectType.Any);
+
+ /// <summary>
+ /// Try to lookup an object by its sha or a reference canonical name and <see cref = "GitObjectType" />. If no matching object is found, null will be returned.
+ /// </summary>
+ /// <param name = "shaOrReferenceName">The sha or reference canonical name to lookup.</param>
+ /// <param name = "type">The kind of <see cref = "GitObject" /> being looked up</param>
+ /// <returns>The <see cref = "GitObject" /> or null if it was not found.</returns>
+ GitObject Lookup(string shaOrReferenceName, GitObjectType type = GitObjectType.Any);
+
+ /// <summary>
+ /// Stores the content of the <see cref = "Repository.Index" /> as a new <see cref = "Commit" /> into the repository.
+ /// The tip of the <see cref = "Repository.Head"/> will be used as the parent of this new Commit.
+ /// Once the commit is created, the <see cref = "Repository.Head"/> will move forward to point at it.
+ /// </summary>
+ /// <param name = "message">The description of why a change was made to the repository.</param>
+ /// <param name = "author">The <see cref = "Signature" /> of who made the change.</param>
+ /// <param name = "committer">The <see cref = "Signature" /> of who added the change to the repository.</param>
+ /// <param name = "amendPreviousCommit">True to amend the current <see cref = "Commit"/> pointed at by <see cref = "Repository.Head"/>, false otherwise.</param>
+ /// <returns>The generated <see cref = "Commit" />.</returns>
+ Commit Commit(string message, Signature author, Signature committer, bool amendPreviousCommit = false);
+ }
+}
View
42 LibGit2Sharp/Index.cs
@@ -19,6 +19,12 @@ public class Index : IEnumerable<IndexEntry>
private readonly IndexSafeHandle handle;
private readonly Repository repo;
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected Index()
+ { }
+
internal Index(Repository repo)
{
this.repo = repo;
@@ -46,7 +52,7 @@ internal IndexSafeHandle Handle
/// <summary>
/// Gets the number of <see cref = "IndexEntry" /> in the index.
/// </summary>
- public int Count
+ public virtual int Count
{
get { return (int)NativeMethods.git_index_entrycount(handle); }
}
@@ -54,7 +60,7 @@ public int Count
/// <summary>
/// Gets the <see cref = "IndexEntry" /> with the specified relative path.
/// </summary>
- public IndexEntry this[string path]
+ public virtual IndexEntry this[string path]
{
get
{
@@ -88,7 +94,7 @@ public int Count
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>An <see cref = "IEnumerator{T}" /> object that can be used to iterate through the collection.</returns>
- public IEnumerator<IndexEntry> GetEnumerator()
+ public virtual IEnumerator<IndexEntry> GetEnumerator()
{
for (uint i = 0; i < Count; i++)
{
@@ -111,7 +117,7 @@ IEnumerator IEnumerable.GetEnumerator()
/// Promotes to the staging area the latest modifications of a file in the working directory (addition, updation or removal).
/// </summary>
/// <param name = "path">The path of the file within the working directory.</param>
- public void Stage(string path)
+ public virtual void Stage(string path)
{
Ensure.ArgumentNotNull(path, "path");
@@ -122,12 +128,12 @@ public void Stage(string path)
/// Promotes to the staging area the latest modifications of a collection of files in the working directory (addition, updation or removal).
/// </summary>
/// <param name = "paths">The collection of paths of the files within the working directory.</param>
- public void Stage(IEnumerable<string> paths)
+ public virtual void Stage(IEnumerable<string> paths)
{
//TODO: Stage() should support following use cases:
// - Recursively staging the content of a directory
- IDictionary<string, FileStatus> batch = PrepareBatch(paths);
+ IEnumerable<KeyValuePair<string, FileStatus>> batch = PrepareBatch(paths);
foreach (KeyValuePair<string, FileStatus> kvp in batch)
{
@@ -166,7 +172,7 @@ public void Stage(IEnumerable<string> paths)
/// Removes from the staging area all the modifications of a file since the latest commit (addition, updation or removal).
/// </summary>
/// <param name = "path">The path of the file within the working directory.</param>
- public void Unstage(string path)
+ public virtual void Unstage(string path)
{
Ensure.ArgumentNotNull(path, "path");
@@ -177,7 +183,7 @@ public void Unstage(string path)
/// Removes from the staging area all the modifications of a collection of file since the latest commit (addition, updation or removal).
/// </summary>
/// <param name = "paths">The collection of paths of the files within the working directory.</param>
- public void Unstage(IEnumerable<string> paths)
+ public virtual void Unstage(IEnumerable<string> paths)
{
repo.Reset("HEAD", paths);
}
@@ -187,7 +193,7 @@ public void Unstage(IEnumerable<string> paths)
/// </summary>
/// <param name = "sourcePath">The path of the file within the working directory which has to be moved/renamed.</param>
/// <param name = "destinationPath">The target path of the file within the working directory.</param>
- public void Move(string sourcePath, string destinationPath)
+ public virtual void Move(string sourcePath, string destinationPath)
{
Move(new[] { sourcePath }, new[] { destinationPath });
}
@@ -197,7 +203,7 @@ public void Move(string sourcePath, string destinationPath)
/// </summary>
/// <param name = "sourcePaths">The paths of the files within the working directory which have to be moved/renamed.</param>
/// <param name = "destinationPaths">The target paths of the files within the working directory.</param>
- public void Move(IEnumerable<string> sourcePaths, IEnumerable<string> destinationPaths)
+ public virtual void Move(IEnumerable<string> sourcePaths, IEnumerable<string> destinationPaths)
{
Ensure.ArgumentNotNull(sourcePaths, "sourcePaths");
Ensure.ArgumentNotNull(destinationPaths, "destinationPaths");
@@ -263,7 +269,7 @@ public void Move(IEnumerable<string> sourcePaths, IEnumerable<string> destinatio
/// </para>
/// </summary>
/// <param name = "path">The path of the file within the working directory.</param>
- public void Remove(string path)
+ public virtual void Remove(string path)
{
Ensure.ArgumentNotNull(path, "path");
@@ -278,12 +284,12 @@ public void Remove(string path)
/// </para>
/// </summary>
/// <param name = "paths">The collection of paths of the files within the working directory.</param>
- public void Remove(IEnumerable<string> paths)
+ public virtual void Remove(IEnumerable<string> paths)
{
//TODO: Remove() should support following use cases:
// - Removing a directory and its content
- IDictionary<string, FileStatus> batch = PrepareBatch(paths);
+ IEnumerable<KeyValuePair<string, FileStatus>> batch = PrepareBatch(paths);
foreach (KeyValuePair<string, FileStatus> keyValuePair in batch)
{
@@ -314,7 +320,7 @@ public void Remove(IEnumerable<string> paths)
UpdatePhysicalIndex();
}
- private IDictionary<string, FileStatus> PrepareBatch(IEnumerable<string> paths)
+ private IEnumerable<KeyValuePair<string, FileStatus>> PrepareBatch(IEnumerable<string> paths)
{
Ensure.ArgumentNotNull(paths, "paths");
@@ -364,7 +370,7 @@ public void Remove(IEnumerable<string> paths)
return new Tuple<string, FileStatus>(relativePath, RetrieveStatus(relativePath));
}
- private bool Enumerate(IEnumerator<string> leftEnum, IEnumerator<string> rightEnum)
+ private static bool Enumerate(IEnumerator<string> leftEnum, IEnumerator<string> rightEnum)
{
bool isLeftEoF = leftEnum.MoveNext();
bool isRightEoF = rightEnum.MoveNext();
@@ -423,7 +429,7 @@ private static string BuildRelativePathFrom(Repository repo, string path)
/// </summary>
/// <param name = "filePath">The relative path within the working directory to the file.</param>
/// <returns>A <see cref = "FileStatus" /> representing the state of the <paramref name = "filePath" /> parameter.</returns>
- public FileStatus RetrieveStatus(string filePath)
+ public virtual FileStatus RetrieveStatus(string filePath)
{
Ensure.ArgumentNotNullOrEmptyString(filePath, "filePath");
@@ -446,7 +452,7 @@ public FileStatus RetrieveStatus(string filePath)
/// Retrieves the state of all files in the working directory, comparing them against the staging area and the latest commmit.
/// </summary>
/// <returns>A <see cref = "RepositoryStatus" /> holding the state of all the files.</returns>
- public RepositoryStatus RetrieveStatus()
+ public virtual RepositoryStatus RetrieveStatus()
{
return new RepositoryStatus(repo);
}
@@ -478,7 +484,7 @@ internal void Reset(TreeChanges changes)
continue;
default:
- throw new InvalidOperationException(string.Format("Entry '{0}' bears an unexpected ChangeKind '{1}'", treeEntryChanges.Path, treeEntryChanges.Status));
+ throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Entry '{0}' bears an unexpected ChangeKind '{1}'", treeEntryChanges.Path, treeEntryChanges.Status));
}
}
View
2  LibGit2Sharp/LibGit2Sharp.csproj
@@ -57,6 +57,7 @@
<ItemGroup>
<Compile Include="AbbreviatedObjectId.cs" />
<Compile Include="Blob.cs" />
+ <Compile Include="BlobExtensions.cs" />
<Compile Include="Branch.cs" />
<Compile Include="BranchCollection.cs" />
<Compile Include="Changes.cs" />
@@ -96,6 +97,7 @@
<Compile Include="DetachedHead.cs" />
<Compile Include="Diff.cs" />
<Compile Include="DiffTarget.cs" />
+ <Compile Include="IRepository.cs" />
<Compile Include="NoteCollection.cs" />
<Compile Include="Note.cs" />
<Compile Include="TreeChanges.cs" />
View
2  LibGit2Sharp/Mode.cs
@@ -25,7 +25,7 @@ public enum Mode
/// <summary>
/// 100664 file mode
/// </summary>
- NonExecutableGroupWriteableFile = 0x81B4,
+ NonExecutableGroupWritableFile = 0x81B4,
/// <summary>
/// 100755 file mode
View
18 LibGit2Sharp/Note.cs
@@ -7,8 +7,14 @@ namespace LibGit2Sharp
/// <summary>
/// A note, attached to a given <see cref = "GitObject"/>.
/// </summary>
- public class Note
+ public class Note : IEquatable<Note>
{
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected Note()
+ { }
+
private Note(ObjectId blobId, string message, ObjectId targetObjectId, string @namespace)
{
BlobId = blobId;
@@ -20,25 +26,25 @@ private Note(ObjectId blobId, string message, ObjectId targetObjectId, string @n
/// <summary>
/// The <see cref = "ObjectId"/> of the blob containing the note message.
/// </summary>
- public ObjectId BlobId { get; private set; }
+ public virtual ObjectId BlobId { get; private set; }
/// <summary>
/// The message.
/// </summary>
- public string Message { get; private set; }
+ public virtual string Message { get; private set; }
/// <summary>
/// The namespace with which this note is associated.
/// <para>This is the abbreviated namespace (e.g.: commits), and not the canonical namespace (e.g.: refs/notes/commits).</para>
/// </summary>
- public string Namespace { get; private set; }
+ public virtual string Namespace { get; private set; }
/// <summary>
/// The <see cref = "ObjectId"/> of the target object.
/// </summary>
- public ObjectId TargetObjectId { get; private set; }
+ public virtual ObjectId TargetObjectId { get; private set; }
- internal static Note BuildFromPtr(Repository repo, string @namespace, ObjectId targetObjectId, NoteSafeHandle note)
+ internal static Note BuildFromPtr(string @namespace, ObjectId targetObjectId, NoteSafeHandle note)
{
ObjectId oid = NativeMethods.git_note_oid(note).MarshalAsObjectId();
string message = NativeMethods.git_note_message(note);
View
30 LibGit2Sharp/NoteCollection.cs
@@ -18,6 +18,12 @@ public class NoteCollection : IEnumerable<Note>
private const string refsNotesPrefix = "refs/notes/";
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected NoteCollection()
+ { }
+
internal NoteCollection(Repository repo)
{
this.repo = repo;
@@ -30,7 +36,7 @@ internal NoteCollection(Repository repo)
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>An <see cref = "IEnumerator{T}" /> object that can be used to iterate through the collection.</returns>
- public IEnumerator<Note> GetEnumerator()
+ public virtual IEnumerator<Note> GetEnumerator()
{
return this[DefaultNamespace].GetEnumerator();
}
@@ -49,7 +55,7 @@ IEnumerator IEnumerable.GetEnumerator()
/// <summary>
/// The default namespace for notes.
/// </summary>
- public string DefaultNamespace
+ public virtual string DefaultNamespace
{
get { return defaultNamespace.Value; }
}
@@ -57,7 +63,7 @@ public string DefaultNamespace
/// <summary>
/// The list of canonicalized namespaces related to notes.
/// </summary>
- public IEnumerable<string> Namespaces
+ public virtual IEnumerable<string> Namespaces
{
get
{
@@ -72,