diff --git a/.travis.yml b/.travis.yml index b0930caa6..f564a6e81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,22 +3,14 @@ language: c -# Make sure CMake is installed +# Make sure CMake and Mono are installed install: - sudo apt-get install cmake mono-devel mono-gmcs # Build libgit2, LibGit2Sharp and run the tests script: - git submodule update --init - - mkdir cmake-build - - LIBGIT2SHA=`cat ./LibGit2Sharp/libgit2_hash.txt` - - SHORTSHA=${LIBGIT2SHA:0:7} - - cd cmake-build - - cmake -DTHREADSAFE=ON -DCMAKE_BUILD_TYPE=Release -DBUILD_CLAR=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=./libgit2-bin -DSONAME_APPEND=$SHORTSHA ../libgit2 - - export LD_LIBRARY_PATH=$PWD/libgit2-bin/lib - - cmake --build . --target install - - cd .. - - xbuild CI-build.msbuild /t:Deploy + - ./build.libgit2sharp.sh # Only watch the development branch branches: diff --git a/CHANGES.md b/CHANGES.md index f8dbc4c32..7537a74e2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,41 @@ - CI server: - @libgit2sharp: +## v0.13.0 - ([diff](https://github.com/libgit2/libgit2sharp/compare/v0.12.0...v0.13.0)) + +### Additions + + - Teach Repository to Checkout paths + - Teach Checkout() to cope with revparse extended syntax leading to references + - Make Stash expose Base, Index and Untracked commits + - Teach Repository.Init() to set up a separate git directory + - Teach checkout to report notifications + - Create a new repo.Checkout() overload which accepts a Commit object + - Allow ObjectDatabase.CreateBlob() to limit the number of bytes to consume + - Make ObjectDatabase.CreateBlob() accept a Stream + - Introduce repo.Refs.RewriteHistory() + - Introduce repo.Refs.ReachableFrom() + - Introduce TreeDefinition.From(Commit) + - Expose TagFetchMode property on Remote type + - Add CopyNativeDependencies.targets + +### Changes + + - Rename CheckoutOptions into CheckoutModifiers + - Rename DiffOptions into DiffModifiers + - Rename StashOptions into StashModifiers + - Rename GitSortOptions into CommitSortStrategies + - Rename Filter into CommitFilter + - Rename ObjectDatabase.CreateTag into ObjectDatabase.CreateTagAnnotation + - Obsolete repo.Clone() overload which returns a Repository + - Obsolete repo.Init() overload which returns a Repository + - Obsolete ObjectDatabase.CreateBlob(BinaryReader, string) + - Update libgit2 binaries to libgit2/libgit2@7940036 + +### Fixes + + - Fetch should respect the remote's configured tagopt setting unless explicitly specified + ## v0.12.0 - ([diff](https://github.com/libgit2/libgit2sharp/compare/v0.11.0...v0.12.0)) ### Additions diff --git a/Lib/NativeBinaries/amd64/git2-7940036.dll b/Lib/NativeBinaries/amd64/git2-7940036.dll new file mode 100644 index 000000000..0b3f720b0 Binary files /dev/null and b/Lib/NativeBinaries/amd64/git2-7940036.dll differ diff --git a/Lib/NativeBinaries/amd64/git2-7940036.pdb b/Lib/NativeBinaries/amd64/git2-7940036.pdb new file mode 100644 index 000000000..eb4d63a22 Binary files /dev/null and b/Lib/NativeBinaries/amd64/git2-7940036.pdb differ diff --git a/Lib/NativeBinaries/amd64/git2-9d9fff3.dll b/Lib/NativeBinaries/amd64/git2-9d9fff3.dll deleted file mode 100644 index 1c4d5f176..000000000 Binary files a/Lib/NativeBinaries/amd64/git2-9d9fff3.dll and /dev/null differ diff --git a/Lib/NativeBinaries/amd64/git2-9d9fff3.pdb b/Lib/NativeBinaries/amd64/git2-9d9fff3.pdb deleted file mode 100644 index 6a8bb33be..000000000 Binary files a/Lib/NativeBinaries/amd64/git2-9d9fff3.pdb and /dev/null differ diff --git a/Lib/NativeBinaries/x86/git2-7940036.dll b/Lib/NativeBinaries/x86/git2-7940036.dll new file mode 100644 index 000000000..29af823e0 Binary files /dev/null and b/Lib/NativeBinaries/x86/git2-7940036.dll differ diff --git a/Lib/NativeBinaries/x86/git2-7940036.pdb b/Lib/NativeBinaries/x86/git2-7940036.pdb new file mode 100644 index 000000000..fad7220d4 Binary files /dev/null and b/Lib/NativeBinaries/x86/git2-7940036.pdb differ diff --git a/Lib/NativeBinaries/x86/git2-9d9fff3.dll b/Lib/NativeBinaries/x86/git2-9d9fff3.dll deleted file mode 100644 index 0c94ac714..000000000 Binary files a/Lib/NativeBinaries/x86/git2-9d9fff3.dll and /dev/null differ diff --git a/Lib/NativeBinaries/x86/git2-9d9fff3.pdb b/Lib/NativeBinaries/x86/git2-9d9fff3.pdb deleted file mode 100644 index 93be3f06b..000000000 Binary files a/Lib/NativeBinaries/x86/git2-9d9fff3.pdb and /dev/null differ diff --git a/LibGit2Sharp.Tests/AttributesFixture.cs b/LibGit2Sharp.Tests/AttributesFixture.cs index df0282b4f..8fea41f33 100644 --- a/LibGit2Sharp.Tests/AttributesFixture.cs +++ b/LibGit2Sharp.Tests/AttributesFixture.cs @@ -1,5 +1,4 @@ -using System.IO; -using System.Text; +using System.Text; using LibGit2Sharp.Tests.TestHelpers; using Xunit; @@ -29,7 +28,7 @@ private static void AssertNormalization(Repository repo, string filename, bool s sb.Append("...are going to be\n"); sb.Append("normalized!\r\n"); - File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, filename), sb.ToString()); + Touch(repo.Info.WorkingDirectory, filename, sb.ToString()); repo.Index.Stage(filename); @@ -46,15 +45,12 @@ private static void AssertNormalization(Repository repo, string filename, bool s private static void CreateAttributesFile(Repository repo) { - const string relativePath = ".gitattributes"; - string fullFilePath = Path.Combine(repo.Info.WorkingDirectory, relativePath); - var sb = new StringBuilder(); sb.Append("* text=auto\n"); sb.Append("*.txt text\n"); sb.Append("*.data binary\n"); - File.WriteAllText(fullFilePath, sb.ToString()); + Touch(repo.Info.WorkingDirectory, ".gitattributes", sb.ToString()); } } } diff --git a/LibGit2Sharp.Tests/BlobFixture.cs b/LibGit2Sharp.Tests/BlobFixture.cs index 42fecf6c5..2e09fad89 100644 --- a/LibGit2Sharp.Tests/BlobFixture.cs +++ b/LibGit2Sharp.Tests/BlobFixture.cs @@ -84,9 +84,9 @@ public static void CopyStream(Stream input, Stream output) [Fact] public void CanStageAFileGeneratedFromABlobContentStream() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (Repository repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { for (int i = 0; i < 5; i++) { diff --git a/LibGit2Sharp.Tests/BranchFixture.cs b/LibGit2Sharp.Tests/BranchFixture.cs index 8208305dd..bb5d6b5e8 100644 --- a/LibGit2Sharp.Tests/BranchFixture.cs +++ b/LibGit2Sharp.Tests/BranchFixture.cs @@ -352,8 +352,9 @@ public void LookingOutABranchByNameWithBadParamsThrows() public void CanGetInformationFromUnbornBranch() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.DirectoryPath, true)) + string repoPath = InitNewRepository(true); + + using (var repo = new Repository(repoPath)) { var head = repo.Head; @@ -518,7 +519,7 @@ public void CanSetUpstreamBranch() Branch trackedBranch = repo.Branches[trackedBranchName]; Branch updatedBranch = repo.Branches.Update(branch, b => b.Remote = remoteName, - b => b.UpstreamBranch = upstreamBranchName); + b => b.UpstreamBranch = upstreamBranchName); // Verify the immutability of the branch. Assert.False(branch.IsTracking); @@ -793,16 +794,20 @@ public void DetachedHeadIsNotATrackingBranch() [Fact] public void TrackedBranchExistsFromDefaultConfigInEmptyClone() { - SelfCleaningDirectory scd1 = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(true); Uri uri; - using (var emptyRepo = Repository.Init(scd1.DirectoryPath, true)) + + using (var emptyRepo = new Repository(repoPath)) { uri = new Uri(emptyRepo.Info.Path); } SelfCleaningDirectory scd2 = BuildSelfCleaningDirectory(); - using (Repository repo = Repository.Clone(uri.AbsoluteUri, scd2.RootedDirectoryPath)) + + string clonedRepoPath = Repository.Clone(uri.AbsoluteUri, scd2.DirectoryPath); + + using (var repo = new Repository(clonedRepoPath)) { Assert.Empty(Directory.GetFiles(scd2.RootedDirectoryPath)); Assert.Equal(repo.Head.Name, "master"); @@ -819,9 +824,9 @@ public void TrackedBranchExistsFromDefaultConfigInEmptyClone() Assert.NotNull(repo.Head.Remote); Assert.Equal("origin", repo.Head.Remote.Name); - File.WriteAllText(Path.Combine(scd2.RootedDirectoryPath, "a.txt"), "a"); + Touch(repo.Info.WorkingDirectory, "a.txt", "a"); repo.Index.Stage("a.txt"); - repo.Commit("A file", DummySignature, DummySignature); + repo.Commit("A file", Constants.Signature, Constants.Signature); Assert.NotNull(repo.Head.Tip); Assert.NotNull(repo.Head.TrackedBranch); diff --git a/LibGit2Sharp.Tests/CheckoutFixture.cs b/LibGit2Sharp.Tests/CheckoutFixture.cs index ebeed6c19..83e883ab1 100644 --- a/LibGit2Sharp.Tests/CheckoutFixture.cs +++ b/LibGit2Sharp.Tests/CheckoutFixture.cs @@ -1,9 +1,9 @@ using System; +using System.IO; using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; using Xunit.Extensions; -using System.IO; namespace LibGit2Sharp.Tests { @@ -94,10 +94,13 @@ public void CanCheckoutAnExistingBranchByName(string branchName) } [Theory] - [InlineData("6dcf9bf")] - [InlineData("refs/tags/lw")] - [InlineData("HEAD~2")] - public void CanCheckoutAnArbitraryCommit(string commitPointer) + [InlineData("6dcf9bf", true, "6dcf9bf")] + [InlineData("refs/tags/lw", true, "refs/tags/lw")] + [InlineData("HEAD~2", true, "HEAD~2")] + [InlineData("6dcf9bf", false, "6dcf9bf7541ee10456529833502442f385010c3d")] + [InlineData("refs/tags/lw", false, "e90810b8df3e80c413d903f631643c716887138d")] + [InlineData("HEAD~2", false, "4c062a6361ae6959e06292c1fa5e2822d9c96345")] + public void CanCheckoutAnArbitraryCommit(string commitPointer, bool checkoutByCommitOrBranchSpec, string expectedReflogTarget) { string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) @@ -110,12 +113,12 @@ public void CanCheckoutAnArbitraryCommit(string commitPointer) Assert.False(repo.Index.RetrieveStatus().IsDirty); - var commitSha = repo.Lookup(commitPointer).Sha; + var commit = repo.Lookup(commitPointer); - Branch detachedHead = repo.Checkout(commitPointer); + Branch detachedHead = checkoutByCommitOrBranchSpec ? repo.Checkout(commitPointer) : repo.Checkout(commit); Assert.Equal(repo.Head, detachedHead); - Assert.Equal(commitSha, detachedHead.Tip.Sha); + Assert.Equal(commit.Sha, detachedHead.Tip.Sha); Assert.True(repo.Head.IsCurrentRepositoryHead); Assert.True(repo.Info.IsHeadDetached); Assert.False(repo.Index.RetrieveStatus().IsDirty); @@ -131,19 +134,19 @@ public void CanCheckoutAnArbitraryCommit(string commitPointer) // Assert reflog entry is created var reflogEntry = repo.Refs.Log(repo.Refs.Head).First(); Assert.Equal(master.Tip.Id, reflogEntry.From); - Assert.Equal(commitSha, reflogEntry.To.Sha); + Assert.Equal(commit.Sha, reflogEntry.To.Sha); Assert.NotNull(reflogEntry.Commiter.Email); Assert.NotNull(reflogEntry.Commiter.Name); - Assert.Equal(string.Format("checkout: moving from master to {0}", commitPointer), reflogEntry.Message); + Assert.Equal(string.Format("checkout: moving from master to {0}", expectedReflogTarget), reflogEntry.Message); } } [Fact] public void CheckoutAddsMissingFilesInWorkingDirectory() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); @@ -167,16 +170,17 @@ public void CheckoutAddsMissingFilesInWorkingDirectory() [Fact] public void CheckoutRemovesExtraFilesInWorkingDirectory() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); // Add extra file in master branch // Verify it is removed after checking out otherBranch. - string newFileFullPath = Path.Combine(repo.Info.WorkingDirectory, "b.txt"); - File.WriteAllText(newFileFullPath, "hello from master branch!\n"); + string newFileFullPath = Touch( + repo.Info.WorkingDirectory, "b.txt", "hello from master branch!\n"); + repo.Index.Stage(newFileFullPath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); @@ -194,16 +198,17 @@ public void CheckoutRemovesExtraFilesInWorkingDirectory() [Fact] public void CheckoutUpdatesModifiedFilesInWorkingDirectory() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); // Modify file in master branch. // Verify contents match initial commit after checking out other branch. - string fullPath = Path.Combine(repo.Info.WorkingDirectory, originalFilePath); - File.WriteAllText(fullPath, "Update : hello from master branch!\n"); + string fullPath = Touch( + repo.Info.WorkingDirectory, originalFilePath, "Update : hello from master branch!\n"); + repo.Index.Stage(fullPath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); @@ -232,7 +237,6 @@ public void CanForcefullyCheckoutWithConflictingStagedChanges() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - string fileFullPath = Path.Combine(repo.Info.WorkingDirectory, originalFilePath); Branch master = repo.Branches["master"]; Assert.True(master.IsCurrentRepositoryHead); @@ -245,24 +249,24 @@ public void CanForcefullyCheckoutWithConflictingStagedChanges() repo.Branches.Add(otherBranchName, master.Tip); // Add change to master. - string fullPath = Path.Combine(repo.Info.WorkingDirectory, fileFullPath); - File.WriteAllText(fullPath, originalFileContent); - repo.Index.Stage(fullPath); + Touch(repo.Info.WorkingDirectory, originalFilePath, originalFileContent); + + repo.Index.Stage(originalFilePath); repo.Commit("change in master", Constants.Signature, Constants.Signature); // Checkout otherBranch. repo.Checkout(otherBranchName); // Add change to otherBranch. - File.WriteAllText(fullPath, alternateFileContent); - repo.Index.Stage(fullPath); + Touch(repo.Info.WorkingDirectory, originalFilePath, alternateFileContent); + repo.Index.Stage(originalFilePath); // Assert that normal checkout throws exception // for the conflict. Assert.Throws(() => repo.Checkout(master.CanonicalName)); // Checkout with force option should succeed. - repo.Checkout(master.CanonicalName, CheckoutOptions.Force, null); + repo.Checkout(master.CanonicalName, CheckoutModifiers.Force, null, null); // Assert that master branch is checked out. Assert.True(repo.Branches["master"].IsCurrentRepositoryHead); @@ -275,37 +279,71 @@ public void CanForcefullyCheckoutWithConflictingStagedChanges() [Fact] public void CheckingOutWithMergeConflictsThrows() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { - string fullPath = Path.Combine(repo.Info.WorkingDirectory, "a.txt"); - File.WriteAllText(fullPath, "Hello\n"); - repo.Index.Stage(fullPath); + Touch(repo.Info.WorkingDirectory, originalFilePath, "Hello\n"); + repo.Index.Stage(originalFilePath); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); // Create 2nd branch repo.CreateBranch("branch2"); // Update file in main - File.WriteAllText(fullPath, "Hello from master!\n"); - repo.Index.Stage(fullPath); + Touch(repo.Info.WorkingDirectory, originalFilePath, "Hello from master!\n"); + repo.Index.Stage(originalFilePath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); // Checkout branch2 repo.Checkout("branch2"); - File.WriteAllText(fullPath, "Hello From branch2!\n"); + Touch(repo.Info.WorkingDirectory, originalFilePath, "Hello From branch2!\n"); // Assert that checking out master throws // when there are unstaged commits Assert.Throws(() => repo.Checkout("master")); // And when there are staged commits - repo.Index.Stage(fullPath); + repo.Index.Stage(originalFilePath); Assert.Throws(() => repo.Checkout("master")); } } + [Fact] + public void CanCancelCheckoutThroughNotifyCallback() + { + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) + { + string relativePath = "a.txt"; + Touch(repo.Info.WorkingDirectory, relativePath, "Hello\n"); + + repo.Index.Stage(relativePath); + repo.Commit("Initial commit", Constants.Signature, Constants.Signature); + + // Create 2nd branch + repo.CreateBranch("branch2"); + + // Update file in main + Touch(repo.Info.WorkingDirectory, relativePath, "Hello from master!\n"); + repo.Index.Stage(relativePath); + repo.Commit("2nd commit", Constants.Signature, Constants.Signature); + + // Checkout branch2 + repo.Checkout("branch2"); + + // Update the context of a.txt - a.txt will then conflict between branch2 and master. + Touch(repo.Info.WorkingDirectory, relativePath, "Hello From branch2!\n"); + + // Verify that we get called for the notify conflict cb + string conflictPath = string.Empty; + CheckoutNotificationOptions checkoutNotifications = new CheckoutNotificationOptions((path, flags) => { conflictPath = path; return false; }, CheckoutNotifyFlags.Conflict); + Assert.Throws(() => repo.Checkout("master", CheckoutModifiers.None, null, checkoutNotifications)); + Assert.Equal(relativePath, conflictPath); + } + } + [Fact] public void CheckingOutInABareRepoThrows() { @@ -319,9 +357,9 @@ public void CheckingOutInABareRepoThrows() [Fact] public void CheckingOutAgainstAnUnbornBranchThrows() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Assert.True(repo.Info.IsHeadOrphaned); @@ -352,15 +390,15 @@ public void CheckingOutABranchWithBadParamsThrows() [Fact] public void CheckingOutThroughBranchCallsCheckoutProgress() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); bool wasCalled = false; Branch branch = repo.Branches[otherBranchName]; - branch.Checkout(CheckoutOptions.None, (path, completed, total) => wasCalled = true); + branch.Checkout(CheckoutModifiers.None, (path, completed, total) => wasCalled = true, null); Assert.True(wasCalled); } @@ -369,31 +407,108 @@ public void CheckingOutThroughBranchCallsCheckoutProgress() [Fact] public void CheckingOutThroughRepositoryCallsCheckoutProgress() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); bool wasCalled = false; - repo.Checkout(otherBranchName, CheckoutOptions.None, (path, completed, total) => wasCalled = true); + repo.Checkout(otherBranchName, CheckoutModifiers.None, (path, completed, total) => wasCalled = true, null); Assert.True(wasCalled); } } + [Theory] + [InlineData(CheckoutNotifyFlags.Conflict, "conflict.txt", false)] + [InlineData(CheckoutNotifyFlags.Updated, "updated.txt", false)] + [InlineData(CheckoutNotifyFlags.Untracked, "untracked.txt", false)] + [InlineData(CheckoutNotifyFlags.Ignored, "bin", true)] + public void CheckingOutCallsCheckoutNotify(CheckoutNotifyFlags notifyFlags, string expectedNotificationPath, bool isDirectory) + { + if (isDirectory) + { + expectedNotificationPath = expectedNotificationPath + Path.DirectorySeparatorChar; + } + + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) + { + PopulateBasicRepository(repo); + + string relativePathUpdated = "updated.txt"; + Touch(repo.Info.WorkingDirectory, relativePathUpdated, "updated file text A"); + repo.Index.Stage(relativePathUpdated); + repo.Commit("Commit initial update file", Constants.Signature, Constants.Signature); + + // Create conflicting change + string relativePathConflict = "conflict.txt"; + Touch(repo.Info.WorkingDirectory, relativePathConflict, "conflict file text A"); + repo.Index.Stage(relativePathConflict); + repo.Commit("Initial commit of conflict.txt and update.txt", Constants.Signature, Constants.Signature); + + // Create another branch + repo.CreateBranch("newbranch"); + + // Make an edit to conflict.txt and update.txt + Touch(repo.Info.WorkingDirectory, relativePathUpdated, "updated file text BB"); + repo.Index.Stage(relativePathUpdated); + Touch(repo.Info.WorkingDirectory, relativePathConflict, "conflict file text BB"); + repo.Index.Stage(relativePathConflict); + + repo.Commit("2nd commit of conflict.txt and update.txt on master branch", Constants.Signature, Constants.Signature); + + // Checkout other branch + repo.Checkout("newbranch"); + + // Make alternate edits to conflict.txt and update.txt + Touch(repo.Info.WorkingDirectory, relativePathUpdated, "updated file text CCC"); + repo.Index.Stage(relativePathUpdated); + Touch(repo.Info.WorkingDirectory, relativePathConflict, "conflict file text CCC"); + repo.Index.Stage(relativePathConflict); + repo.Commit("2nd commit of conflict.txt and update.txt on newbranch", Constants.Signature, Constants.Signature); + + // make conflicting change to conflict.txt + Touch(repo.Info.WorkingDirectory, relativePathConflict, "conflict file text DDDD"); + repo.Index.Stage(relativePathConflict); + + // Create ignored change + string relativePathIgnore = Path.Combine("bin", "ignored.txt"); + Touch(repo.Info.WorkingDirectory, relativePathIgnore, "ignored file"); + + // Create untracked change + string relativePathUntracked = "untracked.txt"; + Touch(repo.Info.WorkingDirectory, relativePathUntracked, "untracked file"); + + bool wasCalled = false; + string actualNotificationPath = string.Empty; + CheckoutNotifyFlags actualNotifyFlags = CheckoutNotifyFlags.None; + + CheckoutNotificationOptions checkoutNotifications = new CheckoutNotificationOptions( + (path, notificationType) => { wasCalled = true; actualNotificationPath = path; actualNotifyFlags = notificationType; return true; }, + notifyFlags); + + Assert.Throws(() => repo.Checkout("master", CheckoutModifiers.None, null, checkoutNotifications)); + + Assert.True(wasCalled); + Assert.Equal(expectedNotificationPath, actualNotificationPath); + Assert.Equal(notifyFlags, actualNotifyFlags); + } + } + [Fact] public void CheckoutRetainsUntrackedChanges() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); // Generate an unstaged change. - string fullPathFileB = Path.Combine(repo.Info.WorkingDirectory, "b.txt"); - File.WriteAllText(fullPathFileB, alternateFileContent); + string fullPathFileB = Touch(repo.Info.WorkingDirectory, "b.txt", alternateFileContent); // Verify that there is an untracked entry. Assert.Equal(1, repo.Index.RetrieveStatus().Untracked.Count()); @@ -410,21 +525,20 @@ public void CheckoutRetainsUntrackedChanges() [Fact] public void ForceCheckoutRetainsUntrackedChanges() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); // Generate an unstaged change. - string fullPathFileB = Path.Combine(repo.Info.WorkingDirectory, "b.txt"); - File.WriteAllText(fullPathFileB, alternateFileContent); + string fullPathFileB = Touch(repo.Info.WorkingDirectory, "b.txt", alternateFileContent); // Verify that there is an untracked entry. Assert.Equal(1, repo.Index.RetrieveStatus().Untracked.Count()); Assert.Equal(FileStatus.Untracked, repo.Index.RetrieveStatus(fullPathFileB)); - repo.Checkout(otherBranchName, CheckoutOptions.Force, null); + repo.Checkout(otherBranchName, CheckoutModifiers.Force, null, null); // Verify untracked entry still exists. Assert.Equal(1, repo.Index.RetrieveStatus().Untracked.Count()); @@ -435,15 +549,14 @@ public void ForceCheckoutRetainsUntrackedChanges() [Fact] public void CheckoutRetainsUnstagedChanges() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); // Generate an unstaged change. - string fullPathFileA = Path.Combine(repo.Info.WorkingDirectory, originalFilePath); - File.WriteAllText(fullPathFileA, alternateFileContent); + string fullPathFileA = Touch(repo.Info.WorkingDirectory, originalFilePath, alternateFileContent); // Verify that there is a modified entry. Assert.Equal(1, repo.Index.RetrieveStatus().Modified.Count()); @@ -460,15 +573,14 @@ public void CheckoutRetainsUnstagedChanges() [Fact] public void CheckoutRetainsStagedChanges() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); // Generate a staged change. - string fullPathFileA = Path.Combine(repo.Info.WorkingDirectory, originalFilePath); - File.WriteAllText(fullPathFileA, alternateFileContent); + string fullPathFileA = Touch(repo.Info.WorkingDirectory, originalFilePath, alternateFileContent); repo.Index.Stage(fullPathFileA); // Verify that there is a staged entry. @@ -486,19 +598,17 @@ public void CheckoutRetainsStagedChanges() [Fact] public void CheckoutRetainsIgnoredChanges() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); - // Create a bin directory. - string ignoredDirectoryPath = Path.Combine(repo.Info.WorkingDirectory, "bin"); - Directory.CreateDirectory(ignoredDirectoryPath); - // Create file in ignored bin directory. - string ignoredFilePath = Path.Combine(repo.Info.WorkingDirectory, Path.Combine("bin", "some_ignored_file.txt")); - File.WriteAllText(ignoredFilePath, "hello from this ignored file."); + string ignoredFilePath = Touch( + repo.Info.WorkingDirectory, + "bin/some_ignored_file.txt", + "hello from this ignored file."); Assert.Equal(1, repo.Index.RetrieveStatus().Ignored.Count()); @@ -515,25 +625,23 @@ public void CheckoutRetainsIgnoredChanges() [Fact] public void ForceCheckoutRetainsIgnoredChanges() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); - // Create a bin directory. - string ignoredDirectoryPath = Path.Combine(repo.Info.WorkingDirectory, "bin"); - Directory.CreateDirectory(ignoredDirectoryPath); - // Create file in ignored bin directory. - string ignoredFilePath = Path.Combine(repo.Info.WorkingDirectory, Path.Combine("bin", "some_ignored_file.txt")); - File.WriteAllText(ignoredFilePath, "hello from this ignored file."); + string ignoredFilePath = Touch( + repo.Info.WorkingDirectory, + "bin/some_ignored_file.txt", + "hello from this ignored file."); Assert.Equal(1, repo.Index.RetrieveStatus().Ignored.Count()); Assert.Equal(FileStatus.Ignored, repo.Index.RetrieveStatus(ignoredFilePath)); - repo.Checkout(otherBranchName, CheckoutOptions.Force, null); + repo.Checkout(otherBranchName, CheckoutModifiers.Force, null, null); // Verify that the ignored file still exists. Assert.Equal(FileStatus.Ignored, repo.Index.RetrieveStatus(ignoredFilePath)); @@ -544,9 +652,9 @@ public void ForceCheckoutRetainsIgnoredChanges() [Fact] public void CheckoutBranchSnapshot() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { PopulateBasicRepository(repo); @@ -556,8 +664,7 @@ public void CheckoutBranchSnapshot() Commit initialCommit = initial.Tip; // Add commit to master - string fullPath = Path.Combine(repo.Info.WorkingDirectory, originalFilePath); - File.WriteAllText(fullPath, "Update : hello from master branch!\n"); + string fullPath = Touch(repo.Info.WorkingDirectory, originalFilePath, "Update : hello from master branch!\n"); repo.Index.Stage(fullPath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); @@ -575,8 +682,11 @@ public void CheckoutBranchSnapshot() } } - [Fact] - public void CheckingOutRemoteBranchResultsInDetachedHead() + [Theory] + [InlineData("refs/remotes/origin/master")] + [InlineData("master@{u}")] + [InlineData("origin/master")] + public void CheckingOutRemoteBranchResultsInDetachedHead(string remoteBranchSpec) { string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) @@ -587,19 +697,11 @@ public void CheckingOutRemoteBranchResultsInDetachedHead() // Set the working directory to the current head ResetAndCleanWorkingDirectory(repo); - repo.Checkout("refs/remotes/origin/master"); + repo.Checkout(remoteBranchSpec); // Verify that HEAD is detached. Assert.Equal(repo.Refs["HEAD"].TargetIdentifier, repo.Branches["origin/master"].Tip.Sha); Assert.True(repo.Info.IsHeadDetached); - - // Assert reflog entry is created - var reflogEntry = repo.Refs.Log(repo.Refs.Head).First(); - Assert.Equal(master.Tip.Id, reflogEntry.From); - Assert.Equal(repo.Branches["origin/master"].Tip.Id, reflogEntry.To); - Assert.NotNull(reflogEntry.Commiter.Email); - Assert.NotNull(reflogEntry.Commiter.Name); - Assert.Equal("checkout: moving from master to origin/master", reflogEntry.Message); } } @@ -616,7 +718,7 @@ public void CheckingOutABranchDoesNotAlterBinaryFiles() // The blob actually exists in the object database with the correct Sha Assert.Equal(expectedSha, repo.Lookup(expectedSha).Sha); - repo.Checkout("refs/heads/logo", CheckoutOptions.Force, null); + repo.Checkout("refs/heads/logo", CheckoutModifiers.Force, null, null); // The Index has been updated as well with the blob Assert.Equal(expectedSha, repo.Index["square-logo.png"].Id.Sha); @@ -684,8 +786,30 @@ public void CheckoutBranchFromDetachedHead() } } + [Theory] + [InlineData("master", "refs/heads/master")] + [InlineData("heads/master", "refs/heads/master")] + public void CheckoutBranchByShortNameAttachesTheHead(string shortBranchName, string referenceName) + { + string path = CloneStandardTestRepo(); + using (var repo = new Repository(path)) + { + // Set the working directory to the current head + ResetAndCleanWorkingDirectory(repo); + Assert.False(repo.Index.RetrieveStatus().IsDirty); - [Fact(Skip = "Current libgit2 revparse implementation only returns the object being pointed at, not the reference pointing at it.")] + repo.Checkout("6dcf9bf"); + Assert.True(repo.Info.IsHeadDetached); + + var branch = repo.Checkout(shortBranchName); + + Assert.False(repo.Info.IsHeadDetached); + Assert.Equal(referenceName, repo.Head.CanonicalName); + Assert.Equal(referenceName, branch.CanonicalName); + } + } + + [Fact] public void CheckoutPreviousCheckedOutBranch() { string path = CloneStandardTestRepo(); @@ -696,18 +820,14 @@ public void CheckoutPreviousCheckedOutBranch() Assert.False(repo.Index.RetrieveStatus().IsDirty); Branch previousHead = repo.Checkout("i-do-numbers"); - Branch newHead = repo.Checkout("diff-test-cases"); + repo.Checkout("diff-test-cases"); //Go back to previous branch checked out - repo.Checkout(@"@{-1}"); + var branch = repo.Checkout(@"@{-1}"); - // Assert reflog entry is created - var reflogEntry = repo.Refs.Log(repo.Refs.Head).First(); - Assert.Equal(newHead.Tip.Id, reflogEntry.From); - Assert.Equal(previousHead.Tip.Id, reflogEntry.To); - Assert.NotNull(reflogEntry.Commiter.Email); - Assert.NotNull(reflogEntry.Commiter.Name); - Assert.Equal("checkout: moving from diff-test-cases to i-do-numbers", reflogEntry.Message); + Assert.False(repo.Info.IsHeadDetached); + Assert.Equal(previousHead.CanonicalName, repo.Head.CanonicalName); + Assert.Equal(previousHead.CanonicalName, branch.CanonicalName); } } @@ -802,20 +922,86 @@ public void CanCheckoutDetachedHead() } } + [Theory] + [InlineData("master", "6dcf9bf", "readme.txt", FileStatus.Added)] + [InlineData("master", "refs/tags/lw", "readme.txt", FileStatus.Added)] + [InlineData("master", "i-do-numbers", "super-file.txt", FileStatus.Added)] + [InlineData("i-do-numbers", "diff-test-cases", "numbers.txt", FileStatus.Staged)] + public void CanCheckoutPath(string originalBranch, string checkoutFrom, string path, FileStatus expectedStatus) + { + string repoPath = CloneStandardTestRepo(); + using (var repo = new Repository(repoPath)) + { + // Set the working directory to the current head + ResetAndCleanWorkingDirectory(repo); + + repo.Checkout(originalBranch); + Assert.False(repo.Index.RetrieveStatus().IsDirty); + + repo.CheckoutPaths(checkoutFrom, new string[] { path }, CheckoutModifiers.None, null, null); + + Assert.Equal(expectedStatus, repo.Index.RetrieveStatus(path)); + Assert.Equal(1, repo.Index.RetrieveStatus().Count()); + } + } + + [Fact] + public void CanCheckoutPaths() + { + string repoPath = CloneStandardTestRepo(); + var checkoutPaths = new[] { "numbers.txt", "super-file.txt" }; + + using (var repo = new Repository(repoPath)) + { + // Set the working directory to the current head + ResetAndCleanWorkingDirectory(repo); + Assert.False(repo.Index.RetrieveStatus().IsDirty); + + repo.CheckoutPaths("i-do-numbers", checkoutPaths, CheckoutModifiers.None, null, null); + + foreach (string checkoutPath in checkoutPaths) + { + Assert.Equal(FileStatus.Added, repo.Index.RetrieveStatus(checkoutPath)); + } + } + } + + [Theory] + [InlineData("new.txt")] + [InlineData("1.txt")] + public void CanCheckoutPathFromCurrentBranch(string fileName) + { + string repoPath = CloneStandardTestRepo(); + + using (var repo = new Repository(repoPath)) + { + // Set the working directory to the current head + ResetAndCleanWorkingDirectory(repo); + + Assert.False(repo.Index.RetrieveStatus().IsDirty); + + Touch(repo.Info.WorkingDirectory, fileName, "new text file"); + + Assert.True(repo.Index.RetrieveStatus().IsDirty); + + repo.CheckoutPaths("HEAD", new string[] { fileName }, CheckoutModifiers.Force, null, null); + + Assert.False(repo.Index.RetrieveStatus().IsDirty); + } + } + /// - /// Helper method to populate a simple repository with - /// a single file and two branches. + /// Helper method to populate a simple repository with + /// a single file and two branches. /// /// Repository to populate private void PopulateBasicRepository(Repository repo) { // Generate a .gitignore file. - string gitIgnoreFilePath = Path.Combine(repo.Info.WorkingDirectory, ".gitignore"); - File.WriteAllText(gitIgnoreFilePath, "bin"); + string gitIgnoreFilePath = Touch(repo.Info.WorkingDirectory, ".gitignore", "bin"); repo.Index.Stage(gitIgnoreFilePath); - string fullPathFileA = Path.Combine(repo.Info.WorkingDirectory, originalFilePath); - File.WriteAllText(fullPathFileA, originalFileContent); + string fullPathFileA = Touch(repo.Info.WorkingDirectory, originalFilePath, originalFileContent); repo.Index.Stage(fullPathFileA); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp.Tests/CloneFixture.cs b/LibGit2Sharp.Tests/CloneFixture.cs index f5f005d19..a1ae44ded 100644 --- a/LibGit2Sharp.Tests/CloneFixture.cs +++ b/LibGit2Sharp.Tests/CloneFixture.cs @@ -17,7 +17,10 @@ public class CloneFixture : BaseFixture public void CanClone(string url) { var scd = BuildSelfCleaningDirectory(); - using (Repository repo = Repository.Clone(url, scd.RootedDirectoryPath)) + + string clonedRepoPath = Repository.Clone(url, scd.DirectoryPath); + + using (var repo = new Repository(clonedRepoPath)) { string dir = repo.Info.Path; Assert.True(Path.IsPathRooted(dir)); @@ -36,7 +39,10 @@ public void CanClone(string url) private void AssertLocalClone(string path) { var scd = BuildSelfCleaningDirectory(); - using (Repository clonedRepo = Repository.Clone(path, scd.RootedDirectoryPath)) + + string clonedRepoPath = Repository.Clone(path, scd.DirectoryPath); + + using (var clonedRepo = new Repository(clonedRepoPath)) using (var originalRepo = new Repository(BareTestRepoPath)) { Assert.NotEqual(originalRepo.Info.Path, clonedRepo.Info.Path); @@ -71,7 +77,10 @@ public void CanCloneALocalRepositoryFromAStandardPath() public void CanCloneBarely(string url) { var scd = BuildSelfCleaningDirectory(); - using (Repository repo = Repository.Clone(url, scd.RootedDirectoryPath, bare: true)) + + string clonedRepoPath = Repository.Clone(url, scd.DirectoryPath, bare: true); + + using (var repo = new Repository(clonedRepoPath)) { string dir = repo.Info.Path; Assert.True(Path.IsPathRooted(dir)); @@ -88,9 +97,12 @@ public void CanCloneBarely(string url) public void WontCheckoutIfAskedNotTo(string url) { var scd = BuildSelfCleaningDirectory(); - using (Repository repo = Repository.Clone(url, scd.RootedDirectoryPath, checkout: false)) + + string clonedRepoPath = Repository.Clone(url, scd.DirectoryPath, checkout: false); + + using (var repo = new Repository(clonedRepoPath)) { - Assert.False(File.Exists(Path.Combine(scd.RootedDirectoryPath, "master.txt"))); + Assert.False(File.Exists(Path.Combine(repo.Info.WorkingDirectory, "master.txt"))); } } @@ -102,13 +114,13 @@ public void CallsProgressCallbacks(string url) bool checkoutWasCalled = false; var scd = BuildSelfCleaningDirectory(); - using (Repository repo = Repository.Clone(url, scd.RootedDirectoryPath, - onTransferProgress: (_) => { transferWasCalled = true; return 0; }, - onCheckoutProgress: (a, b, c) => checkoutWasCalled = true)) - { - Assert.True(transferWasCalled); - Assert.True(checkoutWasCalled); - } + + Repository.Clone(url, scd.DirectoryPath, + onTransferProgress: _ => { transferWasCalled = true; return 0; }, + onCheckoutProgress: (a, b, c) => checkoutWasCalled = true); + + Assert.True(transferWasCalled); + Assert.True(checkoutWasCalled); } [SkippableFact] @@ -118,13 +130,16 @@ public void CanCloneWithCredentials() "Populate Constants.PrivateRepo* to run this test"); var scd = BuildSelfCleaningDirectory(); - using (Repository repo = Repository.Clone( - Constants.PrivateRepoUrl, scd.RootedDirectoryPath, + + string clonedRepoPath = Repository.Clone(Constants.PrivateRepoUrl, scd.DirectoryPath, credentials: new Credentials { Username = Constants.PrivateRepoUsername, Password = Constants.PrivateRepoPassword - })) + }); + + + using (var repo = new Repository(clonedRepoPath)) { string dir = repo.Info.Path; Assert.True(Path.IsPathRooted(dir)); diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index 63a232b50..b6577d453 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -77,7 +77,7 @@ public void DefaultOrderingWhenEnumeratingCommitsIsTimeBased() { using (var repo = new Repository(BareTestRepoPath)) { - Assert.Equal(GitSortOptions.Time, repo.Commits.SortedBy); + Assert.Equal(CommitSortStrategies.Time, repo.Commits.SortedBy); } } @@ -87,7 +87,7 @@ public void CanEnumerateCommitsFromSha() int count = 0; using (var repo = new Repository(BareTestRepoPath)) { - foreach (Commit commit in repo.Commits.QueryBy(new Filter { Since = "a4a7dce85cf63874e984719f4fdd239f5145052f" })) + foreach (Commit commit in repo.Commits.QueryBy(new CommitFilter { Since = "a4a7dce85cf63874e984719f4fdd239f5145052f" })) { Assert.NotNull(commit); count++; @@ -101,9 +101,9 @@ public void QueryingTheCommitHistoryWithUnknownShaOrInvalidEntryPointThrows() { using (var repo = new Repository(BareTestRepoPath)) { - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = Constants.UnknownSha }).Count()); - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = "refs/heads/deadbeef" }).Count()); - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = null }).Count()); + Assert.Throws(() => repo.Commits.QueryBy(new CommitFilter { Since = Constants.UnknownSha }).Count()); + Assert.Throws(() => repo.Commits.QueryBy(new CommitFilter { Since = "refs/heads/deadbeef" }).Count()); + Assert.Throws(() => repo.Commits.QueryBy(new CommitFilter { Since = null }).Count()); } } @@ -115,8 +115,8 @@ public void QueryingTheCommitHistoryFromACorruptedReferenceThrows() { CreateCorruptedDeadBeefHead(repo.Info.Path); - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = repo.Branches["deadbeef"] }).Count()); - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = repo.Refs["refs/heads/deadbeef"] }).Count()); + Assert.Throws(() => repo.Commits.QueryBy(new CommitFilter { Since = repo.Branches["deadbeef"] }).Count()); + Assert.Throws(() => repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs["refs/heads/deadbeef"] }).Count()); } } @@ -125,9 +125,9 @@ public void QueryingTheCommitHistoryWithBadParamsThrows() { using (var repo = new Repository(BareTestRepoPath)) { - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = string.Empty })); - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = null })); - Assert.Throws(() => repo.Commits.QueryBy(null)); + Assert.Throws(() => repo.Commits.QueryBy(new CommitFilter { Since = string.Empty })); + Assert.Throws(() => repo.Commits.QueryBy(new CommitFilter { Since = null })); + Assert.Throws(() => repo.Commits.QueryBy(default(CommitFilter))); } } @@ -140,7 +140,11 @@ public void CanEnumerateCommitsWithReverseTimeSorting() int count = 0; using (var repo = new Repository(BareTestRepoPath)) { - foreach (Commit commit in repo.Commits.QueryBy(new Filter { Since = "a4a7dce85cf63874e984719f4fdd239f5145052f", SortBy = GitSortOptions.Time | GitSortOptions.Reverse })) + foreach (Commit commit in repo.Commits.QueryBy(new CommitFilter + { + Since = "a4a7dce85cf63874e984719f4fdd239f5145052f", + SortBy = CommitSortStrategies.Time | CommitSortStrategies.Reverse + })) { Assert.NotNull(commit); Assert.True(commit.Sha.StartsWith(reversedShas[count])); @@ -155,7 +159,11 @@ public void CanEnumerateCommitsWithReverseTopoSorting() { using (var repo = new Repository(BareTestRepoPath)) { - List commits = repo.Commits.QueryBy(new Filter { Since = "a4a7dce85cf63874e984719f4fdd239f5145052f", SortBy = GitSortOptions.Time | GitSortOptions.Reverse }).ToList(); + List commits = repo.Commits.QueryBy(new CommitFilter + { + Since = "a4a7dce85cf63874e984719f4fdd239f5145052f", + SortBy = CommitSortStrategies.Time | CommitSortStrategies.Reverse + }).ToList(); foreach (Commit commit in commits) { Assert.NotNull(commit); @@ -183,7 +191,11 @@ public void CanEnumerateCommitsWithTimeSorting() int count = 0; using (var repo = new Repository(BareTestRepoPath)) { - foreach (Commit commit in repo.Commits.QueryBy(new Filter { Since = "a4a7dce85cf63874e984719f4fdd239f5145052f", SortBy = GitSortOptions.Time })) + foreach (Commit commit in repo.Commits.QueryBy(new CommitFilter + { + Since = "a4a7dce85cf63874e984719f4fdd239f5145052f", + SortBy = CommitSortStrategies.Time + })) { Assert.NotNull(commit); Assert.True(commit.Sha.StartsWith(expectedShas[count])); @@ -198,7 +210,11 @@ public void CanEnumerateCommitsWithTopoSorting() { using (var repo = new Repository(BareTestRepoPath)) { - List commits = repo.Commits.QueryBy(new Filter { Since = "a4a7dce85cf63874e984719f4fdd239f5145052f", SortBy = GitSortOptions.Topological }).ToList(); + List commits = repo.Commits.QueryBy(new CommitFilter + { + Since = "a4a7dce85cf63874e984719f4fdd239f5145052f", + SortBy = CommitSortStrategies.Topological + }).ToList(); foreach (Commit commit in commits) { Assert.NotNull(commit); @@ -215,7 +231,7 @@ public void CanEnumerateCommitsWithTopoSorting() public void CanEnumerateFromHead() { AssertEnumerationOfCommits( - repo => new Filter { Since = repo.Head }, + repo => new CommitFilter { Since = repo.Head }, new[] { "4c062a6", "be3563a", "c47800c", "9fd738e", @@ -237,7 +253,7 @@ public void CanEnumerateFromDetachedHead() repoClone.Checkout(headSha); AssertEnumerationOfCommitsInRepo(repoClone, - repo => new Filter { Since = repo.Head }, + repo => new CommitFilter { Since = repo.Head }, new[] { "32eab9c", "592d3c8", "4c062a6", @@ -251,7 +267,7 @@ public void CanEnumerateFromDetachedHead() public void CanEnumerateUsingTwoHeadsAsBoundaries() { AssertEnumerationOfCommits( - repo => new Filter { Since = "HEAD", Until = "refs/heads/br2" }, + repo => new CommitFilter { Since = "HEAD", Until = "refs/heads/br2" }, new[] { "4c062a6", "be3563a" } ); } @@ -260,7 +276,7 @@ public void CanEnumerateUsingTwoHeadsAsBoundaries() public void CanEnumerateUsingImplicitHeadAsSinceBoundary() { AssertEnumerationOfCommits( - repo => new Filter { Until = "refs/heads/br2" }, + repo => new CommitFilter { Until = "refs/heads/br2" }, new[] { "4c062a6", "be3563a" } ); } @@ -269,7 +285,7 @@ public void CanEnumerateUsingImplicitHeadAsSinceBoundary() public void CanEnumerateUsingTwoAbbreviatedShasAsBoundaries() { AssertEnumerationOfCommits( - repo => new Filter { Since = "a4a7dce", Until = "4a202b3" }, + repo => new CommitFilter { Since = "a4a7dce", Until = "4a202b3" }, new[] { "a4a7dce", "c47800c", "9fd738e" } ); } @@ -278,7 +294,7 @@ public void CanEnumerateUsingTwoAbbreviatedShasAsBoundaries() public void CanEnumerateCommitsFromTwoHeads() { AssertEnumerationOfCommits( - repo => new Filter { Since = new[] { "refs/heads/br2", "refs/heads/master" } }, + repo => new CommitFilter { Since = new[] { "refs/heads/br2", "refs/heads/master" } }, new[] { "4c062a6", "a4a7dce", "be3563a", "c47800c", @@ -290,7 +306,7 @@ public void CanEnumerateCommitsFromTwoHeads() public void CanEnumerateCommitsFromMixedStartingPoints() { AssertEnumerationOfCommits( - repo => new Filter { Since = new object[] { repo.Branches["br2"], + repo => new CommitFilter { Since = new object[] { repo.Branches["br2"], "refs/heads/master", new ObjectId("e90810b8df3e80c413d903f631643c716887138d") } }, new[] @@ -305,7 +321,7 @@ public void CanEnumerateCommitsFromMixedStartingPoints() public void CanEnumerateCommitsUsingGlob() { AssertEnumerationOfCommits( - repo => new Filter { Since = repo.Refs.FromGlob("refs/heads/*") }, + repo => new CommitFilter { Since = repo.Refs.FromGlob("refs/heads/*") }, new[] { "4c062a6", "e90810b", "6dcf9bf", "a4a7dce", "be3563a", "c47800c", "9fd738e", "4a202b3", "41bc8c6", "5001298", "5b5b025", "8496071" @@ -316,7 +332,7 @@ public void CanEnumerateCommitsUsingGlob() public void CanHideCommitsUsingGlob() { AssertEnumerationOfCommits( - repo => new Filter { Since = "refs/heads/packed-test", Until = repo.Refs.FromGlob("*/packed") }, + repo => new CommitFilter { Since = "refs/heads/packed-test", Until = repo.Refs.FromGlob("*/packed") }, new[] { "4a202b3", "5b5b025", "8496071" @@ -338,7 +354,7 @@ public void CanEnumerateCommitsFromATagAnnotation() private static void CanEnumerateCommitsFromATag(Func transformer) { AssertEnumerationOfCommits( - repo => new Filter { Since = transformer(repo.Tags["test"]) }, + repo => new CommitFilter { Since = transformer(repo.Tags["test"]) }, new[] { "e90810b", "6dcf9bf", } ); } @@ -347,7 +363,7 @@ private static void CanEnumerateCommitsFromATag(Func transformer) public void CanEnumerateAllCommits() { AssertEnumerationOfCommits( - repo => new Filter + repo => new CommitFilter { Since = repo.Refs.OrderBy(r => r.CanonicalName, StringComparer.Ordinal), }, @@ -364,7 +380,7 @@ public void CanEnumerateAllCommits() public void CanEnumerateCommitsFromATagWhichPointsToABlob() { AssertEnumerationOfCommits( - repo => new Filter { Since = repo.Tags["point_to_blob"] }, + repo => new CommitFilter { Since = repo.Tags["point_to_blob"] }, new string[] { }); } @@ -379,12 +395,12 @@ public void CanEnumerateCommitsFromATagWhichPointsToATree() Tag tag = repo.ApplyTag("point_to_tree", headTreeSha); AssertEnumerationOfCommitsInRepo(repo, - r => new Filter { Since = tag }, + r => new CommitFilter { Since = tag }, new string[] { }); } } - private static void AssertEnumerationOfCommits(Func filterBuilder, IEnumerable abbrevIds) + private static void AssertEnumerationOfCommits(Func filterBuilder, IEnumerable abbrevIds) { using (var repo = new Repository(BareTestRepoPath)) { @@ -392,7 +408,7 @@ private static void AssertEnumerationOfCommits(Func filterBu } } - private static void AssertEnumerationOfCommitsInRepo(Repository repo, Func filterBuilder, IEnumerable abbrevIds) + private static void AssertEnumerationOfCommitsInRepo(Repository repo, Func filterBuilder, IEnumerable abbrevIds) { ICommitLog commits = repo.Commits.QueryBy(filterBuilder(repo)); @@ -494,9 +510,9 @@ public void DirectlyAccessingAnUnknownTreeEntryOfTheCommitReturnsNull() [SkippableFact] public void CanCommitWithSignatureFromConfig() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { string dir = repo.Info.Path; Assert.True(Path.IsPathRooted(dir)); @@ -506,10 +522,9 @@ public void CanCommitWithSignatureFromConfig() "No Git global configuration available"); const string relativeFilepath = "new.txt"; - string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath); - - File.WriteAllText(filePath, "null"); + string filePath = Touch(repo.Info.WorkingDirectory, relativeFilepath, "null"); repo.Index.Stage(relativeFilepath); + File.AppendAllText(filePath, "token\n"); repo.Index.Stage(relativeFilepath); @@ -539,12 +554,11 @@ public void CommitParentsAreMergeHeads() CreateAndStageANewFile(repo); - string mergeHeadPath = Path.Combine(repo.Info.Path, "MERGE_HEAD"); - File.WriteAllText(mergeHeadPath, "9fd738e8f7967c078dceed8190330fc8648ee56a\n"); + Touch(repo.Info.Path, "MERGE_HEAD", "9fd738e8f7967c078dceed8190330fc8648ee56a\n"); Assert.Equal(CurrentOperation.Merge, repo.Info.CurrentOperation); - Commit newMergedCommit = repo.Commit("Merge commit", DummySignature, DummySignature); + Commit newMergedCommit = repo.Commit("Merge commit", Constants.Signature, Constants.Signature); Assert.Equal(CurrentOperation.None, repo.Info.CurrentOperation); @@ -564,36 +578,29 @@ public void CommitParentsAreMergeHeads() [Fact] public void CommitCleansUpMergeMetadata() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { string dir = repo.Info.Path; Assert.True(Path.IsPathRooted(dir)); Assert.True(Directory.Exists(dir)); const string relativeFilepath = "new.txt"; - string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath); - - File.WriteAllText(filePath, "this is a new file"); + Touch(repo.Info.WorkingDirectory, relativeFilepath, "this is a new file"); repo.Index.Stage(relativeFilepath); - string mergeHeadPath = Path.Combine(repo.Info.Path, "MERGE_HEAD"); - string mergeMsgPath = Path.Combine(repo.Info.Path, "MERGE_MSG"); - string mergeModePath = Path.Combine(repo.Info.Path, "MERGE_MODE"); - string origHeadPath = Path.Combine(repo.Info.Path, "ORIG_HEAD"); - - File.WriteAllText(mergeHeadPath, "abcdefabcdefabcdefabcdefabcdefabcdefabcd"); - File.WriteAllText(mergeMsgPath, "This is a dummy merge.\n"); - File.WriteAllText(mergeModePath, "no-ff"); - File.WriteAllText(origHeadPath, "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef"); + string mergeHeadPath = Touch(repo.Info.Path, "MERGE_HEAD", "abcdefabcdefabcdefabcdefabcdefabcdefabcd"); + string mergeMsgPath = Touch(repo.Info.Path, "MERGE_MSG", "This is a dummy merge.\n"); + string mergeModePath = Touch(repo.Info.Path, "MERGE_MODE", "no-ff"); + string origHeadPath = Touch(repo.Info.Path, "ORIG_HEAD", "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef"); Assert.True(File.Exists(mergeHeadPath)); Assert.True(File.Exists(mergeMsgPath)); Assert.True(File.Exists(mergeModePath)); Assert.True(File.Exists(origHeadPath)); - var author = DummySignature; + var author = Constants.Signature; repo.Commit("Initial egotistic commit", author, author); Assert.False(File.Exists(mergeHeadPath)); @@ -606,25 +613,23 @@ public void CommitCleansUpMergeMetadata() [Fact] public void CanCommitALittleBit() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { string dir = repo.Info.Path; Assert.True(Path.IsPathRooted(dir)); Assert.True(Directory.Exists(dir)); const string relativeFilepath = "new.txt"; - string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath); - - File.WriteAllText(filePath, "null"); + string filePath = Touch(repo.Info.WorkingDirectory, relativeFilepath, "null"); repo.Index.Stage(relativeFilepath); File.AppendAllText(filePath, "token\n"); repo.Index.Stage(relativeFilepath); Assert.Null(repo.Head[relativeFilepath]); - var author = DummySignature; + var author = Constants.Signature; const string shortMessage = "Initial egotistic commit"; const string commitMessage = shortMessage + "\n\nOnly the coolest commits from us"; @@ -692,14 +697,12 @@ private static void AssertBlobContent(TreeEntry entry, string expectedContent) Assert.Equal(expectedContent, ((Blob)(entry.Target)).ContentAsUtf8()); } - private static void CommitToANewRepository(string path) + private static void AddCommitToRepo(string path) { - using (Repository repo = Repository.Init(path)) + using (var repo = new Repository(path)) { const string relativeFilepath = "test.txt"; - string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath); - - File.WriteAllText(filePath, "test\n"); + Touch(repo.Info.WorkingDirectory, relativeFilepath, "test\n"); repo.Index.Stage(relativeFilepath); var author = new Signature("nulltoken", "emeric.fermas@gmail.com", DateTimeOffset.Parse("Wed, Dec 14 2011 08:29:03 +0100")); @@ -710,11 +713,11 @@ private static void CommitToANewRepository(string path) [Fact] public void CanGeneratePredictableObjectShas() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - CommitToANewRepository(scd.DirectoryPath); + AddCommitToRepo(repoPath); - using (var repo = new Repository(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Commit commit = repo.Commits.Single(); Assert.Equal("1fe3126578fc4eca68c193e4a3a0a14a0704624d", commit.Sha); @@ -730,11 +733,11 @@ public void CanGeneratePredictableObjectShas() [Fact] public void CanAmendARootCommit() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - CommitToANewRepository(scd.DirectoryPath); + AddCommitToRepo(repoPath); - using (var repo = new Repository(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Assert.Equal(1, repo.Head.Commits.Count()); @@ -743,7 +746,7 @@ public void CanAmendARootCommit() CreateAndStageANewFile(repo); - Commit amendedCommit = repo.Commit("I'm rewriting the history!", DummySignature, DummySignature, true); + Commit amendedCommit = repo.Commit("I'm rewriting the history!", Constants.Signature, Constants.Signature, true); Assert.Equal(1, repo.Head.Commits.Count()); @@ -766,7 +769,7 @@ public void CanAmendACommitWithMoreThanOneParent() CreateAndStageANewFile(repo); const string commitMessage = "I'm rewriting the history!"; - Commit amendedCommit = repo.Commit(commitMessage, DummySignature, DummySignature, true); + Commit amendedCommit = repo.Commit(commitMessage, Constants.Signature, Constants.Signature, true); AssertCommitHasBeenAmended(repo, amendedCommit, mergedCommit); @@ -781,9 +784,7 @@ public void CanAmendACommitWithMoreThanOneParent() private static void CreateAndStageANewFile(Repository repo) { string relativeFilepath = string.Format("new-file-{0}.txt", Guid.NewGuid()); - string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath); - - File.WriteAllText(filePath, "brand new content\n"); + Touch(repo.Info.WorkingDirectory, relativeFilepath, "brand new content\n"); repo.Index.Stage(relativeFilepath); } @@ -799,11 +800,11 @@ private static void AssertCommitHasBeenAmended(Repository repo, Commit amendedCo [Fact] public void CanNotAmendAnEmptyRepository() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (Repository repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { - Assert.Throws(() => repo.Commit("I can not amend anything !:(", DummySignature, DummySignature, true)); + Assert.Throws(() => repo.Commit("I can not amend anything !:(", Constants.Signature, Constants.Signature, true)); } } @@ -815,7 +816,7 @@ public void CanRetrieveChildrenOfASpecificCommit() { const string parentSha = "5b5b025afb0b4c913b4c338a42934a3863bf3644"; - var filter = new Filter + var filter = new CommitFilter { /* Revwalk from all the refs (git log --all) ... */ Since = repo.Refs, @@ -861,21 +862,20 @@ public void CanCorrectlyDistinguishAuthorFromCommitter() public void CanCommitOnOrphanedBranch() { string newBranchName = "refs/heads/newBranch"; - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.DirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { // Set Head to point to branch other than master repo.Refs.UpdateTarget("HEAD", newBranchName); Assert.Equal(newBranchName, repo.Head.CanonicalName); const string relativeFilepath = "test.txt"; - string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath); - - File.WriteAllText(filePath, "test\n"); + Touch(repo.Info.WorkingDirectory, relativeFilepath, "test\n"); repo.Index.Stage(relativeFilepath); - repo.Commit("Initial commit", DummySignature, DummySignature); + repo.Commit("Initial commit", Constants.Signature, Constants.Signature); Assert.Equal(1, repo.Head.Commits.Count()); } } diff --git a/LibGit2Sharp.Tests/CurrentOperationFixture.cs b/LibGit2Sharp.Tests/CurrentOperationFixture.cs index 9e094df4d..5b9200310 100644 --- a/LibGit2Sharp.Tests/CurrentOperationFixture.cs +++ b/LibGit2Sharp.Tests/CurrentOperationFixture.cs @@ -1,5 +1,4 @@ using System.IO; -using System.Text; using LibGit2Sharp.Tests.TestHelpers; using Xunit; using Xunit.Extensions; @@ -13,8 +12,9 @@ public class CurrentOperationFixture : BaseFixture [InlineData(false)] public void CurrentOperationIsNoneForNewRepo(bool isBare) { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.DirectoryPath, isBare)) + string repoPath = InitNewRepository(isBare); + + using (var repo = new Repository(repoPath)) { Assert.Equal(CurrentOperation.None, repo.Info.CurrentOperation); } diff --git a/LibGit2Sharp.Tests/DiffBlobToBlobFixture.cs b/LibGit2Sharp.Tests/DiffBlobToBlobFixture.cs index 6d19ae8ee..15bfc5f87 100644 --- a/LibGit2Sharp.Tests/DiffBlobToBlobFixture.cs +++ b/LibGit2Sharp.Tests/DiffBlobToBlobFixture.cs @@ -1,5 +1,4 @@ using System.IO; -using System.Linq; using System.Text; using LibGit2Sharp.Tests.TestHelpers; using Xunit; diff --git a/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs index 34e272bf1..37b3f669f 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs @@ -10,11 +10,10 @@ public class DiffTreeToTargetFixture : BaseFixture { private static void SetUpSimpleDiffContext(Repository repo) { - var fullpath = Path.Combine(repo.Info.WorkingDirectory, "file.txt"); - File.WriteAllText(fullpath, "hello\n"); + var fullpath = Touch(repo.Info.WorkingDirectory, "file.txt", "hello\n"); repo.Index.Stage(fullpath); - repo.Commit("Initial commit", DummySignature, DummySignature); + repo.Commit("Initial commit", Constants.Signature, Constants.Signature); File.AppendAllText(fullpath, "world\n"); @@ -38,9 +37,9 @@ private static void SetUpSimpleDiffContext(Repository repo) */ public void CanCompareASimpleTreeAgainstTheWorkDir() { - var scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + using (var repo = new Repository(repoPath)) { SetUpSimpleDiffContext(repo); @@ -98,9 +97,9 @@ public void CanCompareAMoreComplexTreeAgainstTheWorkdir() */ public void CanCompareASimpleTreeAgainstTheWorkDirAndTheIndex() { - var scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + using (var repo = new Repository(repoPath)) { SetUpSimpleDiffContext(repo); @@ -145,9 +144,9 @@ public void CanCompareASimpleTreeAgainstTheWorkDirAndTheIndex() */ public void ShowcaseTheDifferenceBetweenTheTwoKindOfComparison() { - var scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + using (var repo = new Repository(repoPath)) { SetUpSimpleDiffContext(repo); @@ -202,9 +201,9 @@ public void ShowcaseTheDifferenceBetweenTheTwoKindOfComparison() */ public void CanCompareASimpleTreeAgainstTheIndex() { - var scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + using (var repo = new Repository(repoPath)) { SetUpSimpleDiffContext(repo); @@ -348,15 +347,14 @@ public void ComparingASubsetofTheTreeAgainstTheIndexWithStrictExplicitPathsValid */ public void CanCopeWithEndOfFileNewlineChanges() { - var scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + using (var repo = new Repository(repoPath)) { - var fullpath = Path.Combine(repo.Info.WorkingDirectory, "file.txt"); - File.WriteAllText(fullpath, "a"); + var fullpath = Touch(repo.Info.WorkingDirectory, "file.txt", "a"); repo.Index.Stage("file.txt"); - repo.Commit("Add file without line ending", DummySignature, DummySignature); + repo.Commit("Add file without line ending", Constants.Signature, Constants.Signature); File.AppendAllText(fullpath, "\n"); repo.Index.Stage("file.txt"); @@ -397,9 +395,9 @@ public void ComparingATreeInABareRepositoryAgainstTheWorkDirOrTheIndexThrows() [Fact] public void CanCompareANullTreeAgainstTheIndex() { - var scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + using (var repo = new Repository(repoPath)) { SetUpSimpleDiffContext(repo); @@ -417,9 +415,9 @@ public void CanCompareANullTreeAgainstTheIndex() [Fact] public void CanCompareANullTreeAgainstTheWorkdir() { - var scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + using (var repo = new Repository(repoPath)) { SetUpSimpleDiffContext(repo); @@ -437,9 +435,9 @@ public void CanCompareANullTreeAgainstTheWorkdir() [Fact] public void CanCompareANullTreeAgainstTheWorkdirAndTheIndex() { - var scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + using (var repo = new Repository(repoPath)) { SetUpSimpleDiffContext(repo); diff --git a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs index a40070b5c..4ed88ea69 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs @@ -349,9 +349,9 @@ public void CanCompareTwoVersionsOfAFileWithADiffOfTwoHunks(int contextLines, in [Fact] public void CanHandleTwoTreeEntryChangesWithTheSamePath() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (Repository repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Blob mainContent = OdbHelper.CreateBlob(repo, "awesome content\n"); Blob linkContent = OdbHelper.CreateBlob(repo, "../../objc/Nu.h"); @@ -511,10 +511,11 @@ private RepositoryOptions BuildFakeSystemConfigFilemodeOption( [Fact] public void RetrievingDiffChangesMustAlwaysBeCaseSensitive() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); ObjectId treeOldOid, treeNewOid; - using (Repository repo = Repository.Init(scd.DirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { Blob oldContent = OdbHelper.CreateBlob(repo, "awesome content\n"); Blob newContent = OdbHelper.CreateBlob(repo, "more awesome content\n"); @@ -532,7 +533,7 @@ public void RetrievingDiffChangesMustAlwaysBeCaseSensitive() treeNewOid = repo.ObjectDatabase.CreateTree(td).Id; } - using (var repo = new Repository(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { var changes = repo.Diff.Compare(repo.Lookup(treeOldOid), repo.Lookup(treeNewOid)); diff --git a/LibGit2Sharp.Tests/FetchFixture.cs b/LibGit2Sharp.Tests/FetchFixture.cs index f40dcd667..182fd7f06 100644 --- a/LibGit2Sharp.Tests/FetchFixture.cs +++ b/LibGit2Sharp.Tests/FetchFixture.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; +using System.Linq; using LibGit2Sharp.Tests.TestHelpers; +using Xunit; using Xunit.Extensions; namespace LibGit2Sharp.Tests @@ -14,8 +16,9 @@ public class FetchFixture : BaseFixture [InlineData("git://github.com/libgit2/TestGitRepository.git")] public void CanFetchIntoAnEmptyRepository(string url) { - var scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { Remote remote = repo.Network.Remotes.Add(remoteName, url); @@ -52,8 +55,9 @@ public void CanFetchIntoAnEmptyRepositoryWithCredentials() InconclusiveIf(() => string.IsNullOrEmpty(Constants.PrivateRepoUrl), "Populate Constants.PrivateRepo* to run this test"); - var scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { Remote remote = repo.Network.Remotes.Add(remoteName, Constants.PrivateRepoUrl); @@ -72,8 +76,9 @@ public void CanFetchIntoAnEmptyRepositoryWithCredentials() [InlineData("git://github.com/libgit2/TestGitRepository.git")] public void CanFetchAllTagsIntoAnEmptyRepository(string url) { - var scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { Remote remote = repo.Network.Remotes.Add(remoteName, url); @@ -95,5 +100,32 @@ public void CanFetchAllTagsIntoAnEmptyRepository(string url) expectedFetchState.CheckUpdatedReferences(repo); } } + + [Theory] + [InlineData(TagFetchMode.All, 4)] + [InlineData(TagFetchMode.None, 0)] + [InlineData(TagFetchMode.Auto, 3)] + public void FetchRespectsConfiguredAutoTagSetting(TagFetchMode tagFetchMode, int expectedTagCount) + { + string url = "http://github.com/libgit2/TestGitRepository"; + + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) + { + Remote remote = repo.Network.Remotes.Add(remoteName, url); + Assert.NotNull(remote); + + // Update the configured autotag setting. + repo.Network.Remotes.Update(remote, + r => r.TagFetchMode = tagFetchMode); + + // Perform the actual fetch. + repo.Network.Fetch(remote); + + // Verify the number of fetched tags. + Assert.Equal(expectedTagCount, repo.Tags.Count()); + } + } } } diff --git a/LibGit2Sharp.Tests/FetchHeadFixture.cs b/LibGit2Sharp.Tests/FetchHeadFixture.cs index c6cc8656b..9714ff64a 100644 --- a/LibGit2Sharp.Tests/FetchHeadFixture.cs +++ b/LibGit2Sharp.Tests/FetchHeadFixture.cs @@ -1,7 +1,6 @@ -using LibGit2Sharp.Tests.TestHelpers; -using System; -using System.IO; +using System; using System.Linq; +using LibGit2Sharp.Tests.TestHelpers; using Xunit; using Xunit.Extensions; @@ -12,8 +11,9 @@ public class FetchHeadFixture : BaseFixture [Fact] public void FetchHeadIsEmptyByDefault() { - var scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { Assert.Equal(0, repo.Network.FetchHeads.Count()); } @@ -33,14 +33,16 @@ private class FetchHeadExpected public void CanIterateFetchHead(string url) { var scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Clone(url, scd.RootedDirectoryPath)) + + string clonedRepoPath = Repository.Clone(url, scd.DirectoryPath); + + using (var repo = new Repository(clonedRepoPath)) { repo.Reset(ResetOptions.Hard, "HEAD~2"); // Create a file, stage it, and commit it. - String filename = "b.txt"; - String fullPath = Path.Combine(repo.Info.WorkingDirectory, filename); - File.WriteAllText(fullPath, ""); + const string filename = "b.txt"; + Touch(repo.Info.WorkingDirectory, filename); repo.Index.Stage(filename); repo.Commit("comment", Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp.Tests/FilterBranchFixture.cs b/LibGit2Sharp.Tests/FilterBranchFixture.cs new file mode 100644 index 000000000..e0bbdd1ab --- /dev/null +++ b/LibGit2Sharp.Tests/FilterBranchFixture.cs @@ -0,0 +1,375 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using LibGit2Sharp.Tests.TestHelpers; +using Xunit; + +namespace LibGit2Sharp.Tests +{ + public class FilterBranchFixture : BaseFixture + { + private readonly Repository repo; + + public FilterBranchFixture() + { + string path = CloneBareTestRepo(); + repo = new Repository(path); + } + + public override void Dispose() + { + repo.Dispose(); + } + + [Fact] + public void CanRewriteHistoryWithoutChangingCommitMetadata() + { + var originalRefs = repo.Refs.ToList().OrderBy(r => r.CanonicalName); + var commits = repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs }).ToArray(); + + // Noop header rewriter + repo.Refs.RewriteHistory(commits, commitHeaderRewriter: CommitRewriteInfo.From); + + Assert.Equal(originalRefs, repo.Refs.ToList().OrderBy(r => r.CanonicalName)); + Assert.Equal(commits, repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs }).ToArray()); + } + + [Fact] + public void CanRewriteHistoryWithoutChangingTrees() + { + var originalRefs = repo.Refs.ToList().OrderBy(r => r.CanonicalName); + var commits = repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs }).ToArray(); + + // Noop tree rewriter + repo.Refs.RewriteHistory(commits, commitTreeRewriter: TreeDefinition.From); + + Assert.Equal(originalRefs, repo.Refs.ToList().OrderBy(r => r.CanonicalName)); + Assert.Equal(commits, repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs }).ToArray()); + } + + [Fact] + public void CanRewriteAuthorOfCommits() + { + var commits = repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs }).ToArray(); + repo.Refs.RewriteHistory( + commits, + commitHeaderRewriter: c => CommitRewriteInfo.From(c, author: new Signature("Ben Straub", "me@example.com", c.Author.When))); + + var nonBackedUpRefs = repo.Refs.Where(x => !x.CanonicalName.StartsWith("refs/original")); + Assert.Empty(repo.Commits.QueryBy(new CommitFilter { Since = nonBackedUpRefs }) + .Where(c => c.Author.Name != "Ben Straub")); + } + + [Fact] + public void CanRewriteAuthorOfCommitsOnlyBeingPointedAtByTags() + { + var commit = repo.ObjectDatabase.CreateCommit( + "I'm a lonesome commit", Constants.Signature, Constants.Signature, + repo.Head.Tip.Tree, Enumerable.Empty()); + + repo.Tags.Add("so-lonely", commit); + + repo.Tags.Add("so-lonely-but-annotated", commit, Constants.Signature, + "Yeah, baby! I'm going to be rewritten as well"); + + repo.Refs.RewriteHistory( + new[] { commit }, + commitHeaderRewriter: c => CommitRewriteInfo.From(c, message: "Bam!")); + + var lightweightTag = repo.Tags["so-lonely"]; + Assert.Equal("Bam!\n", ((Commit)lightweightTag.Target).Message); + + var annotatedTag = repo.Tags["so-lonely-but-annotated"]; + Assert.Equal("Bam!\n", ((Commit)annotatedTag.Target).Message); + } + + [Fact] + public void CanRewriteTrees() + { + repo.Refs.RewriteHistory(repo.Head.Commits, commitTreeRewriter: c => + { + var td = TreeDefinition.From(c); + td.Remove("README"); + return td; + }); + + Assert.True(repo.Head.Commits.All(c => c["README"] == null)); + } + + // * 41bc8c6 (packed) + // | + // * 5001298 <----- rewrite this commit message + [Fact] + public void OnlyRewriteSelectedCommits() + { + var commit = repo.Branches["packed"].Tip; + var parent = commit.Parents.Single(); + + Assert.True(parent.Sha.StartsWith("5001298")); + Assert.NotEqual(Constants.Signature, commit.Author); + Assert.NotEqual(Constants.Signature, parent.Author); + + repo.Refs.RewriteHistory( + new[] { parent }, + commitHeaderRewriter: c => CommitRewriteInfo.From(c, author: Constants.Signature)); + + commit = repo.Branches["packed"].Tip; + parent = commit.Parents.Single(); + + Assert.False(parent.Sha.StartsWith("5001298")); + Assert.NotEqual(Constants.Signature, commit.Author); + Assert.Equal(Constants.Signature, parent.Author); + } + + [Fact] + public void CanCustomizeTheNamespaceOfBackedUpRefs() + { + repo.Refs.RewriteHistory(repo.Head.Commits, c => CommitRewriteInfo.From(c, message: "")); + Assert.NotEmpty(repo.Refs.Where(x => x.CanonicalName.StartsWith("refs/original"))); + + Assert.Empty(repo.Refs.Where(x => x.CanonicalName.StartsWith("refs/rewritten"))); + + repo.Refs.RewriteHistory(repo.Head.Commits, + commitHeaderRewriter: c => CommitRewriteInfo.From(c, message: "abc"), + backupRefsNamespace: "refs/rewritten"); + + Assert.NotEmpty(repo.Refs.Where(x => x.CanonicalName.StartsWith("refs/rewritten"))); + } + + [Fact] + public void RefRewritingRollsBackOnFailure() + { + IList origRefs = repo.Refs.OrderBy(r => r.CanonicalName).ToArray(); + + const string backupNamespace = "refs/original/"; + + Assert.Throws( + () => + repo.Refs.RewriteHistory( + new[] { repo.Lookup("6dcf9bf7541ee10456529833502442f385010c3d") }, + c => CommitRewriteInfo.From(c, message: ""), + backupRefsNamespace: backupNamespace, + tagNameRewriter: (n, isA, t) => + { + var newRef = repo.Refs.FromGlob(backupNamespace + "*").FirstOrDefault(); + + if (newRef == null) + return n; + + // At least one of the refs have been rewritten + // Let's make sure it's been updated to a new target + var oldName = newRef.CanonicalName.Replace(backupNamespace, "refs/"); + Assert.NotEqual(origRefs.Single(r => r.CanonicalName == oldName), newRef); + + // Violently interrupt the process + throw new Exception("BREAK"); + } + )); + + // Ensure all the refs have been restored to their original targets + var newRefs = repo.Refs.OrderBy(r => r.CanonicalName).ToArray(); + Assert.Equal(newRefs, origRefs); + } + + // This test should rewrite br2, but not packed-test: + // * a4a7dce (br2) Merge branch 'master' into br2 + // |\ + // | * 9fd738e a fourth commit + // | * 4a202b3 (packed-test) a third commit + // * | c47800c branch commit one <----- rewrite this one + // |/ + // * 5b5b025 another commit + // * 8496071 testing + [Fact] + public void DoesNotRewriteRefsThatDontChange() + { + repo.Refs.RewriteHistory(new[] { repo.Lookup("c47800c") }, + c => CommitRewriteInfo.From(c, message: "abc")); + + Assert.Null(repo.Refs["refs/original/heads/packed-test"]); + Assert.NotNull(repo.Refs["refs/original/heads/br2"]); + + // Ensure br2 is still a merge commit + var parents = repo.Branches["br2"].Tip.Parents.ToList(); + Assert.Equal(2, parents.Count()); + Assert.NotEmpty(parents.Where(c => c.Sha.StartsWith("9fd738e"))); + Assert.Equal("abc\n", parents.Single(c => !c.Sha.StartsWith("9fd738e")).Message); + } + + [Fact] + public void CanNotOverWriteBackedUpReferences() + { + Func headerRewriter = c => CommitRewriteInfo.From(c, message: "abc"); + Assert.Empty(repo.Refs.FromGlob("refs/original/*")); + + repo.Refs.RewriteHistory(repo.Head.Commits, commitHeaderRewriter: headerRewriter); + var originalRefs = repo.Refs.FromGlob("refs/original/*").OrderBy(r => r.CanonicalName).ToArray(); + Assert.NotEmpty(originalRefs); + + headerRewriter = c => CommitRewriteInfo.From(c, message: "def"); + + Assert.Throws(() => + repo.Refs.RewriteHistory(repo.Head.Commits, commitHeaderRewriter: headerRewriter)); + Assert.Equal("abc\n", repo.Head.Tip.Message); + + var newOriginalRefs = repo.Refs.FromGlob("refs/original/*").OrderBy(r => r.CanonicalName).ToArray(); + Assert.Equal(originalRefs, newOriginalRefs); + + Assert.Empty(repo.Refs.Where(x => x.CanonicalName.StartsWith("refs/original/original/"))); + } + + [Fact] + public void CanNotOverWriteAnExistingReference() + { + var commits = repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs }).ToArray(); + + Assert.Throws(() => repo.Refs.RewriteHistory(commits, tagNameRewriter: (n, b, t) => "test")); + + Assert.Equal(0, repo.Refs.FromGlob("refs/original/*").Count()); + } + + // Graft the orphan "test" branch to the tip of "packed" + // + // Before: + // * e90810b (test, lw, e90810b, test) + // | + // * 6dcf9bf + // <------------------ note: no connection + // * 41bc8c6 (packed) + // | + // * 5001298 + // + // ... and after: + // + // * f558880 (test, lw, e90810b, test) + // | + // * 0c25efa + // | <------------------ add this link + // * 41bc8c6 (packed) + // | + // * 5001298 + [Fact] + public void CanRewriteParents() + { + var commitToRewrite = repo.Lookup("6dcf9bf"); + var newParent = repo.Lookup("41bc8c6"); + bool hasBeenCalled = false; + + repo.Refs.RewriteHistory(new[] { commitToRewrite }, commitParentsRewriter: originalParents => + { + Assert.False(hasBeenCalled); + Assert.Empty(originalParents); + hasBeenCalled = true; + return new[] { newParent }; + }); + + Assert.Contains(newParent, repo.Lookup("refs/heads/test~").Parents); + Assert.True(hasBeenCalled); + } + + [Fact] + public void WritesCorrectReflogMessagesForSimpleRewrites() + { + repo.Refs.RewriteHistory(repo.Head.Commits, c => CommitRewriteInfo.From(c, message: "")); + + Assert.Equal("filter-branch: rewrite", repo.Refs.Log(repo.Refs["refs/heads/master"]).First().Message); + Assert.Equal("filter-branch: backup", repo.Refs.Log(repo.Refs["refs/original/heads/master"]).First().Message); + } + + [Fact] + public void CanProvideNewNamesForTags() + { + GitObject lwTarget = repo.Tags["lw"].Target; + GitObject e908Target = repo.Tags["e90810b"].Target; + GitObject testTarget = repo.Tags["test"].Target; + + repo.Refs.RewriteHistory(repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs["refs/heads/test"] }), + c => CommitRewriteInfo.From(c, message: ""), + tagNameRewriter: (oldName, isAnnotated, o) => oldName + "_new"); + + Assert.NotEqual(lwTarget, repo.Tags["lw_new"].Target); + Assert.NotEqual(e908Target, repo.Tags["e90810b_new"].Target); + Assert.NotEqual(testTarget, repo.Tags["test_new"].Target); + } + + [Fact(Skip = "Rewriting of symbolic references is not supported yet")] + public void CanRewriteSymbolicRefsPointingToTags() + { + const string tagRefName = "refs/tags/test"; + + repo.Refs.Add("refs/tags/one_tracker", tagRefName); + repo.Refs.Add("refs/tags/another_tracker", tagRefName); + repo.Refs.Add("refs/attic/dusty_tracker", "refs/tags/another_tracker"); + + repo.Refs.RewriteHistory(new[] { repo.Lookup("e90810b8df") }, + c => CommitRewriteInfo.From(c, author: Constants.Signature), + tagNameRewriter: (oldName, isAnnotated, o) => oldName + "_new"); + + // Ensure the initial tags don't exist anymore... + Assert.Null(repo.Refs["refs/tags/one_tracker"]); + Assert.Null(repo.Refs["refs/tags/another_tracker"]); + + // ...and have been backed up. + Assert.Equal(tagRefName, repo.Refs["refs/original/tags/one_tracker"].TargetIdentifier); + Assert.Equal(tagRefName, repo.Refs["refs/original/tags/another_tracker"].TargetIdentifier); + + // Ensure the renamed symref tags points to the renamed target + Assert.Equal(tagRefName + "_new", repo.Refs["refs/tags/one_tracker_new"].TargetIdentifier); + Assert.Equal(tagRefName + "_new", repo.Refs["refs/tags/another_tracker_new"].TargetIdentifier); + + // Ensure that the non tag symref points to a renamed target... + Assert.Equal("refs/tags/another_tracker_new", repo.Refs["refs/attic/dusty_tracker"].TargetIdentifier); + + // ...and has been backed up as well. + Assert.Equal("refs/tags/another_tracker", repo.Refs["refs/original/attic/dusty_tracker"].TargetIdentifier); + } + + [Fact] + public void HandlesNameRewritingOfChainedTags() + { + // Add a lightweight tag (A) that points to tag annotation (B) that points to another tag annotation (C), + // which points to a commit + var theCommit = repo.Lookup("6dcf9bf"); + var annotationC = repo.ObjectDatabase.CreateTagAnnotation("annotationC", theCommit, Constants.Signature, ""); + var annotationB = repo.ObjectDatabase.CreateTagAnnotation("annotationB", annotationC, Constants.Signature, ""); + var tagA = repo.Tags.Add("lightweightA", annotationB); + + // Rewrite the commit, renaming the tag + repo.Refs.RewriteHistory(new[] { repo.Lookup("6dcf9bf") }, + c => CommitRewriteInfo.From(c, message: "Rewrote"), + tagNameRewriter: + (oldName, isAnnoted, newTarget) => + isAnnoted ? oldName + "_ann" : oldName + "_lw"); + + + // Verify the rewritten tag-annotation chain + var newTagA = repo.Tags["lightweightA_lw"]; + Assert.NotNull(newTagA); + Assert.NotEqual(newTagA, tagA); + Assert.True(newTagA.IsAnnotated); + + var newAnnotationB = newTagA.Annotation; + Assert.NotNull(newAnnotationB); + Assert.NotEqual(newAnnotationB, annotationB); + Assert.Equal("annotationB_ann", newAnnotationB.Name); + + var newAnnotationC = newAnnotationB.Target as TagAnnotation; + Assert.NotNull(newAnnotationC); + Assert.NotEqual(newAnnotationC, annotationC); + Assert.Equal("annotationC_ann", newAnnotationC.Name); + + var newCommit = newAnnotationC.Target as Commit; + Assert.NotNull(newCommit); + Assert.NotEqual(newCommit, theCommit); + Assert.Equal("Rewrote\n", newCommit.Message); + + // Ensure the original tag doesn't exist anymore + Assert.Null(repo.Tags["lightweightA"]); + + // ...but it's been backed up + Reference backedUpTag = repo.Refs["refs/original/tags/lightweightA"]; + Assert.NotNull(backedUpTag); + Assert.Equal(annotationB, backedUpTag.ResolveToDirectReference().Target); + } + } +} diff --git a/LibGit2Sharp.Tests/IgnoreFixture.cs b/LibGit2Sharp.Tests/IgnoreFixture.cs index 188e5273d..ef91bd179 100644 --- a/LibGit2Sharp.Tests/IgnoreFixture.cs +++ b/LibGit2Sharp.Tests/IgnoreFixture.cs @@ -14,7 +14,7 @@ public void TemporaryRulesShouldApplyUntilCleared() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, "Foo.cs"), "Bar"); + Touch(repo.Info.WorkingDirectory, "Foo.cs", "Bar"); Assert.True(repo.Index.RetrieveStatus().Untracked.Contains("Foo.cs")); @@ -34,7 +34,7 @@ public void IsPathIgnoredShouldVerifyWhetherPathIsIgnored() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, "Foo.cs"), "Bar"); + Touch(repo.Info.WorkingDirectory, "Foo.cs", "Bar"); Assert.False(repo.Ignore.IsPathIgnored("Foo.cs")); @@ -73,8 +73,7 @@ public void CanCheckIfAPathIsIgnoredUsingThePreferedPlatformDirectorySeparatorCh string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - string ignorePath = Path.Combine(repo.Info.WorkingDirectory, ".gitignore"); - File.WriteAllText(ignorePath, "/NewFolder\n/NewFolder/NewFolder"); + Touch(repo.Info.WorkingDirectory, ".gitignore", "/NewFolder\n/NewFolder/NewFolder"); Assert.False(repo.Ignore.IsPathIgnored("File.txt")); Assert.True(repo.Ignore.IsPathIgnored("NewFolder")); diff --git a/LibGit2Sharp.Tests/IndexFixture.cs b/LibGit2Sharp.Tests/IndexFixture.cs index a1667dc4c..144d03942 100644 --- a/LibGit2Sharp.Tests/IndexFixture.cs +++ b/LibGit2Sharp.Tests/IndexFixture.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using LibGit2Sharp.Tests.TestHelpers; using Xunit; using Xunit.Extensions; @@ -86,18 +85,17 @@ public void ReadIndexWithBadParamsFails() [Fact] public void CanRenameAFile() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Assert.Equal(0, repo.Index.Count); const string oldName = "polite.txt"; - string oldPath = Path.Combine(repo.Info.WorkingDirectory, oldName); Assert.Equal(FileStatus.Nonexistent, repo.Index.RetrieveStatus(oldName)); - File.WriteAllText(oldPath, "hello test file\n", Encoding.ASCII); + Touch(repo.Info.WorkingDirectory, oldName, "hello test file\n"); Assert.Equal(FileStatus.Untracked, repo.Index.RetrieveStatus(oldName)); repo.Index.Stage(oldName); @@ -197,31 +195,21 @@ private static void InvalidMoveUseCases(string sourcePath, FileStatus sourceStat [Fact] public void PathsOfIndexEntriesAreExpressedInNativeFormat() { - // Initialize a new repository - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + // Build relative path + string relFilePath = Path.Combine("directory", "Testfile.txt"); - const string directoryName = "directory"; - const string fileName = "Testfile.txt"; + string repoPath = InitNewRepository(); - // Create a file and insert some content - string directoryPath = Path.Combine(scd.RootedDirectoryPath, directoryName); - string filePath = Path.Combine(directoryPath, fileName); - - Directory.CreateDirectory(directoryPath); - File.WriteAllText(filePath, "Anybody out there?"); - - // Initialize the repository - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { + Touch(repo.Info.WorkingDirectory, relFilePath, "Anybody out there?"); + // Stage the file - repo.Index.Stage(filePath); + repo.Index.Stage(relFilePath); // Get the index Index index = repo.Index; - // Build relative path - string relFilePath = Path.Combine(directoryName, fileName); - // Get the index entry IndexEntry ie = index[relFilePath]; diff --git a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj index f9dc8766f..54fb3772d 100644 --- a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj +++ b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj @@ -59,6 +59,7 @@ + @@ -124,16 +125,19 @@ + + $(MSBuildProjectDirectory)\..\Lib\NativeBinaries + + + \ No newline at end of file diff --git a/LibGit2Sharp.Tests/MergeFixture.cs b/LibGit2Sharp.Tests/MergeFixture.cs index 1d4253b2d..96df06a59 100644 --- a/LibGit2Sharp.Tests/MergeFixture.cs +++ b/LibGit2Sharp.Tests/MergeFixture.cs @@ -1,5 +1,4 @@ -using System.IO; -using System.Linq; +using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; @@ -10,8 +9,9 @@ public class MergeFixture : BaseFixture [Fact] public void ANewRepoIsFullyMerged() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.DirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { Assert.Equal(true, repo.Index.IsFullyMerged); Assert.Empty(repo.MergeHeads); @@ -54,7 +54,7 @@ public void CommitAgainARepoWithUnmergedEntriesThrows() { Assert.Equal(false, repo.Index.IsFullyMerged); - var author = DummySignature; + var author = Constants.Signature; Assert.Throws( () => repo.Commit("Try commit unmerged entries", author, author)); } @@ -69,9 +69,7 @@ public void CanRetrieveTheBranchBeingMerged() const string firstBranch = "9fd738e8f7967c078dceed8190330fc8648ee56a"; const string secondBranch = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; - string mergeHeadPath = Path.Combine(repo.Info.Path, "MERGE_HEAD"); - File.WriteAllText(mergeHeadPath, - string.Format("{0}{1}{2}{1}", firstBranch, "\n", secondBranch)); + Touch(repo.Info.Path, "MERGE_HEAD", string.Format("{0}{1}{2}{1}", firstBranch, "\n", secondBranch)); Assert.Equal(CurrentOperation.Merge, repo.Info.CurrentOperation); diff --git a/LibGit2Sharp.Tests/MetaFixture.cs b/LibGit2Sharp.Tests/MetaFixture.cs index 340f1352e..e37e3a1b7 100644 --- a/LibGit2Sharp.Tests/MetaFixture.cs +++ b/LibGit2Sharp.Tests/MetaFixture.cs @@ -1,10 +1,10 @@ -using System.Diagnostics; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; using System.Text; using Xunit; -using System.Reflection; -using System; -using System.Linq; -using System.Collections.Generic; namespace LibGit2Sharp.Tests { @@ -12,6 +12,8 @@ public class MetaFixture { private static readonly Type[] excludedTypes = new[] { + typeof(CommitFilter), + typeof(CommitRewriteInfo), typeof(CompareOptions), typeof(Credentials), typeof(ExplicitPathsOptions), diff --git a/LibGit2Sharp.Tests/MockedRepositoryFixture.cs b/LibGit2Sharp.Tests/MockedRepositoryFixture.cs index eb552f823..fd3044ac6 100644 --- a/LibGit2Sharp.Tests/MockedRepositoryFixture.cs +++ b/LibGit2Sharp.Tests/MockedRepositoryFixture.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; -using System; +using System; +using System.Collections.Generic; using System.Linq; using LibGit2Sharp.Tests.TestHelpers; -using Xunit; using Moq; +using Xunit; namespace LibGit2Sharp.Tests { diff --git a/LibGit2Sharp.Tests/NetworkFixture.cs b/LibGit2Sharp.Tests/NetworkFixture.cs index 87c9f25cb..870633aa8 100644 --- a/LibGit2Sharp.Tests/NetworkFixture.cs +++ b/LibGit2Sharp.Tests/NetworkFixture.cs @@ -17,8 +17,9 @@ public void CanListRemoteReferences(string url) { string remoteName = "testRemote"; - var scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { Remote remote = repo.Network.Remotes.Add(remoteName, url); IEnumerable references = repo.Network.ListReferences(remote); @@ -38,16 +39,19 @@ public void CanListRemoteReferences(string url) [Fact] public void CanListRemoteReferenceObjects() { - string url = "http://github.com/libgit2/TestGitRepository"; - string remoteName = "origin"; + const string url = "http://github.com/libgit2/TestGitRepository"; + const string remoteName = "origin"; var scd = BuildSelfCleaningDirectory(); - using (Repository repo = Repository.Clone(url, scd.RootedDirectoryPath)) + + string clonedRepoPath = Repository.Clone(url, scd.DirectoryPath); + + using (var repo = new Repository(clonedRepoPath)) { Remote remote = repo.Network.Remotes[remoteName]; IEnumerable references = repo.Network.ListReferences(remote); - List> actualRefs = new List>(); + var actualRefs = new List>(); foreach(DirectReference reference in references) { diff --git a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs index a845e8068..4804a3bb2 100644 --- a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs +++ b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs @@ -54,9 +54,7 @@ public void CanCreateABlobIntoTheDatabaseOfABareRepository() SelfCleaningDirectory directory = BuildSelfCleaningDirectory(); - Directory.CreateDirectory(directory.RootedDirectoryPath); - string filepath = Path.Combine(directory.RootedDirectoryPath, "hello.txt"); - File.WriteAllText(filepath, "I'm a new file\n"); + string filepath = Touch(directory.RootedDirectoryPath, "hello.txt", "I'm a new file\n"); using (var repo = new Repository(path)) { @@ -82,7 +80,7 @@ public void CanCreateABlobIntoTheDatabaseOfABareRepository() [InlineData("321cbdf08803c744082332332838df6bd160f8f9", "dummy.data")] [InlineData("e9671e138a780833cb689753570fd10a55be84fb", "dummy.txt")] [InlineData("e9671e138a780833cb689753570fd10a55be84fb", "dummy.guess")] - public void CanCreateABlobFromABinaryReader(string expectedSha, string hintPath) + public void CanCreateABlobFromAStream(string expectedSha, string hintPath) { string path = CloneBareTestRepo(); @@ -97,20 +95,59 @@ public void CanCreateABlobFromABinaryReader(string expectedSha, string hintPath) 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); + Blob blob = repo.ObjectDatabase.CreateBlob(stream, hintPath); Assert.Equal(expectedSha, blob.Sha); } } } + [Theory] + [InlineData(16, 32)] + [InlineData(34, 8)] + [InlineData(7584, 5879)] + [InlineData(7854, 1247)] + [InlineData(7854, 9785)] + [InlineData(8192, 4096)] + [InlineData(8192, 4095)] + [InlineData(8192, 4097)] + public void CanCreateABlobFromAStreamWithANumberOfBytesToConsume(int contentSize, int numberOfBytesToConsume) + { + string path = CloneBareTestRepo(); + + var sb = new StringBuilder(); + for (int i = 0; i < contentSize; i++) + { + sb.Append(i % 10); + } + + using (var repo = new Repository(path)) + { + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(sb.ToString()))) + { + Blob blob = repo.ObjectDatabase.CreateBlob(stream, numberOfBytesToConsume: numberOfBytesToConsume); + Assert.Equal(Math.Min(numberOfBytesToConsume, contentSize), blob.Size); + } + } + } + + [Fact] + public void CreatingABlobFromANonReadableStreamThrows() + { + string path = CloneStandardTestRepo(); + + using (var stream = new FileStream(Path.Combine(path, "file.txt"), FileMode.CreateNew, FileAccess.Write)) + using (var repo = new Repository(path)) + { + Assert.Throws(() => repo.ObjectDatabase.CreateBlob(stream)); + } + } + 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); + Touch(where, filename, attributes); } [Theory] @@ -274,7 +311,7 @@ public void CanCreateATreeContainingAGitLinkFromAnUntrackedSubmoduleInTheWorking Assert.IsType(te.Target); Assert.Equal(objectId, te.Target.Id); - var commitWithSubmodule = repo.ObjectDatabase.CreateCommit("Submodule!", DummySignature, DummySignature, tree, + var commitWithSubmodule = repo.ObjectDatabase.CreateCommit("Submodule!", Constants.Signature, Constants.Signature, tree, new[] { repo.Head.Tip }); repo.Reset(ResetOptions.Soft, commitWithSubmodule); @@ -311,7 +348,7 @@ public void CanCreateACommit() Tree tree = repo.ObjectDatabase.CreateTree(td); - Commit commit = repo.ObjectDatabase.CreateCommit("Ü message", DummySignature, DummySignature, tree, new[] { repo.Head.Tip }); + Commit commit = repo.ObjectDatabase.CreateCommit("Ü message", Constants.Signature, Constants.Signature, tree, new[] { repo.Head.Tip }); Branch newHead = repo.Head; @@ -322,7 +359,7 @@ public void CanCreateACommit() } [Fact] - public void CanCreateABinaryBlobFromABinaryReader() + public void CanCreateABinaryBlobFromAStream() { var binaryContent = new byte[] { 0, 1, 2, 3, 4, 5 }; @@ -330,9 +367,8 @@ public void CanCreateABinaryBlobFromABinaryReader() using (var repo = new Repository(path)) { using (var stream = new MemoryStream(binaryContent)) - using (var binReader = new BinaryReader(stream)) { - Blob blob = repo.ObjectDatabase.CreateBlob(binReader); + Blob blob = repo.ObjectDatabase.CreateBlob(stream); Assert.Equal(6, blob.Size); Assert.Equal(true, blob.IsBinary); } @@ -348,10 +384,10 @@ public void CanCreateATagAnnotationPointingToAGitObject() var blob = repo.Head.Tip["README"].Target as Blob; Assert.NotNull(blob); - TagAnnotation tag = repo.ObjectDatabase.CreateTag( + TagAnnotation tag = repo.ObjectDatabase.CreateTagAnnotation( "nice_blob", blob, - DummySignature, + Constants.Signature, "I can point at blobs, too!"); Assert.NotNull(tag); diff --git a/LibGit2Sharp.Tests/OdbBackendFixture.cs b/LibGit2Sharp.Tests/OdbBackendFixture.cs index 0f4a93d1e..913ce3f28 100644 --- a/LibGit2Sharp.Tests/OdbBackendFixture.cs +++ b/LibGit2Sharp.Tests/OdbBackendFixture.cs @@ -12,18 +12,18 @@ public class OdbBackendFixture : BaseFixture [Fact] public void SimpleOdbBackendFixtureTest() { - var scd = new SelfCleaningDirectory(this); + string repoPath = InitNewRepository(); - using (Repository repository = Repository.Init(scd.RootedDirectoryPath)) + using (var repository = new Repository(repoPath)) { repository.ObjectDatabase.AddBackend(new MockOdbBackend(), priority: 5); - String filePath = Path.Combine(scd.RootedDirectoryPath, "file.txt"); - String fileContents = "Hello!"; + const string filename = "file.txt"; + const string fileContents = "Hello!"; // Exercises read, write, writestream, exists - File.WriteAllText(filePath, fileContents); - repository.Index.Stage(filePath); + Touch(repository.Info.WorkingDirectory, filename, fileContents); + repository.Index.Stage(filename); var signature = new Signature("SimpleOdbBackendFixtureTest", "user@example.com", DateTimeOffset.Now); repository.Commit(String.Empty, signature, signature); diff --git a/LibGit2Sharp.Tests/PushFixture.cs b/LibGit2Sharp.Tests/PushFixture.cs index cc7db8d9f..d8d8a2311 100644 --- a/LibGit2Sharp.Tests/PushFixture.cs +++ b/LibGit2Sharp.Tests/PushFixture.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; @@ -17,8 +16,12 @@ private void OnPushStatusError(PushStatusError pushStatusErrors) private void AssertPush(Action push) { var scd = BuildSelfCleaningDirectory(); - using (var originalRepo = new Repository(CloneBareTestRepo())) - using (Repository clonedRepo = Repository.Clone(originalRepo.Info.Path, scd.RootedDirectoryPath)) + + string originalRepoPath = CloneBareTestRepo(); + string clonedRepoPath = Repository.Clone(originalRepoPath, scd.DirectoryPath); + + using (var originalRepo = new Repository(originalRepoPath)) + using (var clonedRepo = new Repository(clonedRepoPath)) { Remote remote = clonedRepo.Network.Remotes["origin"]; @@ -31,10 +34,9 @@ private void AssertPush(Action push) // Change local state (commit) const string relativeFilepath = "new_file.txt"; - string filePath = Path.Combine(clonedRepo.Info.WorkingDirectory, relativeFilepath); - File.WriteAllText(filePath, "__content__"); + Touch(clonedRepo.Info.WorkingDirectory, relativeFilepath, "__content__"); clonedRepo.Index.Stage(relativeFilepath); - clonedRepo.Commit("__commit_message__", DummySignature, DummySignature); + clonedRepo.Commit("__commit_message__", Constants.Signature, Constants.Signature); // Assert local state has changed Assert.NotEqual(originalRepo.Refs["HEAD"].ResolveToDirectReference().TargetIdentifier, diff --git a/LibGit2Sharp.Tests/ReferenceFixture.cs b/LibGit2Sharp.Tests/ReferenceFixture.cs index 85da6bb44..308908aac 100644 --- a/LibGit2Sharp.Tests/ReferenceFixture.cs +++ b/LibGit2Sharp.Tests/ReferenceFixture.cs @@ -737,9 +737,9 @@ public void CanTellIfAReferenceIsValid(string refname, bool expectedResult) [Fact] public void CanUpdateTheTargetOfASymbolicReferenceWithAnotherSymbolicReference() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Reference symbolicRef = repo.Refs.Add("refs/heads/unit_test", "refs/heads/master"); @@ -778,5 +778,59 @@ public void CanIdentifyReferenceKind() Assert.True(repo.Refs["refs/notes/commits"].IsNote()); } } + + [Fact] + public void CanQueryReachability() + { + using (var repo = new Repository(StandardTestRepoWorkingDirPath)) + { + var result = repo.Refs.ReachableFrom( + new[] { repo.Lookup("f8d44d7"), repo.Lookup("6dcf9bf") }); + + var expected = new[] + { + "refs/heads/diff-test-cases", + "refs/heads/i-do-numbers", + "refs/remotes/origin/test", + "refs/tags/e90810b", + "refs/tags/lw", + "refs/tags/test", + }; + + Assert.Equal(expected, result.Select(x => x.CanonicalName).OrderBy(x => x).ToList()); + } + } + + [Fact] + public void CanQueryReachabilityAmongASubsetOfreferences() + { + using (var repo = new Repository(StandardTestRepoWorkingDirPath)) + { + var result = repo.Refs.ReachableFrom( + repo.Refs.Where(r => r.IsTag()), + new[] { repo.Lookup("f8d44d7"), repo.Lookup("6dcf9bf") }); + + var expected = new[] + { + "refs/tags/e90810b", + "refs/tags/lw", + "refs/tags/test", + }; + + Assert.Equal(expected, result.Select(x => x.CanonicalName).OrderBy(x => x).ToList()); + } + } + + [Fact] + public void CanHandleInvalidArguments() + { + using (var repo = new Repository(StandardTestRepoWorkingDirPath)) + { + Assert.Throws(() => repo.Refs.ReachableFrom(null)); + Assert.Throws(() => repo.Refs.ReachableFrom(null, repo.Commits.Take(2))); + Assert.Throws(() => repo.Refs.ReachableFrom(repo.Refs, null)); + Assert.Empty(repo.Refs.ReachableFrom(new Commit[] { })); + } + } } } diff --git a/LibGit2Sharp.Tests/ReflogFixture.cs b/LibGit2Sharp.Tests/ReflogFixture.cs index a10bf3a9d..7f4093bea 100644 --- a/LibGit2Sharp.Tests/ReflogFixture.cs +++ b/LibGit2Sharp.Tests/ReflogFixture.cs @@ -1,6 +1,5 @@ -using System.IO; +using System.Linq; using LibGit2Sharp.Tests.TestHelpers; -using System.Linq; using Xunit; namespace LibGit2Sharp.Tests @@ -42,9 +41,9 @@ public void CannotReadReflogOnUnknownReference() [Fact] public void CommitShouldCreateReflogEntryOnHeadandOnTargetedDirectReference() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { // setup refs as HEAD => unit_test => master var newRef = repo.Refs.Add("refs/heads/unit_test", "refs/heads/master"); @@ -52,12 +51,10 @@ public void CommitShouldCreateReflogEntryOnHeadandOnTargetedDirectReference() repo.Refs.UpdateTarget(repo.Refs.Head, newRef); const string relativeFilepath = "new.txt"; - string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath); - - File.WriteAllText(filePath, "content\n"); + Touch(repo.Info.WorkingDirectory, relativeFilepath, "content\n"); repo.Index.Stage(relativeFilepath); - var author = DummySignature; + var author = Constants.Signature; const string commitMessage = "Hope reflog behaves as it should"; Commit commit = repo.Commit(commitMessage, author, author); @@ -83,17 +80,15 @@ public void CommitShouldCreateReflogEntryOnHeadandOnTargetedDirectReference() [Fact] public void CommitOnUnbornReferenceShouldCreateReflogEntryWithInitialTag() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { const string relativeFilepath = "new.txt"; - string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath); - - File.WriteAllText(filePath, "content\n"); + Touch(repo.Info.WorkingDirectory, relativeFilepath, "content\n"); repo.Index.Stage(relativeFilepath); - var author = DummySignature; + var author = Constants.Signature; const string commitMessage = "First commit should be logged as initial"; repo.Commit(commitMessage, author, author); @@ -117,12 +112,10 @@ public void CommitOnDetachedHeadShouldInsertReflogEntry() Assert.True(repo.Info.IsHeadDetached); const string relativeFilepath = "new.txt"; - string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath); - - File.WriteAllText(filePath, "content\n"); + Touch(repo.Info.WorkingDirectory, relativeFilepath, "content\n"); repo.Index.Stage(relativeFilepath); - var author = DummySignature; + var author = Constants.Signature; const string commitMessage = "Commit on detached head"; var commit = repo.Commit(commitMessage, author, author); diff --git a/LibGit2Sharp.Tests/RemoteFixture.cs b/LibGit2Sharp.Tests/RemoteFixture.cs index 7aa842893..02a293b27 100644 --- a/LibGit2Sharp.Tests/RemoteFixture.cs +++ b/LibGit2Sharp.Tests/RemoteFixture.cs @@ -44,6 +44,29 @@ public void CanEnumerateTheRemotes() } } + [Theory] + [InlineData(TagFetchMode.All)] + [InlineData(TagFetchMode.Auto)] + [InlineData(TagFetchMode.None)] + public void CanSetTagFetchMode(TagFetchMode tagFetchMode) + { + string path = CloneBareTestRepo(); + using (var repo = new Repository(path)) + { + const string name = "upstream"; + const string url = "https://github.com/libgit2/libgit2sharp.git"; + + repo.Network.Remotes.Add(name, url); + Remote remote = repo.Network.Remotes[name]; + Assert.NotNull(remote); + + Remote updatedremote = repo.Network.Remotes.Update(remote, + r => r.TagFetchMode = tagFetchMode); + + Assert.Equal(tagFetchMode, updatedremote.TagFetchMode); + } + } + [Fact] public void CanCheckEqualityOfRemote() { diff --git a/LibGit2Sharp.Tests/RepositoryFixture.cs b/LibGit2Sharp.Tests/RepositoryFixture.cs index 6a8819767..a0640aa5f 100644 --- a/LibGit2Sharp.Tests/RepositoryFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryFixture.cs @@ -14,8 +14,9 @@ public class RepositoryFixture : BaseFixture [Fact] public void CanCreateBareRepo() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.DirectoryPath, true)) + string repoPath = InitNewRepository(true); + + using (var repo = new Repository(repoPath)) { string dir = repo.Info.Path; Assert.True(Path.IsPathRooted(dir)); @@ -23,7 +24,7 @@ public void CanCreateBareRepo() CheckGitConfigFile(dir); Assert.Null(repo.Info.WorkingDirectory); - Assert.Equal(scd.RootedDirectoryPath + Path.DirectorySeparatorChar, repo.Info.Path); + Assert.Equal(Path.GetFullPath(repoPath), repo.Info.Path); Assert.True(repo.Info.IsBare); AssertInitializedRepository(repo, "refs/heads/master"); @@ -43,15 +44,26 @@ public void AccessingTheIndexInABareRepoThrows() } [Fact] - public void CanCreateStandardRepo() + public void CanCheckIfADirectoryLeadsToAValidRepository() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); Assert.False(Repository.IsValid(scd.DirectoryPath)); - using (var repo = Repository.Init(scd.DirectoryPath)) + Directory.CreateDirectory(scd.DirectoryPath); + + Assert.False(Repository.IsValid(scd.DirectoryPath)); + } + + [Fact] + public void CanCreateStandardRepo() + { + string repoPath = InitNewRepository(); + + Assert.True(Repository.IsValid(repoPath)); + + using (var repo = new Repository(repoPath)) { - Assert.True(Repository.IsValid(scd.DirectoryPath)); Assert.True(Repository.IsValid(repo.Info.WorkingDirectory)); Assert.True(Repository.IsValid(repo.Info.Path)); @@ -61,7 +73,7 @@ public void CanCreateStandardRepo() CheckGitConfigFile(dir); Assert.NotNull(repo.Info.WorkingDirectory); - Assert.Equal(Path.Combine(scd.RootedDirectoryPath, ".git" + Path.DirectorySeparatorChar), repo.Info.Path); + Assert.Equal(repoPath, repo.Info.Path); Assert.False(repo.Info.IsBare); AssertIsHidden(repo.Info.Path); @@ -73,6 +85,54 @@ public void CanCreateStandardRepo() } } + [Fact] + public void CanCreateStandardRepoAndSpecifyAFolderWhichWillContainTheNewlyCreatedGitDirectory() + { + var scd1 = BuildSelfCleaningDirectory(); + var scd2 = BuildSelfCleaningDirectory(); + + string repoPath = Repository.Init(scd1.DirectoryPath, scd2.DirectoryPath); + + Assert.True(Repository.IsValid(repoPath)); + + using (var repo = new Repository(repoPath)) + { + Assert.True(Repository.IsValid(repo.Info.WorkingDirectory)); + Assert.True(Repository.IsValid(repo.Info.Path)); + + Assert.Equal(false, repo.Info.IsBare); + + char sep = Path.DirectorySeparatorChar; + Assert.Equal(scd1.RootedDirectoryPath + sep, repo.Info.WorkingDirectory); + Assert.Equal(scd2.RootedDirectoryPath + sep + ".git" + sep, repo.Info.Path); + } + } + + [Fact] + public void CanCreateStandardRepoAndDirectlySpecifyAGitDirectory() + { + var scd1 = BuildSelfCleaningDirectory(); + var scd2 = BuildSelfCleaningDirectory(); + + var gitDir = Path.Combine(scd2.DirectoryPath, ".git/"); + + string repoPath = Repository.Init(scd1.DirectoryPath, gitDir); + + Assert.True(Repository.IsValid(repoPath)); + + using (var repo = new Repository(repoPath)) + { + Assert.True(Repository.IsValid(repo.Info.WorkingDirectory)); + Assert.True(Repository.IsValid(repo.Info.Path)); + + Assert.Equal(false, repo.Info.IsBare); + + char sep = Path.DirectorySeparatorChar; + Assert.Equal(scd1.RootedDirectoryPath + sep, repo.Info.WorkingDirectory); + Assert.Equal(Path.GetFullPath(gitDir), repo.Info.Path); + } + } + private static void CheckGitConfigFile(string dir) { string configFilePath = Path.Combine(dir, "config"); @@ -95,8 +155,9 @@ public void CanFetchFromRemoteByName() string remoteName = "testRemote"; string url = "http://github.com/libgit2/TestGitRepository"; - var scd = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd.RootedDirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { Remote remote = repo.Network.Remotes.Add(remoteName, url); @@ -143,12 +204,16 @@ public void CanFetchFromRemoteByName() [Fact] public void CanReinitARepository() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (Repository repository = Repository.Init(scd.DirectoryPath)) - using (Repository repository2 = Repository.Init(scd.DirectoryPath)) + using (var repository = new Repository(repoPath)) { - Assert.Equal(repository2.Info.Path, repository.Info.Path); + string repoPath2 = Repository.Init(repoPath, false); + + using (var repository2 = new Repository(repoPath2)) + { + Assert.Equal(repository2.Info.Path, repository.Info.Path); + } } } @@ -176,11 +241,11 @@ private static void AssertInitializedRepository(Repository repo, string expected Assert.Null(repo.Head.Tip); Assert.Equal(0, repo.Commits.Count()); - Assert.Equal(0, repo.Commits.QueryBy(new Filter()).Count()); - Assert.Equal(0, repo.Commits.QueryBy(new Filter { Since = repo.Refs.Head }).Count()); - Assert.Equal(0, repo.Commits.QueryBy(new Filter { Since = repo.Head }).Count()); - Assert.Equal(0, repo.Commits.QueryBy(new Filter { Since = "HEAD" }).Count()); - Assert.Equal(0, repo.Commits.QueryBy(new Filter { Since = expectedHeadTargetIdentifier }).Count()); + Assert.Equal(0, repo.Commits.QueryBy(new CommitFilter()).Count()); + Assert.Equal(0, repo.Commits.QueryBy(new CommitFilter { Since = repo.Refs.Head }).Count()); + Assert.Equal(0, repo.Commits.QueryBy(new CommitFilter { Since = repo.Head }).Count()); + Assert.Equal(0, repo.Commits.QueryBy(new CommitFilter { Since = "HEAD" }).Count()); + Assert.Equal(0, repo.Commits.QueryBy(new CommitFilter { Since = expectedHeadTargetIdentifier }).Count()); Assert.Null(repo.Head["subdir/I-do-not-exist"]); @@ -338,14 +403,13 @@ public void CanLookupWhithShortIdentifers() const string expectedAbbrevSha = "fe8410b"; const string expectedSha = expectedAbbrevSha + "6bfdf69ccfd4f397110d61f8070e46e40"; - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { - string filePath = Path.Combine(repo.Info.WorkingDirectory, "new.txt"); - - File.WriteAllText(filePath, "one "); - repo.Index.Stage(filePath); + const string filename = "new.txt"; + Touch(repo.Info.WorkingDirectory, filename, "one "); + repo.Index.Stage(filename); Signature author = Constants.Signature; Commit commit = repo.Commit("Initial commit", author, author); @@ -493,7 +557,7 @@ public void QueryingTheRemoteForADetachedHeadBranchReturnsNull() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - repo.Checkout(repo.Head.Tip.Sha, CheckoutOptions.Force, null); + repo.Checkout(repo.Head.Tip.Sha, CheckoutModifiers.Force, null, null); Branch trackLocal = repo.Head; Assert.Null(trackLocal.Remote); } @@ -502,9 +566,9 @@ public void QueryingTheRemoteForADetachedHeadBranchReturnsNull() [Fact] public void ReadingEmptyRepositoryMessageReturnsNull() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Assert.Null(repo.Info.Message); } @@ -513,12 +577,13 @@ public void ReadingEmptyRepositoryMessageReturnsNull() [Fact] public void CanReadRepositoryMessage() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); string testMessage = "This is a test message!"; - using (var repo = Repository.Init(scd.DirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { - File.WriteAllText(Path.Combine(repo.Info.Path, "MERGE_MSG"), testMessage); + Touch(repo.Info.Path, "MERGE_MSG", testMessage); Assert.Equal(testMessage, repo.Info.Message); } @@ -527,9 +592,9 @@ public void CanReadRepositoryMessage() [Fact] public void AccessingADeletedHeadThrows() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Assert.NotNull(repo.Head); diff --git a/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs b/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs index b62de3c76..64acdd04f 100644 --- a/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs @@ -129,11 +129,11 @@ private string MeanwhileInAnotherDimensionAnEvilMastermindIsAtWork(string workin sneakyRepo.Reset(ResetOptions.Mixed, sneakyRepo.Head.Tip.Sha); - var filepath = Path.Combine(sneakyRepo.Info.WorkingDirectory, "zomg.txt"); - File.WriteAllText(filepath, "I'm being sneaked in!\n"); + const string filename = "zomg.txt"; + Touch(sneakyRepo.Info.WorkingDirectory, filename, "I'm being sneaked in!\n"); - sneakyRepo.Index.Stage(filepath); - return sneakyRepo.Commit("Tadaaaa!", DummySignature, DummySignature).Sha; + sneakyRepo.Index.Stage(filename); + return sneakyRepo.Commit("Tadaaaa!", Constants.Signature, Constants.Signature).Sha; } } @@ -174,72 +174,5 @@ public void CanProvideDifferentConfigurationFilesToARepository() AssertValueInConfigFile(systemLocation, "xpaulbettsx"); } - - [Fact] - public void CanProvideDifferentWorkingDirOnInit() - { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - var options = new RepositoryOptions {WorkingDirectoryPath = newWorkdir}; - - using (var repo = Repository.Init(scd.DirectoryPath, false, options)) - { - Assert.Equal(Path.GetFullPath(newWorkdir) + Path.DirectorySeparatorChar, repo.Info.WorkingDirectory); - } - } - - [Fact] - public void CanProvideDifferentConfigurationFilesOnInit() - { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - var options = BuildFakeConfigs(scd); - - using (var repo = Repository.Init(scd.DirectoryPath, false, options)) - { - Assert.True(repo.Config.HasConfig(ConfigurationLevel.Global)); - Assert.Equal("global", repo.Config.Get("woot.this-rocks").Value); - Assert.Equal(42, repo.Config.Get("wow.man-I-am-totally-global").Value); - - Assert.True(repo.Config.HasConfig(ConfigurationLevel.Xdg)); - Assert.Equal("xdg", repo.Config.Get("woot.this-rocks", ConfigurationLevel.Xdg).Value); - - Assert.True(repo.Config.HasConfig(ConfigurationLevel.System)); - Assert.Equal("system", repo.Config.Get("woot.this-rocks", ConfigurationLevel.System).Value); - } - } - - [Fact] - public void CanProvideDifferentWorkingDirOnClone() - { - string url = "https://github.com/libgit2/TestGitRepository"; - var scd = BuildSelfCleaningDirectory(); - var options = new RepositoryOptions { WorkingDirectoryPath = newWorkdir }; - - using (var repo = Repository.Clone(url, scd.DirectoryPath, false, true, null, null, options)) - { - Assert.Equal(Path.GetFullPath(newWorkdir) + Path.DirectorySeparatorChar, repo.Info.WorkingDirectory); - } - } - - [Fact] - public void CanProvideDifferentConfigurationFilesOnClone() - { - string url = "https://github.com/libgit2/TestGitRepository"; - var scd = BuildSelfCleaningDirectory(); - var configScd = BuildSelfCleaningDirectory(); - var options = BuildFakeConfigs(configScd); - - using (var repo = Repository.Clone(url, scd.DirectoryPath, false, true, null, null, options)) - { - Assert.True(repo.Config.HasConfig(ConfigurationLevel.Global)); - Assert.Equal("global", repo.Config.Get("woot.this-rocks").Value); - Assert.Equal(42, repo.Config.Get("wow.man-I-am-totally-global").Value); - - Assert.True(repo.Config.HasConfig(ConfigurationLevel.Xdg)); - Assert.Equal("xdg", repo.Config.Get("woot.this-rocks", ConfigurationLevel.Xdg).Value); - - Assert.True(repo.Config.HasConfig(ConfigurationLevel.System)); - Assert.Equal("system", repo.Config.Get("woot.this-rocks", ConfigurationLevel.System).Value); - } - } } } diff --git a/LibGit2Sharp.Tests/ResetHeadFixture.cs b/LibGit2Sharp.Tests/ResetHeadFixture.cs index 18c392c13..e6c8e88d5 100644 --- a/LibGit2Sharp.Tests/ResetHeadFixture.cs +++ b/LibGit2Sharp.Tests/ResetHeadFixture.cs @@ -14,9 +14,9 @@ public class ResetHeadFixture : BaseFixture [InlineData(false)] public void ResetANewlyInitializedRepositoryThrows(bool isBare) { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(isBare); - using (var repo = Repository.Init(scd.DirectoryPath, isBare)) + using (var repo = new Repository(repoPath)) { Assert.Throws(() => repo.Reset(ResetOptions.Soft)); } @@ -91,9 +91,9 @@ public void SoftResetSetsTheDetachedHeadToTheSpecifiedCommit() private void AssertSoftReset(Func branchIdentifierRetriever, bool shouldHeadBeDetached, Func expectedHeadNameRetriever) { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { FeedTheRepository(repo); @@ -131,8 +131,7 @@ private void AssertSoftReset(Func branchIdentifierRetriever, boo private static void FeedTheRepository(Repository repo) { - string fullPath = Path.Combine(repo.Info.WorkingDirectory, "a.txt"); - File.WriteAllText(fullPath, "Hello\n"); + string fullPath = Touch(repo.Info.WorkingDirectory, "a.txt", "Hello\n"); repo.Index.Stage(fullPath); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); repo.ApplyTag("mytag"); @@ -152,9 +151,9 @@ private static void FeedTheRepository(Repository repo) [Fact] public void MixedResetRefreshesTheIndex() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { FeedTheRepository(repo); @@ -196,7 +195,7 @@ public void HardResetUpdatesTheContentOfTheWorkingDirectory() var names = new DirectoryInfo(repo.Info.WorkingDirectory).GetFileSystemInfos().Select(fsi => fsi.Name).ToList(); File.Delete(Path.Combine(repo.Info.WorkingDirectory, "README")); - File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, "WillNotBeRemoved.txt"), "content\n"); + Touch(repo.Info.WorkingDirectory, "WillNotBeRemoved.txt", "content\n"); Assert.True(names.Count > 4); diff --git a/LibGit2Sharp.Tests/ResetIndexFixture.cs b/LibGit2Sharp.Tests/ResetIndexFixture.cs index b9903b579..0232ae0c7 100644 --- a/LibGit2Sharp.Tests/ResetIndexFixture.cs +++ b/LibGit2Sharp.Tests/ResetIndexFixture.cs @@ -10,9 +10,9 @@ public class ResetIndexFixture : BaseFixture [Fact] public void ResetANewlyInitializedBareRepositoryThrows() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(true); - using (Repository repo = Repository.Init(scd.DirectoryPath, true)) + using (var repo = new Repository(repoPath)) { Assert.Throws(() => repo.Reset()); } @@ -21,9 +21,9 @@ public void ResetANewlyInitializedBareRepositoryThrows() [Fact] public void ResetANewlyInitializedNonBareRepositoryThrows() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(false); - using (Repository repo = Repository.Init(scd.DirectoryPath, false)) + using (var repo = new Repository(repoPath)) { Assert.Throws(() => repo.Reset()); } diff --git a/LibGit2Sharp.Tests/StageFixture.cs b/LibGit2Sharp.Tests/StageFixture.cs index 280710379..1c69a8c87 100644 --- a/LibGit2Sharp.Tests/StageFixture.cs +++ b/LibGit2Sharp.Tests/StageFixture.cs @@ -45,7 +45,7 @@ public void CanStageTheUpdationOfAStagedFile() Assert.Equal(FileStatus.Added, repo.Index.RetrieveStatus(filename)); - File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, filename), "brand new content"); + Touch(repo.Info.WorkingDirectory, filename, "brand new content"); Assert.Equal(FileStatus.Added | FileStatus.Modified, repo.Index.RetrieveStatus(filename)); repo.Index.Stage(filename); @@ -136,7 +136,7 @@ public void CanStageANewFileInAPersistentManner() Assert.Equal(FileStatus.Nonexistent, repo.Index.RetrieveStatus(filename)); Assert.Null(repo.Index[filename]); - File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, filename), "some contents"); + Touch(repo.Info.WorkingDirectory, filename, "some contents"); Assert.Equal(FileStatus.Untracked, repo.Index.RetrieveStatus(filename)); Assert.Null(repo.Index[filename]); @@ -158,8 +158,13 @@ public void CanStageANewFileInAPersistentManner() [InlineData(true)] public void CanStageANewFileWithAFullPath(bool ignorecase) { - InconclusiveIf(() => IsFileSystemCaseSensitive && ignorecase, - "Skipping 'ignorecase = true' test on case-sensitive file system."); + // Skipping due to ignorecase issue in libgit2. + // See: https://github.com/libgit2/libgit2/pull/1689. + InconclusiveIf(() => ignorecase, + "Skipping 'ignorecase = true' test due to ignorecase issue in libgit2."); + + //InconclusiveIf(() => IsFileSystemCaseSensitive && ignorecase, + // "Skipping 'ignorecase = true' test on case-sensitive file system."); string path = CloneStandardTestRepo(); @@ -203,10 +208,9 @@ public void CanStageANewFileWithARelativePathContainingNativeDirectorySeparatorC { int count = repo.Index.Count; - DirectoryInfo di = Directory.CreateDirectory(Path.Combine(repo.Info.WorkingDirectory, "Project")); string file = Path.Combine("Project", "a_file.txt"); - File.WriteAllText(Path.Combine(di.FullName, "a_file.txt"), "With backward slash on Windows!"); + Touch(repo.Info.WorkingDirectory, file, "With backward slash on Windows!"); repo.Index.Stage(file); @@ -225,11 +229,7 @@ public void StagingANewFileWithAFullPathWhichEscapesOutOfTheWorkingDirThrows() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - DirectoryInfo di = Directory.CreateDirectory(scd.DirectoryPath); - - const string filename = "unit_test.txt"; - string fullPath = Path.Combine(di.FullName, filename); - File.WriteAllText(fullPath, "some contents"); + string fullPath = Touch(scd.RootedDirectoryPath, "unit_test.txt", "some contents"); Assert.Throws(() => repo.Index.Stage(fullPath)); } diff --git a/LibGit2Sharp.Tests/StashFixture.cs b/LibGit2Sharp.Tests/StashFixture.cs index 2349aa3e4..2417a70f2 100644 --- a/LibGit2Sharp.Tests/StashFixture.cs +++ b/LibGit2Sharp.Tests/StashFixture.cs @@ -15,9 +15,9 @@ public void CannotAddStashAgainstBareRepository() string path = CloneBareTestRepo(); using (var repo = new Repository(path)) { - var stasher = DummySignature; + var stasher = Constants.Signature; - Assert.Throws(() => repo.Stashes.Add(stasher, "My very first stash")); + Assert.Throws(() => repo.Stashes.Add(stasher, "My very first stash", StashModifiers.Default)); } } @@ -27,29 +27,31 @@ public void CanAddAndRemoveStash() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - var stasher = DummySignature; + var stasher = Constants.Signature; Assert.True(repo.Index.RetrieveStatus().IsDirty); - Stash stash = repo.Stashes.Add(stasher, "My very first stash", StashOptions.IncludeUntracked); + Stash stash = repo.Stashes.Add(stasher, "My very first stash", StashModifiers.IncludeUntracked); // Check that untracked files are deleted from working directory - Assert.False(File.Exists(Path.Combine(repo.Info.WorkingDirectory, "new_untracked_file.txt"))); + string untrackedFilename = "new_untracked_file.txt"; + Assert.False(File.Exists(Path.Combine(repo.Info.WorkingDirectory, untrackedFilename))); + Assert.NotNull(stash.Untracked[untrackedFilename]); Assert.NotNull(stash); Assert.Equal("stash@{0}", stash.CanonicalName); Assert.Contains("My very first stash", stash.Message); var stashRef = repo.Refs["refs/stash"]; - Assert.Equal(stash.Target.Sha, stashRef.TargetIdentifier); + Assert.Equal(stash.WorkTree.Sha, stashRef.TargetIdentifier); Assert.False(repo.Index.RetrieveStatus().IsDirty); // Create extra file - string newFileFullPath = Path.Combine(repo.Info.WorkingDirectory, "stash_candidate.txt"); - File.WriteAllText(newFileFullPath, "Oh, I'm going to be stashed!\n"); + untrackedFilename = "stash_candidate.txt"; + Touch(repo.Info.WorkingDirectory, untrackedFilename, "Oh, I'm going to be stashed!\n"); - Stash secondStash = repo.Stashes.Add(stasher, "My second stash", StashOptions.IncludeUntracked); + Stash secondStash = repo.Stashes.Add(stasher, "My second stash", StashModifiers.IncludeUntracked); Assert.NotNull(stash); Assert.Equal("stash@{0}", stash.CanonicalName); @@ -59,20 +61,22 @@ public void CanAddAndRemoveStash() Assert.Equal("stash@{0}", repo.Stashes.First().CanonicalName); Assert.Equal("stash@{1}", repo.Stashes.Last().CanonicalName); + Assert.NotNull(secondStash.Untracked[untrackedFilename]); + // Stash history has been shifted - Assert.Equal(repo.Lookup("stash@{0}").Sha, secondStash.Target.Sha); - Assert.Equal(repo.Lookup("stash@{1}").Sha, stash.Target.Sha); + Assert.Equal(repo.Lookup("stash@{0}").Sha, secondStash.WorkTree.Sha); + Assert.Equal(repo.Lookup("stash@{1}").Sha, stash.WorkTree.Sha); //Remove one stash repo.Stashes.Remove(0); Assert.Equal(1, repo.Stashes.Count()); Stash newTopStash = repo.Stashes.First(); Assert.Equal("stash@{0}", newTopStash.CanonicalName); - Assert.Equal(stash.Target.Sha, newTopStash.Target.Sha); + Assert.Equal(stash.WorkTree.Sha, newTopStash.WorkTree.Sha); // Stash history has been shifted - Assert.Equal(stash.Target.Sha, repo.Lookup("stash").Sha); - Assert.Equal(stash.Target.Sha, repo.Lookup("stash@{0}").Sha); + Assert.Equal(stash.WorkTree.Sha, repo.Lookup("stash").Sha); + Assert.Equal(stash.WorkTree.Sha, repo.Lookup("stash@{0}").Sha); } } @@ -82,16 +86,16 @@ public void AddingAStashWithNoMessageGeneratesADefaultOne() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - var stasher = DummySignature; + var stasher = Constants.Signature; - Stash stash = repo.Stashes.Add(stasher); + Stash stash = repo.Stashes.Add(stasher, options: StashModifiers.Default); Assert.NotNull(stash); Assert.Equal("stash@{0}", stash.CanonicalName); - Assert.NotEmpty(stash.Target.Message); + Assert.NotEmpty(stash.WorkTree.Message); var stashRef = repo.Refs["refs/stash"]; - Assert.Equal(stash.Target.Sha, stashRef.TargetIdentifier); + Assert.Equal(stash.WorkTree.Sha, stashRef.TargetIdentifier); } } @@ -101,7 +105,7 @@ public void AddStashWithBadParamsShouldThrows() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - Assert.Throws(() => repo.Stashes.Add(null)); + Assert.Throws(() => repo.Stashes.Add(default(Signature), options: StashModifiers.Default)); } } @@ -111,14 +115,14 @@ public void StashingAgainstCleanWorkDirShouldReturnANullStash() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - var stasher = DummySignature; + var stasher = Constants.Signature; - Stash stash = repo.Stashes.Add(stasher, "My very first stash", StashOptions.IncludeUntracked); + Stash stash = repo.Stashes.Add(stasher, "My very first stash", StashModifiers.IncludeUntracked); Assert.NotNull(stash); //Stash against clean working directory - Assert.Null(repo.Stashes.Add(stasher)); + Assert.Null(repo.Stashes.Add(stasher, options: StashModifiers.Default)); } } @@ -128,24 +132,26 @@ public void CanStashWithoutOptions() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - var stasher = DummySignature; + var stasher = Constants.Signature; - var untrackedFilePath = Path.Combine(repo.Info.WorkingDirectory, "new_untracked_file.txt"); - File.WriteAllText(untrackedFilePath, "I'm untracked\n"); + const string untracked = "new_untracked_file.txt"; + Touch(repo.Info.WorkingDirectory, untracked, "I'm untracked\n"); - string stagedfilePath = Path.Combine(repo.Info.WorkingDirectory, "staged_file_path.txt"); - File.WriteAllText(stagedfilePath, "I'm staged\n"); - repo.Index.Stage(stagedfilePath); + const string staged = "staged_file_path.txt"; + Touch(repo.Info.WorkingDirectory, staged, "I'm staged\n"); + repo.Index.Stage(staged); - Stash stash = repo.Stashes.Add(stasher, "Stash with default options"); + Stash stash = repo.Stashes.Add(stasher, "Stash with default options", StashModifiers.Default); Assert.NotNull(stash); //It should not keep staged files - Assert.Equal(FileStatus.Nonexistent, repo.Index.RetrieveStatus("staged_file_path.txt")); + Assert.Equal(FileStatus.Nonexistent, repo.Index.RetrieveStatus(staged)); + Assert.NotNull(stash.Index[staged]); //It should leave untracked files untracked - Assert.Equal(FileStatus.Untracked, repo.Index.RetrieveStatus("new_untracked_file.txt")); + Assert.Equal(FileStatus.Untracked, repo.Index.RetrieveStatus(untracked)); + Assert.Null(stash.Untracked); } } @@ -155,16 +161,18 @@ public void CanStashAndKeepIndex() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - var stasher = DummySignature; + var stasher = Constants.Signature; - string stagedfilePath = Path.Combine(repo.Info.WorkingDirectory, "staged_file_path.txt"); - File.WriteAllText(stagedfilePath, "I'm staged\n"); - repo.Index.Stage(stagedfilePath); + const string filename = "staged_file_path.txt"; + Touch(repo.Info.WorkingDirectory, filename, "I'm staged\n"); + repo.Index.Stage(filename); - Stash stash = repo.Stashes.Add(stasher, "This stash wil keep index", StashOptions.KeepIndex); + Stash stash = repo.Stashes.Add(stasher, "This stash will keep index", StashModifiers.KeepIndex); Assert.NotNull(stash); - Assert.Equal(FileStatus.Added, repo.Index.RetrieveStatus("staged_file_path.txt")); + Assert.NotNull(stash.Index[filename]); + Assert.Equal(FileStatus.Added, repo.Index.RetrieveStatus(filename)); + Assert.Null(stash.Untracked); } } @@ -174,24 +182,26 @@ public void CanStashIgnoredFiles() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - string gitIgnoreFilePath = Path.Combine(repo.Info.WorkingDirectory, ".gitignore"); - File.WriteAllText(gitIgnoreFilePath, "ignored_file.txt"); - repo.Index.Stage(gitIgnoreFilePath); + const string gitIgnore = ".gitignore"; + const string ignoredFilename = "ignored_file.txt"; + + Touch(repo.Info.WorkingDirectory, gitIgnore, ignoredFilename); + repo.Index.Stage(gitIgnore); repo.Commit("Modify gitignore", Constants.Signature, Constants.Signature); - string ignoredFilePath = Path.Combine(repo.Info.WorkingDirectory, "ignored_file.txt"); - File.WriteAllText(ignoredFilePath, "I'm ignored\n"); + Touch(repo.Info.WorkingDirectory, ignoredFilename, "I'm ignored\n"); - Assert.True(repo.Ignore.IsPathIgnored("ignored_file.txt")); + Assert.True(repo.Ignore.IsPathIgnored(ignoredFilename)); - var stasher = DummySignature; - repo.Stashes.Add(stasher, "This stash includes ignore files", StashOptions.IncludeIgnored); + var stasher = Constants.Signature; + var stash = repo.Stashes.Add(stasher, "This stash includes ignore files", StashModifiers.IncludeIgnored); //TODO : below assertion doesn't pass. Bug? //Assert.False(File.Exists(ignoredFilePath)); var blob = repo.Lookup("stash^3:ignored_file.txt"); Assert.NotNull(blob); + Assert.NotNull(stash.Untracked[ignoredFilename]); } } @@ -213,41 +223,39 @@ public void CanGetStashByIndexer() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - var stasher = DummySignature; + var stasher = Constants.Signature; const string firstStashMessage = "My very first stash"; const string secondStashMessage = "My second stash"; const string thirdStashMessage = "My third stash"; // Create first stash - Stash firstStash = repo.Stashes.Add(stasher, firstStashMessage, StashOptions.IncludeUntracked); + Stash firstStash = repo.Stashes.Add(stasher, firstStashMessage, StashModifiers.IncludeUntracked); Assert.NotNull(firstStash); // Create second stash - string newFileFullPath = Path.Combine(repo.Info.WorkingDirectory, "stash_candidate.txt"); - File.WriteAllText(newFileFullPath, "Oh, I'm going to be stashed!\n"); + Touch(repo.Info.WorkingDirectory, "stash_candidate.txt", "Oh, I'm going to be stashed!\n"); - Stash secondStash = repo.Stashes.Add(stasher, secondStashMessage, StashOptions.IncludeUntracked); + Stash secondStash = repo.Stashes.Add(stasher, secondStashMessage, StashModifiers.IncludeUntracked); Assert.NotNull(secondStash); // Create third stash - newFileFullPath = Path.Combine(repo.Info.WorkingDirectory, "stash_candidate_again.txt"); - File.WriteAllText(newFileFullPath, "Oh, I'm going to be stashed!\n"); + Touch(repo.Info.WorkingDirectory, "stash_candidate_again.txt", "Oh, I'm going to be stashed!\n"); - Stash thirdStash = repo.Stashes.Add(stasher, thirdStashMessage, StashOptions.IncludeUntracked); + Stash thirdStash = repo.Stashes.Add(stasher, thirdStashMessage, StashModifiers.IncludeUntracked); Assert.NotNull(thirdStash); // Get by indexer Assert.Equal(3, repo.Stashes.Count()); Assert.Equal("stash@{0}", repo.Stashes[0].CanonicalName); Assert.Contains(thirdStashMessage, repo.Stashes[0].Message); - Assert.Equal(thirdStash.Target, repo.Stashes[0].Target); + Assert.Equal(thirdStash.WorkTree, repo.Stashes[0].WorkTree); Assert.Equal("stash@{1}", repo.Stashes[1].CanonicalName); Assert.Contains(secondStashMessage, repo.Stashes[1].Message); - Assert.Equal(secondStash.Target, repo.Stashes[1].Target); + Assert.Equal(secondStash.WorkTree, repo.Stashes[1].WorkTree); Assert.Equal("stash@{2}", repo.Stashes[2].CanonicalName); Assert.Contains(firstStashMessage, repo.Stashes[2].Message); - Assert.Equal(firstStash.Target, repo.Stashes[2].Target); + Assert.Equal(firstStash.WorkTree, repo.Stashes[2].WorkTree); } } diff --git a/LibGit2Sharp.Tests/StatusFixture.cs b/LibGit2Sharp.Tests/StatusFixture.cs index 618a765fe..0ce6dcba1 100644 --- a/LibGit2Sharp.Tests/StatusFixture.cs +++ b/LibGit2Sharp.Tests/StatusFixture.cs @@ -76,9 +76,9 @@ public void CanRetrieveTheStatusOfTheWholeWorkingDirectory() [Fact] public void CanRetrieveTheStatusOfANewRepository() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (Repository repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { RepositoryStatus status = repo.Index.RetrieveStatus(); Assert.NotNull(status); @@ -97,24 +97,18 @@ public void CanRetrieveTheStatusOfANewRepository() [Fact] public void RetrievingTheStatusOfARepositoryReturnNativeFilePaths() { - // Initialize a new repository - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - - const string directoryName = "directory"; - const string fileName = "Testfile.txt"; - - // Create a file and insert some content - string directoryPath = Path.Combine(scd.RootedDirectoryPath, directoryName); - string filePath = Path.Combine(directoryPath, fileName); - - Directory.CreateDirectory(directoryPath); - File.WriteAllText(filePath, "Anybody out there?"); + // Build relative path + string relFilePath = Path.Combine("directory", "Testfile.txt"); // Open the repository - using (Repository repo = Repository.Init(scd.DirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { + Touch(repo.Info.WorkingDirectory, relFilePath, "Anybody out there?"); + // Add the file to the index - repo.Index.Stage(filePath); + repo.Index.Stage(relFilePath); // Get the repository status RepositoryStatus repoStatus = repo.Index.RetrieveStatus(); @@ -122,7 +116,7 @@ public void RetrievingTheStatusOfARepositoryReturnNativeFilePaths() Assert.Equal(1, repoStatus.Count()); StatusEntry statusEntry = repoStatus.Single(); - Assert.Equal(Path.Combine(directoryName, fileName), statusEntry.FilePath); + Assert.Equal(relFilePath, statusEntry.FilePath); Assert.Equal(statusEntry.FilePath, repoStatus.Added.Single()); } @@ -131,19 +125,17 @@ public void RetrievingTheStatusOfARepositoryReturnNativeFilePaths() [Fact] public void RetrievingTheStatusOfAnEmptyRepositoryHonorsTheGitIgnoreDirectives() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (Repository repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { const string relativePath = "look-ma.txt"; - string fullFilePath = Path.Combine(repo.Info.WorkingDirectory, relativePath); - File.WriteAllText(fullFilePath, "I'm going to be ignored!"); + Touch(repo.Info.WorkingDirectory, relativePath, "I'm going to be ignored!"); RepositoryStatus status = repo.Index.RetrieveStatus(); Assert.Equal(new[] { relativePath }, status.Untracked); - string gitignorePath = Path.Combine(repo.Info.WorkingDirectory, ".gitignore"); - File.WriteAllText(gitignorePath, "*.txt" + Environment.NewLine); + Touch(repo.Info.WorkingDirectory, ".gitignore", "*.txt" + Environment.NewLine); RepositoryStatus newStatus = repo.Index.RetrieveStatus(); Assert.Equal(".gitignore", newStatus.Untracked.Single()); @@ -160,8 +152,7 @@ public void RetrievingTheStatusOfTheRepositoryHonorsTheGitIgnoreDirectives() using (var repo = new Repository(path)) { string relativePath = Path.Combine("1", "look-ma.txt"); - string fullFilePath = Path.Combine(repo.Info.WorkingDirectory, relativePath); - File.WriteAllText(fullFilePath, "I'm going to be ignored!"); + Touch(repo.Info.WorkingDirectory, relativePath, "I'm going to be ignored!"); /* * $ git status --ignored @@ -198,8 +189,7 @@ public void RetrievingTheStatusOfTheRepositoryHonorsTheGitIgnoreDirectives() Assert.Equal(new[]{relativePath, "new_untracked_file.txt"}, status.Untracked); - string gitignorePath = Path.Combine(repo.Info.WorkingDirectory, ".gitignore"); - File.WriteAllText(gitignorePath, "*.txt" + Environment.NewLine); + Touch(repo.Info.WorkingDirectory, ".gitignore", "*.txt" + Environment.NewLine); /* * $ git status --ignored @@ -250,13 +240,10 @@ public void RetrievingTheStatusOfAnAmbiguousFileThrows() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - string relativePath = Path.Combine("1", "ambiguous1.txt"); - string fullFilePath = Path.Combine(repo.Info.WorkingDirectory, relativePath); - File.WriteAllText(fullFilePath, "I don't like brackets."); + Touch(repo.Info.WorkingDirectory, "1/ambiguous1.txt", "I don't like brackets."); - relativePath = Path.Combine("1", "ambiguous[1].txt"); - fullFilePath = Path.Combine(repo.Info.WorkingDirectory, relativePath); - File.WriteAllText(fullFilePath, "Brackets all the way."); + string relativePath = Path.Combine("1", "ambiguous[1].txt"); + Touch(repo.Info.WorkingDirectory, relativePath, "Brackets all the way."); Assert.Throws(() => repo.Index.RetrieveStatus(relativePath)); } @@ -271,29 +258,30 @@ public void RetrievingTheStatusOfAFilePathHonorsTheIgnoreCaseConfigurationSettin FileStatus expectedCamelCasedFileStatus ) { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - string lowerCasedPath; + const string lowercasedFilename = "plop"; + + string repoPath = InitNewRepository(); - using (Repository repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { repo.Config.Set("core.ignorecase", shouldIgnoreCase); - lowerCasedPath = Path.Combine(repo.Info.WorkingDirectory, "plop"); - - File.WriteAllText(lowerCasedPath, string.Empty); + lowerCasedPath = Touch(repo.Info.WorkingDirectory, lowercasedFilename); - repo.Index.Stage(lowerCasedPath); - repo.Commit("initial", DummySignature, DummySignature); + repo.Index.Stage(lowercasedFilename); + repo.Commit("initial", Constants.Signature, Constants.Signature); } - using (var repo = new Repository(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { - string camelCasedPath = Path.Combine(repo.Info.WorkingDirectory, "Plop"); + const string upercasedFilename = "Plop"; + + string camelCasedPath = Path.Combine(repo.Info.WorkingDirectory, upercasedFilename); File.Move(lowerCasedPath, camelCasedPath); - Assert.Equal(expectedlowerCasedFileStatus, repo.Index.RetrieveStatus("plop")); - Assert.Equal(expectedCamelCasedFileStatus, repo.Index.RetrieveStatus("Plop")); + Assert.Equal(expectedlowerCasedFileStatus, repo.Index.RetrieveStatus(lowercasedFilename)); + Assert.Equal(expectedCamelCasedFileStatus, repo.Index.RetrieveStatus(upercasedFilename)); AssertStatus(shouldIgnoreCase, expectedlowerCasedFileStatus, repo, camelCasedPath.ToLowerInvariant()); AssertStatus(shouldIgnoreCase, expectedCamelCasedFileStatus, repo, camelCasedPath.ToUpperInvariant()); @@ -323,9 +311,8 @@ public void RetrievingTheStatusOfTheRepositoryHonorsTheGitIgnoreDirectivesThroug Touch(repo.Info.WorkingDirectory, "bin/look-ma.txt", "I'm going to be ignored!"); Touch(repo.Info.WorkingDirectory, "bin/what-about-me.txt", "Huh?"); - string gitignorePath = Path.Combine(repo.Info.WorkingDirectory, ".gitignore"); - - File.WriteAllText(gitignorePath, "bin"); + const string gitIgnore = ".gitignore"; + Touch(repo.Info.WorkingDirectory, gitIgnore, "bin"); Assert.Equal(FileStatus.Ignored, repo.Index.RetrieveStatus("bin/look-ma.txt")); Assert.Equal(FileStatus.Ignored, repo.Index.RetrieveStatus("bin/what-about-me.txt")); @@ -336,7 +323,7 @@ public void RetrievingTheStatusOfTheRepositoryHonorsTheGitIgnoreDirectivesThroug var sb = new StringBuilder(); sb.AppendLine("bin/*"); sb.AppendLine("!bin/w*"); - File.WriteAllText(gitignorePath, sb.ToString()); + Touch(repo.Info.WorkingDirectory, gitIgnore, sb.ToString()); Assert.Equal(FileStatus.Ignored, repo.Index.RetrieveStatus("bin/look-ma.txt")); Assert.Equal(FileStatus.Untracked, repo.Index.RetrieveStatus("bin/what-about-me.txt")); diff --git a/LibGit2Sharp.Tests/TagFixture.cs b/LibGit2Sharp.Tests/TagFixture.cs index 5215594fe..a7b8524ac 100644 --- a/LibGit2Sharp.Tests/TagFixture.cs +++ b/LibGit2Sharp.Tests/TagFixture.cs @@ -230,9 +230,9 @@ public void CreatingAnAnnotatedTagIsDeterministic() // Ported from cgit (https://github.com/git/git/blob/1c08bf50cfcf924094eca56c2486a90e2bf1e6e2/t/t7004-tag.sh#L32) public void CreatingATagInAEmptyRepositoryThrows() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Assert.Throws(() => repo.ApplyTag("mynotag")); } @@ -242,9 +242,9 @@ public void CreatingATagInAEmptyRepositoryThrows() // Ported from cgit (https://github.com/git/git/blob/1c08bf50cfcf924094eca56c2486a90e2bf1e6e2/t/t7004-tag.sh#L37) public void CreatingATagForHeadInAEmptyRepositoryThrows() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Assert.Throws(() => repo.ApplyTag("mytaghead", "HEAD")); } @@ -598,9 +598,9 @@ public void CanListTags() // Ported from cgit (https://github.com/git/git/blob/1c08bf50cfcf924094eca56c2486a90e2bf1e6e2/t/t7004-tag.sh#L24) public void CanListAllTagsInAEmptyRepository() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { Assert.True(repo.Info.IsHeadOrphaned); Assert.Equal(0, repo.Tags.Count()); diff --git a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs index 316c68ec1..6dc0c76ad 100644 --- a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs +++ b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -28,8 +29,6 @@ static BaseFixture() public static string SubmoduleTestRepoWorkingDirPath { get; private set; } public static DirectoryInfo ResourcesDirectory { get; private set; } - public static readonly Signature DummySignature = new Signature("Author N. Ame", "him@there.com", TruncateSubSeconds(DateTimeOffset.Now)); - public static bool IsFileSystemCaseSensitive { get; private set; } protected static DateTimeOffset TruncateSubSeconds(DateTimeOffset dto) @@ -82,8 +81,9 @@ private static bool IsFileSystemCaseSensitiveInternal() protected void CreateCorruptedDeadBeefHead(string repoPath) { const string deadbeef = "deadbeef"; - string headPath = string.Format("{0}refs/heads/{1}", repoPath, deadbeef); - File.WriteAllText(headPath, string.Format("{0}{0}{0}{0}{0}\n", deadbeef)); + string headPath = string.Format("refs/heads/{0}", deadbeef); + + Touch(repoPath, headPath, string.Format("{0}{0}{0}{0}{0}\n", deadbeef)); } protected SelfCleaningDirectory BuildSelfCleaningDirectory() @@ -136,12 +136,19 @@ private string Clone(string sourceDirectoryPath, params string[] additionalSourc return clonePath; } + protected string InitNewRepository(bool isBare = false) + { + SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + + return Repository.Init(scd.DirectoryPath, isBare); + } + public void Register(string directoryPath) { directories.Add(directoryPath); } - public void Dispose() + public virtual void Dispose() { #if LEAKS GC.Collect(); @@ -211,19 +218,17 @@ private static RepositoryOptions BuildFakeRepositoryOptions(SelfCleaningDirector }; } - protected string Touch(string parent, string file, string content = null) + protected static string Touch(string parent, string file, string content = null) { - var lastIndex = file.LastIndexOf('/'); - if (lastIndex > 0) - { - var parents = file.Substring(0, lastIndex); - Directory.CreateDirectory(Path.Combine(parent, parents)); - } + string filePath = Path.Combine(parent, file); + string dir = Path.GetDirectoryName(filePath); + Debug.Assert(dir != null); + + Directory.CreateDirectory(dir); - var filePath = Path.Combine(parent, file); - File.AppendAllText(filePath, content ?? string.Empty, Encoding.ASCII); + File.WriteAllText(filePath, content ?? string.Empty, Encoding.ASCII); - return file; + return filePath; } protected static void AssertReflogEntryIsCreated(IEnumerable reflog, string targetSha, diff --git a/LibGit2Sharp.Tests/TestHelpers/ExpectedFetchState.cs b/LibGit2Sharp.Tests/TestHelpers/ExpectedFetchState.cs index 512f401d7..722b88730 100644 --- a/LibGit2Sharp.Tests/TestHelpers/ExpectedFetchState.cs +++ b/LibGit2Sharp.Tests/TestHelpers/ExpectedFetchState.cs @@ -5,38 +5,38 @@ namespace LibGit2Sharp.Tests.TestHelpers { /// - /// Class to verify the expected state after fetching github.com/nulltoken/TestGitRepository into an empty repository. - /// Includes the expected reference callbacks and the expected branches / tags after fetch is completed. + /// Class to verify the expected state after fetching github.com/nulltoken/TestGitRepository into an empty repository. + /// Includes the expected reference callbacks and the expected branches / tags after fetch is completed. /// internal class ExpectedFetchState { /// - /// Name of the Remote being fetched from. + /// Name of the Remote being fetched from. /// internal string RemoteName { get; private set; } /// - /// Expected branch tips after fetching into an empty repository. + /// Expected branch tips after fetching into an empty repository. /// private Dictionary ExpectedBranchTips = new Dictionary(); /// - /// Expected tags after fetching into an empty repository + /// Expected tags after fetching into an empty repository /// private Dictionary ExpectedTags = new Dictionary(); /// - /// References that we expect to be updated in the UpdateReferenceTips callback. + /// References that we expect to be updated in the UpdateReferenceTips callback. /// private Dictionary ExpectedReferenceUpdates = new Dictionary(); /// - /// References that were actually updated in the UpdateReferenceTips callback. + /// References that were actually updated in the UpdateReferenceTips callback. /// private Dictionary ObservedReferenceUpdates = new Dictionary(); /// - /// Constructor. + /// Constructor. /// /// Name of the remote being updated. public ExpectedFetchState(string remoteName) @@ -45,7 +45,7 @@ public ExpectedFetchState(string remoteName) } /// - /// Add information on a branch that is expected to be updated during a fetch. + /// Add information on a branch that is expected to be updated during a fetch. /// /// Name of the branch. /// Old ID of the branch reference. @@ -58,7 +58,7 @@ public void AddExpectedBranch(string branchName, ObjectId oldId, ObjectId newId) } /// - /// Add information on a tag that is expected to be updated during a fetch. + /// Add information on a tag that is expected to be updated during a fetch. /// /// Name of the tag. /// Old ID of the tag. @@ -73,12 +73,12 @@ public void AddExpectedTag(string tagName, ObjectId oldId, TestRemoteInfo.Expect } /// - /// Handler to hook up to UpdateTips callback. + /// Handler to hook up to UpdateTips callback. /// /// Name of reference being updated. /// Old ID of reference. /// New ID of reference. - /// + /// 0 on success; a negative value to abort the process. public int RemoteUpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId) { // assert that we have not seen this reference before @@ -101,7 +101,7 @@ public int RemoteUpdateTipsHandler(string referenceName, ObjectId oldId, ObjectI } /// - /// Check that all expected references have been updated. + /// Check that all expected references have been updated. /// /// Repository object whose state will be checked against expected state. public void CheckUpdatedReferences(Repository repo) @@ -157,17 +157,17 @@ public void CheckUpdatedReferences(Repository repo) #region ExpectedFetchState /// - /// Structure to track a reference that has been updated. + /// Structure to track a reference that has been updated. /// private struct ReferenceUpdate { /// - /// Old ID of the reference. + /// Old ID of the reference. /// public ObjectId OldId; /// - /// New ID of the reference. + /// New ID of the reference. /// public ObjectId NewId; diff --git a/LibGit2Sharp.Tests/TestHelpers/OdbHelper.cs b/LibGit2Sharp.Tests/TestHelpers/OdbHelper.cs index 83e21ecf3..748a9a7dc 100644 --- a/LibGit2Sharp.Tests/TestHelpers/OdbHelper.cs +++ b/LibGit2Sharp.Tests/TestHelpers/OdbHelper.cs @@ -8,9 +8,8 @@ public static class OdbHelper public static Blob CreateBlob(Repository repo, string content) { using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(content))) - using (var binReader = new BinaryReader(stream)) { - return repo.ObjectDatabase.CreateBlob(binReader); + return repo.ObjectDatabase.CreateBlob(stream); } } } diff --git a/LibGit2Sharp.Tests/TestHelpers/TestRemoteInfo.cs b/LibGit2Sharp.Tests/TestHelpers/TestRemoteInfo.cs index 65ad922f7..7703bea5f 100644 --- a/LibGit2Sharp.Tests/TestHelpers/TestRemoteInfo.cs +++ b/LibGit2Sharp.Tests/TestHelpers/TestRemoteInfo.cs @@ -3,18 +3,18 @@ namespace LibGit2Sharp.Tests.TestHelpers { /// - /// This is the state of the test repository based at: - /// github.com/libgit2/TestGitRepository + /// This is the state of the test repository based at: + /// github.com/libgit2/TestGitRepository /// public class TestRemoteInfo { /// - /// Expected Branch tips of the remote repository. + /// Expected Branch tips of the remote repository. /// public Dictionary BranchTips = new Dictionary(); /// - /// Expected Tags of the remote repository. + /// Expected Tags of the remote repository. /// public Dictionary Tags = new Dictionary(); @@ -35,7 +35,7 @@ private TestRemoteInfo() #region ExpectedTagInfo class /// - /// Helper class to contain expected info of tags in the test repository. + /// Helper class to contain expected info of tags in the test repository. /// public class ExpectedTagInfo { diff --git a/LibGit2Sharp.Tests/TreeDefinitionFixture.cs b/LibGit2Sharp.Tests/TreeDefinitionFixture.cs index f6d9e3efb..d4fee346a 100644 --- a/LibGit2Sharp.Tests/TreeDefinitionFixture.cs +++ b/LibGit2Sharp.Tests/TreeDefinitionFixture.cs @@ -28,7 +28,7 @@ public void CanBuildATreeDefinitionFromATree() [Fact] public void BuildingATreeDefinitionWithBadParamsThrows() { - Assert.Throws(() => TreeDefinition.From(null)); + Assert.Throws(() => TreeDefinition.From(default(Tree))); } [Fact] diff --git a/LibGit2Sharp.Tests/UnstageFixture.cs b/LibGit2Sharp.Tests/UnstageFixture.cs index 524d8657f..856a8e4fa 100644 --- a/LibGit2Sharp.Tests/UnstageFixture.cs +++ b/LibGit2Sharp.Tests/UnstageFixture.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Linq; -using System.Text; using LibGit2Sharp.Tests.TestHelpers; using Xunit; using Xunit.Extensions; @@ -44,12 +43,10 @@ public void CanStageAndUnstageAnIgnoredFile() string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { - string gitignorePath = Path.Combine(repo.Info.WorkingDirectory, ".gitignore"); - File.WriteAllText(gitignorePath, "*.ign" + Environment.NewLine); + Touch(repo.Info.WorkingDirectory, ".gitignore", "*.ign" + Environment.NewLine); const string relativePath = "Champa.ign"; - string gitignoredFile = Path.Combine(repo.Info.WorkingDirectory, relativePath); - File.WriteAllText(gitignoredFile, "On stage!" + Environment.NewLine); + Touch(repo.Info.WorkingDirectory, relativePath, "On stage!" + Environment.NewLine); Assert.Equal(FileStatus.Ignored, repo.Index.RetrieveStatus(relativePath)); @@ -139,15 +136,14 @@ public void CanUnstageTheRemovalOfAFile() [Fact] public void CanUnstageUntrackedFileAgainstAnOrphanedHead() { - SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); + string repoPath = InitNewRepository(); - using (var repo = Repository.Init(scd.DirectoryPath)) + using (var repo = new Repository(repoPath)) { - string relativePath = "a.txt"; - string absolutePath = Path.Combine(repo.Info.WorkingDirectory, relativePath); + const string relativePath = "a.txt"; + Touch(repo.Info.WorkingDirectory, relativePath, "hello test file\n"); - File.WriteAllText(absolutePath, "hello test file\n", Encoding.ASCII); - repo.Index.Stage(absolutePath); + repo.Index.Stage(relativePath); repo.Index.Unstage(relativePath); RepositoryStatus status = repo.Index.RetrieveStatus(); @@ -202,8 +198,7 @@ public void UnstagingANewFileWithAFullPathWhichEscapesOutOfTheWorkingDirThrows() DirectoryInfo di = Directory.CreateDirectory(scd.DirectoryPath); const string filename = "unit_test.txt"; - string fullPath = Path.Combine(di.FullName, filename); - File.WriteAllText(fullPath, "some contents"); + string fullPath = Touch(di.FullName, filename, "some contents"); Assert.Throws(() => repo.Index.Unstage(fullPath)); } @@ -213,15 +208,15 @@ public void UnstagingANewFileWithAFullPathWhichEscapesOutOfTheWorkingDirThrows() public void UnstagingANewFileWithAFullPathWhichEscapesOutOfTheWorkingDirAgainstAnOrphanedHeadThrows() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); - SelfCleaningDirectory scd2 = BuildSelfCleaningDirectory(); - using (var repo = Repository.Init(scd2.DirectoryPath)) + string repoPath = InitNewRepository(); + + using (var repo = new Repository(repoPath)) { DirectoryInfo di = Directory.CreateDirectory(scd.DirectoryPath); const string filename = "unit_test.txt"; - string fullPath = Path.Combine(di.FullName, filename); - File.WriteAllText(fullPath, "some contents"); + string fullPath = Touch(di.FullName, filename, "some contents"); Assert.Throws(() => repo.Index.Unstage(fullPath)); } diff --git a/LibGit2Sharp/AmbiguousSpecificationException.cs b/LibGit2Sharp/AmbiguousSpecificationException.cs index 499d327d1..ab0db742f 100644 --- a/LibGit2Sharp/AmbiguousSpecificationException.cs +++ b/LibGit2Sharp/AmbiguousSpecificationException.cs @@ -4,42 +4,42 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when the provided specification cannot uniquely identify a reference, an object or a path. + /// The exception that is thrown when the provided specification cannot uniquely identify a reference, an object or a path. /// [Serializable] public class AmbiguousSpecificationException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public AmbiguousSpecificationException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public AmbiguousSpecificationException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public AmbiguousSpecificationException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected AmbiguousSpecificationException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/BareRepositoryException.cs b/LibGit2Sharp/BareRepositoryException.cs index 46a4e5e08..9ba6ee328 100644 --- a/LibGit2Sharp/BareRepositoryException.cs +++ b/LibGit2Sharp/BareRepositoryException.cs @@ -5,43 +5,43 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when an operation which requires a - /// working directory is performed against a bare repository. + /// The exception that is thrown when an operation which requires a + /// working directory is performed against a bare repository. /// [Serializable] public class BareRepositoryException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public BareRepositoryException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public BareRepositoryException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public BareRepositoryException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected BareRepositoryException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/Blob.cs b/LibGit2Sharp/Blob.cs index ef4b31ce6..fd17d203c 100644 --- a/LibGit2Sharp/Blob.cs +++ b/LibGit2Sharp/Blob.cs @@ -5,7 +5,7 @@ namespace LibGit2Sharp { /// - /// Stores the binary content of a tracked file. + /// Stores the binary content of a tracked file. /// public class Blob : GitObject { @@ -13,7 +13,7 @@ public class Blob : GitObject private readonly ILazy lazyIsBinary; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Blob() { } @@ -26,17 +26,17 @@ internal Blob(Repository repo, ObjectId id) } /// - /// Gets the size in bytes of the contents of a blob + /// Gets the size in bytes of the contents of a blob /// public virtual int Size { get { return (int)lazySize.Value; } } /// - /// Determine if the blob content is most certainly binary or not. + /// Determine if the blob content is most certainly binary or not. /// public virtual bool IsBinary { get { return lazyIsBinary.Value; } } /// - /// Gets the blob content in a array. + /// Gets the blob content in a array. /// public virtual byte[] Content { @@ -47,7 +47,7 @@ public virtual byte[] Content } /// - /// Gets the blob content in a . + /// Gets the blob content in a . /// public virtual Stream ContentStream { diff --git a/LibGit2Sharp/BlobExtensions.cs b/LibGit2Sharp/BlobExtensions.cs index d1a7ce9d8..110cdadb8 100644 --- a/LibGit2Sharp/BlobExtensions.cs +++ b/LibGit2Sharp/BlobExtensions.cs @@ -1,15 +1,15 @@ -using System.Text; -using LibGit2Sharp.Core; +using System.Text; +using LibGit2Sharp.Core; namespace LibGit2Sharp { /// - /// Provides helper overloads to a . + /// Provides helper overloads to a . /// public static class BlobExtensions { /// - /// Gets the blob content decoded as UTF-8. + /// Gets the blob content decoded as UTF-8. /// /// The blob for which the content will be returned. /// Blob content as UTF-8 @@ -21,7 +21,7 @@ public static string ContentAsUtf8(this Blob blob) } /// - /// Gets the blob content decoded as Unicode. + /// Gets the blob content decoded as Unicode. /// /// The blob for which the content will be returned. /// Blob content as unicode. diff --git a/LibGit2Sharp/Branch.cs b/LibGit2Sharp/Branch.cs index 2095cc488..44b0d7ff3 100644 --- a/LibGit2Sharp/Branch.cs +++ b/LibGit2Sharp/Branch.cs @@ -7,37 +7,37 @@ namespace LibGit2Sharp { /// - /// A branch is a special kind of reference + /// A branch is a special kind of reference /// public class Branch : ReferenceWrapper { private readonly Lazy trackedBranch; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Branch() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The repo. - /// The reference. - /// The full name of the reference + /// The repo. + /// The reference. + /// The full name of the reference internal Branch(Repository repo, Reference reference, string canonicalName) : this(repo, reference, _ => canonicalName) { } /// - /// Initializes a new instance of an orphaned class. - /// - /// This instance will point to no commit. - /// + /// Initializes a new instance of an orphaned class. + /// + /// This instance will point to no commit. + /// /// - /// The repo. - /// The reference. + /// The repo. + /// The reference. internal Branch(Repository repo, Reference reference) : this(repo, reference, r => r.TargetIdentifier) { @@ -50,10 +50,10 @@ private Branch(Repository repo, Reference reference, Func can } /// - /// Gets the pointed at by the in the . + /// Gets the pointed at by the in the . /// - /// The relative path to the from the working directory. - /// null if nothing has been found, the otherwise. + /// The relative path to the from the working directory. + /// null if nothing has been found, the otherwise. public virtual TreeEntry this[string relativePath] { get @@ -68,10 +68,10 @@ public virtual TreeEntry this[string relativePath] } /// - /// Gets a value indicating whether this instance is a remote. + /// Gets a value indicating whether this instance is a remote. /// /// - /// true if this instance is remote; otherwise, false. + /// true if this instance is remote; otherwise, false. /// public virtual bool IsRemote { @@ -79,7 +79,7 @@ public virtual bool IsRemote } /// - /// Gets the remote branch which is connected to this local one, or null if there is none. + /// Gets the remote branch which is connected to this local one, or null if there is none. /// public virtual Branch TrackedBranch { @@ -87,7 +87,7 @@ public virtual Branch TrackedBranch } /// - /// Determines if this local branch is connected to a remote one. + /// Determines if this local branch is connected to a remote one. /// public virtual bool IsTracking { @@ -95,7 +95,7 @@ public virtual bool IsTracking } /// - /// Gets additional information about the tracked branch. + /// Gets additional information about the tracked branch. /// public virtual BranchTrackingDetails TrackingDetails { @@ -103,10 +103,10 @@ public virtual BranchTrackingDetails TrackingDetails } /// - /// Gets a value indicating whether this instance is current branch (HEAD) in the repository. + /// Gets a value indicating whether this instance is current branch (HEAD) in the repository. /// /// - /// true if this instance is the current branch; otherwise, false. + /// true if this instance is the current branch; otherwise, false. /// public virtual bool IsCurrentRepositoryHead { @@ -114,7 +114,7 @@ public virtual bool IsCurrentRepositoryHead } /// - /// Gets the that this branch points to. + /// Gets the that this branch points to. /// public virtual Commit Tip { @@ -122,19 +122,19 @@ public virtual Commit Tip } /// - /// Gets the commits on this branch. (Starts walking from the References's target). + /// Gets the commits on this branch. (Starts walking from the References's target). /// public virtual ICommitLog Commits { - get { return repo.Commits.QueryBy(new Filter { Since = this }); } + get { return repo.Commits.QueryBy(new CommitFilter { Since = this }); } } /// - /// Gets the configured canonical name of the upstream branch. - /// - /// This is the upstream reference to which this branch will be pushed. - /// It corresponds to the "branch.branch_name.merge" property of the config file. - /// + /// Gets the configured canonical name of the upstream branch. + /// + /// This is the upstream reference to which this branch will be pushed. + /// It corresponds to the "branch.branch_name.merge" property of the config file. + /// /// public virtual string UpstreamBranchCanonicalName { @@ -150,7 +150,7 @@ public virtual string UpstreamBranchCanonicalName } /// - /// Gets the configured to fetch from and push to. + /// Gets the configured to fetch from and push to. /// public virtual Remote Remote { @@ -215,10 +215,10 @@ private string RemoteNameFromRemoteTrackingBranch() } /// - /// Checkout the tip commit of this object. - /// If this commit is the current tip of the branch, will checkout - /// the named branch. Otherwise, will checkout the tip commit as a - /// detached HEAD. + /// Checkout the tip commit of this object. + /// If this commit is the current tip of the branch, will checkout + /// the named branch. Otherwise, will checkout the tip commit as a + /// detached HEAD. /// public virtual void Checkout() { @@ -226,16 +226,31 @@ public virtual void Checkout() } /// - /// Checkout the tip commit of this object - /// with a callback for progress reporting. If this commit is the - /// current tip of the branch, will checkout the named branch. Otherwise, - /// will checkout the tip commit as a detached HEAD. + /// Checkout the tip commit of this object + /// with a callback for progress reporting. If this commit is the + /// current tip of the branch, will checkout the named branch. Otherwise, + /// will checkout the tip commit as a detached HEAD. /// /// Options controlling checkout behavior. /// Callback method to report checkout progress updates through. + [Obsolete("This method will be removed in the next release. Please use Checkout(CheckoutModifiers, CheckoutProgressHandler, CheckoutNotificationOptions) instead.")] public virtual void Checkout(CheckoutOptions checkoutOptions, CheckoutProgressHandler onCheckoutProgress) { - repo.Checkout(this, checkoutOptions, onCheckoutProgress); + Checkout((CheckoutModifiers)checkoutOptions, onCheckoutProgress, null); + } + + /// + /// Checkout the tip commit of this object + /// with a callback for progress reporting. If this commit is the + /// current tip of the branch, will checkout the named branch. Otherwise, + /// will checkout the tip commit as a detached HEAD. + /// + /// Options controlling checkout behavior. + /// Callback method to report checkout progress updates through. + /// to manage checkout notifications. + public virtual void Checkout(CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions) + { + repo.Checkout(this, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions); } private Branch ResolveTrackedBranch() @@ -268,8 +283,8 @@ private static bool IsRemoteBranch(string canonicalName) } /// - /// Removes redundent leading namespaces (regarding the kind of - /// reference being wrapped) from the canonical name. + /// Removes redundent leading namespaces (regarding the kind of + /// reference being wrapped) from the canonical name. /// /// The friendly shortened name protected override string Shorten() diff --git a/LibGit2Sharp/BranchCollection.cs b/LibGit2Sharp/BranchCollection.cs index cc742a9d4..611a3e0e7 100644 --- a/LibGit2Sharp/BranchCollection.cs +++ b/LibGit2Sharp/BranchCollection.cs @@ -10,7 +10,7 @@ namespace LibGit2Sharp { /// - /// The collection of Branches in a + /// The collection of Branches in a /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class BranchCollection : IEnumerable @@ -18,22 +18,22 @@ public class BranchCollection : IEnumerable internal readonly Repository repo; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected BranchCollection() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The repo. + /// The repo. internal BranchCollection(Repository repo) { this.repo = repo; } /// - /// Gets the with the specified name. + /// Gets the with the specified name. /// public virtual Branch this[string name] { @@ -86,9 +86,9 @@ private Branch BuildFromReferenceName(string canonicalName) #region IEnumerable Members /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { return Proxy.git_branch_foreach(repo.Handle, GitBranchType.GIT_BRANCH_LOCAL | GitBranchType.GIT_BRANCH_REMOTE, branchToCanoncialName) @@ -97,9 +97,9 @@ public virtual IEnumerator GetEnumerator() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); @@ -108,11 +108,11 @@ IEnumerator IEnumerable.GetEnumerator() #endregion /// - /// Create a new local branch with the specified name + /// Create a new local branch with the specified name /// - /// The name of the branch. - /// The target commit. - /// True to allow silent overwriting a potentially existing branch, false otherwise. + /// The name of the branch. + /// The target commit. + /// True to allow silent overwriting a potentially existing branch, false otherwise. /// A new . public virtual Branch Add(string name, Commit commit, bool allowOverwrite = false) { @@ -125,9 +125,9 @@ public virtual Branch Add(string name, Commit commit, bool allowOverwrite = fals } /// - /// Deletes the specified branch. + /// Deletes the specified branch. /// - /// The branch to delete. + /// The branch to delete. public virtual void Remove(Branch branch) { Ensure.ArgumentNotNull(branch, "branch"); @@ -139,11 +139,11 @@ public virtual void Remove(Branch branch) } /// - /// Renames an existing local branch with a new name. + /// Renames an existing local branch with a new name. /// - /// The current local branch. - /// The new name the existing branch should bear. - /// True to allow silent overwriting a potentially existing branch, false otherwise. + /// The current local branch. + /// The new name the existing branch should bear. + /// True to allow silent overwriting a potentially existing branch, false otherwise. /// A new . public virtual Branch Move(Branch branch, string newName, bool allowOverwrite = false) { @@ -168,7 +168,7 @@ public virtual Branch Move(Branch branch, string newName, bool allowOverwrite = } /// - /// Update properties of a branch. + /// Update properties of a branch. /// /// The branch to update. /// Delegate to perform updates on the branch. diff --git a/LibGit2Sharp/BranchCollectionExtensions.cs b/LibGit2Sharp/BranchCollectionExtensions.cs index 05f879115..6459c7385 100644 --- a/LibGit2Sharp/BranchCollectionExtensions.cs +++ b/LibGit2Sharp/BranchCollectionExtensions.cs @@ -3,34 +3,34 @@ namespace LibGit2Sharp { /// - /// Provides helper overloads to a . + /// Provides helper overloads to a . /// public static class BranchCollectionExtensions { /// - /// Create a new local branch with the specified name + /// Create a new local branch with the specified name /// - /// The name of the branch. - /// Revparse spec for the target commit. - /// True to allow silent overwriting a potentially existing branch, false otherwise. - /// The being worked with. + /// The name of the branch. + /// Revparse spec for the target commit. + /// True to allow silent overwriting a potentially existing branch, false otherwise. + /// The being worked with. /// A new . public static Branch Add(this BranchCollection branches, string name, string committish, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(committish, "committish"); - Commit commit = branches.repo.LookupCommit(committish); + var commit = branches.repo.LookupCommit(committish); return branches.Add(name, commit, allowOverwrite); } /// - /// Deletes the branch with the specified name. + /// Deletes the branch with the specified name. /// - /// The name of the branch to delete. - /// True if the provided is the name of a remote branch, false otherwise. - /// The being worked with. + /// The name of the branch to delete. + /// True if the provided is the name of a remote branch, false otherwise. + /// The being worked with. public static void Remove(this BranchCollection branches, string name, bool isRemote = false) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); @@ -48,12 +48,12 @@ public static void Remove(this BranchCollection branches, string name, bool isRe } /// - /// Renames an existing local branch with a new name. + /// Renames an existing local branch with a new name. /// - /// The current branch name. - /// The new name the existing branch should bear. - /// True to allow silent overwriting a potentially existing branch, false otherwise. - /// The being worked with. + /// The current branch name. + /// The new name the existing branch should bear. + /// True to allow silent overwriting a potentially existing branch, false otherwise. + /// The being worked with. /// A new . public static Branch Move(this BranchCollection branches, string currentName, string newName, bool allowOverwrite = false) { diff --git a/LibGit2Sharp/BranchTrackingDetails.cs b/LibGit2Sharp/BranchTrackingDetails.cs index c2e51cdbc..0f2fac1d9 100644 --- a/LibGit2Sharp/BranchTrackingDetails.cs +++ b/LibGit2Sharp/BranchTrackingDetails.cs @@ -4,7 +4,7 @@ namespace LibGit2Sharp { /// - /// Tracking information for a + /// Tracking information for a /// public class BranchTrackingDetails { @@ -14,7 +14,7 @@ public class BranchTrackingDetails private readonly Lazy commonAncestor; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected BranchTrackingDetails() { } @@ -29,10 +29,10 @@ internal BranchTrackingDetails(Repository repo, Branch branch) } /// - /// Gets the number of commits that exist in this local branch but don't exist in the tracked one. - /// - /// This property will return null if there is no tracked branch linked to this local branch. - /// + /// Gets the number of commits that exist in this local branch but don't exist in the tracked one. + /// + /// This property will return null if there is no tracked branch linked to this local branch. + /// /// public virtual int? AheadBy { @@ -40,10 +40,10 @@ public virtual int? AheadBy } /// - /// Gets the number of commits that exist in the tracked branch but don't exist in this local one. - /// - /// This property will return null if there is no tracked branch linked to this local branch. - /// + /// Gets the number of commits that exist in the tracked branch but don't exist in this local one. + /// + /// This property will return null if there is no tracked branch linked to this local branch. + /// /// public virtual int? BehindBy { @@ -51,11 +51,11 @@ public virtual int? BehindBy } /// - /// Gets the common ancestor of the local branch and its tracked remote branch. - /// - /// This property will return null if there is no tracked branch linked to this local branch, - /// or if either branch is an orphan. - /// + /// Gets the common ancestor of the local branch and its tracked remote branch. + /// + /// This property will return null if there is no tracked branch linked to this local branch, + /// or if either branch is an orphan. + /// /// public virtual Commit CommonAncestor { diff --git a/LibGit2Sharp/BranchUpdater.cs b/LibGit2Sharp/BranchUpdater.cs index 60d403d14..e31a94703 100644 --- a/LibGit2Sharp/BranchUpdater.cs +++ b/LibGit2Sharp/BranchUpdater.cs @@ -1,12 +1,11 @@ using System; -using LibGit2Sharp.Core; using System.Globalization; -using LibGit2Sharp.Core.Handles; +using LibGit2Sharp.Core; namespace LibGit2Sharp { /// - /// Exposes properties of a branch that can be updated. + /// Exposes properties of a branch that can be updated. /// public class BranchUpdater { @@ -14,7 +13,7 @@ public class BranchUpdater private readonly Branch branch; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected BranchUpdater() { } @@ -29,17 +28,17 @@ internal BranchUpdater(Repository repo, Branch branch) } /// - /// Sets the upstream information for the branch. - /// - /// Passing null or string.Empty will unset the upstream. - /// - /// - /// The upstream branch name is with respect to the current repository. - /// So, passing "refs/remotes/origin/master" will set the current branch - /// to track "refs/heads/master" on the origin. Passing in - /// "refs/heads/master" will result in the branch tracking the local - /// master branch. - /// + /// Sets the upstream information for the branch. + /// + /// Passing null or string.Empty will unset the upstream. + /// + /// + /// The upstream branch name is with respect to the current repository. + /// So, passing "refs/remotes/origin/master" will set the current branch + /// to track "refs/heads/master" on the origin. Passing in + /// "refs/heads/master" will result in the branch tracking the local + /// master branch. + /// /// public virtual string TrackedBranch { @@ -56,12 +55,12 @@ public virtual string TrackedBranch } /// - /// Set the upstream branch for this branch. - /// - /// To track the "master" branch on the "origin" remote, set the - /// property to "origin" and the - /// property to "refs/heads/master". - /// + /// Set the upstream branch for this branch. + /// + /// To track the "master" branch on the "origin" remote, set the + /// property to "origin" and the + /// property to "refs/heads/master". + /// /// public virtual string UpstreamBranch { @@ -72,11 +71,11 @@ public virtual string UpstreamBranch } /// - /// Set the upstream remote for this branch. - /// - /// To track the "master" branch on the "origin" remote, set the - /// property to "origin" and the - /// property to "refs/heads/master". + /// Set the upstream remote for this branch. + /// + /// To track the "master" branch on the "origin" remote, set the + /// property to "origin" and the + /// property to "refs/heads/master". /// /// public virtual string Remote @@ -94,15 +93,15 @@ private void UnsetUpstream() } /// - /// Set the upstream information for the current branch. - /// - /// The upstream branch name is with respect to the current repository. - /// So, passing "refs/remotes/origin/master" will set the current branch - /// to track "refs/heads/master" on the origin. Passing in - /// "refs/heads/master" will result in the branch tracking the local - /// master branch. - /// - /// + /// Set the upstream information for the current branch. + /// + /// The upstream branch name is with respect to the current repository. + /// So, passing "refs/remotes/origin/master" will set the current branch + /// to track "refs/heads/master" on the origin. Passing in + /// "refs/heads/master" will result in the branch tracking the local + /// master branch. + /// + /// /// The remote branch to track (e.g. refs/remotes/origin/master). private void SetUpstream(string upstreamBranchName) { @@ -121,7 +120,7 @@ private void SetUpstream(string upstreamBranchName) } /// - /// Set the upstream merge branch for the local branch. + /// Set the upstream merge branch for the local branch. /// /// The merge branch in the upstream remote's namespace. private void SetUpstreamBranch(string mergeBranchName) @@ -139,7 +138,7 @@ private void SetUpstreamBranch(string mergeBranchName) } /// - /// Set the upstream remote for the local branch. + /// Set the upstream remote for the local branch. /// /// The name of the remote to set as the upstream branch. private void SetUpstreamRemote(string remoteName) @@ -163,8 +162,8 @@ private void SetUpstreamRemote(string remoteName) } /// - /// Get the upstream remote and merge branch name from a Canonical branch name. - /// This will return the remote name (or ".") if a local branch for the remote name. + /// Get the upstream remote and merge branch name from a Canonical branch name. + /// This will return the remote name (or ".") if a local branch for the remote name. /// /// The canonical branch name to parse. /// The name of the corresponding remote the branch belongs to diff --git a/LibGit2Sharp/ChangeKind.cs b/LibGit2Sharp/ChangeKind.cs index f1d26ea40..612e036d8 100644 --- a/LibGit2Sharp/ChangeKind.cs +++ b/LibGit2Sharp/ChangeKind.cs @@ -1,53 +1,53 @@ namespace LibGit2Sharp { /// - /// The kind of changes that a Diff can report. + /// The kind of changes that a Diff can report. /// public enum ChangeKind { /// - /// No changes detected. + /// No changes detected. /// Unmodified = 0, /// - /// The file was added. + /// The file was added. /// Added = 1, /// - /// The file was deleted. + /// The file was deleted. /// Deleted = 2, /// - /// The file content was modified. + /// The file content was modified. /// Modified = 3, /// - /// The file was renamed. + /// The file was renamed. /// Renamed = 4, /// - /// The file was copied. + /// The file was copied. /// Copied = 5, /// - /// The file is ignored in the workdir. + /// The file is ignored in the workdir. /// Ignored = 6, /// - /// The file is untracked in the workdir. + /// The file is untracked in the workdir. /// Untracked = 7, /// - /// The type (i.e. regular file, symlink, submodule, ...) - /// of the file was changed. + /// The type (i.e. regular file, symlink, submodule, ...) + /// of the file was changed. /// TypeChanged = 8, } diff --git a/LibGit2Sharp/Changes.cs b/LibGit2Sharp/Changes.cs index 39f550995..0a1a5f014 100644 --- a/LibGit2Sharp/Changes.cs +++ b/LibGit2Sharp/Changes.cs @@ -5,7 +5,7 @@ namespace LibGit2Sharp { /// - /// Base class for changes. + /// Base class for changes. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public abstract class Changes @@ -18,17 +18,17 @@ internal void AppendToPatch(string patch) } /// - /// The number of lines added. + /// The number of lines added. /// public virtual int LinesAdded { get; internal set; } /// - /// The number of lines deleted. + /// The number of lines deleted. /// public virtual int LinesDeleted { get; internal set; } /// - /// The patch corresponding to these changes. + /// The patch corresponding to these changes. /// public virtual string Patch { @@ -36,7 +36,7 @@ public virtual string Patch } /// - /// Determines if at least one side of the comparison holds binary content. + /// Determines if at least one side of the comparison holds binary content. /// public virtual bool IsBinaryComparison { get; protected set; } diff --git a/LibGit2Sharp/CheckoutCallbacks.cs b/LibGit2Sharp/CheckoutCallbacks.cs index 2c3a61095..56a0c8ad9 100644 --- a/LibGit2Sharp/CheckoutCallbacks.cs +++ b/LibGit2Sharp/CheckoutCallbacks.cs @@ -5,42 +5,77 @@ namespace LibGit2Sharp { /// - /// Class to handle the mapping between libgit2 progress_cb callback on the git_checkout_opts - /// structure to the CheckoutProgressHandler delegate. + /// Class to handle the mapping between libgit2 progress_cb callback on the git_checkout_opts + /// structure to the CheckoutProgressHandler delegate. /// internal class CheckoutCallbacks { /// - /// Managed delegate to call in response to checkout progress_cb callback. + /// The managed delegate (e.g. from library consumer) to be called in response to the checkout progress callback. /// private readonly CheckoutProgressHandler onCheckoutProgress; /// - /// Constructor to set up native callback for given managed delegate. + /// The managed delegate (e.g. from library consumer) to be called in response to the checkout notify callback. + /// + private readonly CheckoutNotifyHandler onCheckoutNotify; + + /// + /// Constructor to set up native callback for given managed delegate. /// /// delegate to call in response to checkout progress_cb - private CheckoutCallbacks(CheckoutProgressHandler onCheckoutProgress) + /// delegate to call in response to checkout notification callback. + private CheckoutCallbacks(CheckoutProgressHandler onCheckoutProgress, CheckoutNotifyHandler onCheckoutNotify) { this.onCheckoutProgress = onCheckoutProgress; + this.onCheckoutNotify = onCheckoutNotify; } /// - /// Generate a delegate matching the signature of the native progress_cb callback and wraps the delegate. + /// The method to pass for the native checkout progress callback. /// - /// that should be wrapped in the native callback. - /// The delegate with signature matching the expected native callback. - internal static progress_cb GenerateCheckoutCallbacks(CheckoutProgressHandler onCheckoutProgress) + public progress_cb CheckoutProgressCallback { - if (onCheckoutProgress == null) + get { + if (this.onCheckoutProgress != null) + { + return this.OnGitCheckoutProgress; + } + return null; } + } + + /// + /// The method to pass for the native checkout notify callback. + /// + public checkout_notify_cb CheckoutNotifyCallback + { + get + { + if (this.onCheckoutNotify != null) + { + return this.OnGitCheckoutNotify; + } - return new CheckoutCallbacks(onCheckoutProgress).OnGitCheckoutProgress; + return null; + } } /// - /// The delegate with a signature that matches the native checkout progress_cb function's signature. + /// Generate a delegate matching the signature of the native progress_cb callback and wraps the delegate. + /// + /// that should be wrapped in the native callback. + /// delegate to call in response to checkout notification callback. + /// The delegate with signature matching the expected native callback. + internal static CheckoutCallbacks GenerateCheckoutCallbacks(CheckoutProgressHandler onCheckoutProgress, CheckoutNotifyHandler onCheckoutNotify) + { + return new CheckoutCallbacks(onCheckoutProgress, onCheckoutNotify); + } + + /// + /// The delegate with a signature that matches the native checkout progress_cb function's signature. /// /// The path that was updated. /// The number of completed steps. @@ -48,10 +83,31 @@ internal static progress_cb GenerateCheckoutCallbacks(CheckoutProgressHandler on /// Payload object. private void OnGitCheckoutProgress(IntPtr str, UIntPtr completedSteps, UIntPtr totalSteps, IntPtr payload) { - // Convert null strings into empty strings. - string path = (str != IntPtr.Zero) ? Utf8Marshaler.FromNative(str) : string.Empty; + if (onCheckoutProgress != null) + { + // Convert null strings into empty strings. + string path = (str != IntPtr.Zero) ? Utf8Marshaler.FromNative(str) : string.Empty; + + onCheckoutProgress(path, (int)completedSteps, (int)totalSteps); + } + } + + private int OnGitCheckoutNotify( + CheckoutNotifyFlags why, + IntPtr pathPtr, + IntPtr baselinePtr, + IntPtr targetPtr, + IntPtr workdirPtr, + IntPtr payloadPtr) + { + int result = 0; + if (this.onCheckoutNotify != null) + { + string path = (pathPtr != IntPtr.Zero) ? FilePathMarshaler.FromNative(pathPtr).Native : string.Empty; + result = onCheckoutNotify(path, why) ? 0 : 1; + } - onCheckoutProgress(path, (int)completedSteps, (int)totalSteps); + return result; } } } diff --git a/LibGit2Sharp/CheckoutModifiers.cs b/LibGit2Sharp/CheckoutModifiers.cs new file mode 100644 index 000000000..9ebad388f --- /dev/null +++ b/LibGit2Sharp/CheckoutModifiers.cs @@ -0,0 +1,22 @@ +using System; + +namespace LibGit2Sharp +{ + /// + /// Options controlling Checkout behavior. + /// + [Flags] + public enum CheckoutModifiers + { + /// + /// No checkout flags - use default behavior. + /// + None = 0, + + /// + /// Proceed with checkout even if the index or the working tree differs from HEAD. + /// This will throw away local changes. + /// + Force, + } +} diff --git a/LibGit2Sharp/CheckoutNotificationOptions.cs b/LibGit2Sharp/CheckoutNotificationOptions.cs new file mode 100644 index 000000000..97b5012c0 --- /dev/null +++ b/LibGit2Sharp/CheckoutNotificationOptions.cs @@ -0,0 +1,79 @@ +using System; +using LibGit2Sharp.Handlers; + +namespace LibGit2Sharp +{ + /// + /// Flags controlling checkout notification behavior. + /// + [Flags] + public enum CheckoutNotifyFlags + { + + /// + /// No checkout notification. + /// + None = 0, /* GIT_CHECKOUT_NOTIFY_NONE */ + + /// + /// Notify on conflicting paths. + /// + Conflict = (1 << 0), /* GIT_CHECKOUT_NOTIFY_CONFLICT */ + + /// + /// Notify about dirty files. These are files that do not need + /// an update, but no longer match the baseline. + /// + Dirty = (1 << 1), /* GIT_CHECKOUT_NOTIFY_DIRTY */ + + /// + /// Notify for files that will be updated. + /// + Updated = (1 << 2), /* GIT_CHECKOUT_NOTIFY_UPDATED */ + + /// + /// Notify for untracked files. + /// + Untracked = (1 << 3), /* GIT_CHECKOUT_NOTIFY_UNTRACKED */ + + /// + /// Notify about ignored file. + /// + Ignored = (1 << 4), /* GIT_CHECKOUT_NOTIFY_IGNORED */ + } + + /// + /// Class to specify options and callback on CheckoutNotifications. + /// + public class CheckoutNotificationOptions + { + /// + /// Needed for mocking purposes. + /// + protected CheckoutNotificationOptions() + { + } + + /// + /// The delegate that will be called for files that match the + /// options specified in NotifyFlags. + /// + public virtual CheckoutNotifyHandler CheckoutNotifyHandler { get; private set; } + + /// + /// The Flags specifying what notifications are reported. + /// + public virtual CheckoutNotifyFlags NotifyFlags { get; private set; } + + /// + /// Construct the CheckoutNotificationOptions class. + /// + /// that checkout notifications are reported through. + /// The checkout notification type. + public CheckoutNotificationOptions(CheckoutNotifyHandler checkoutNotifyHandler, CheckoutNotifyFlags notifyFlags) + { + CheckoutNotifyHandler = checkoutNotifyHandler; + NotifyFlags = notifyFlags; + } + } +} diff --git a/LibGit2Sharp/CheckoutOptions.cs b/LibGit2Sharp/CheckoutOptions.cs index 9f3554222..5c83c15f1 100644 --- a/LibGit2Sharp/CheckoutOptions.cs +++ b/LibGit2Sharp/CheckoutOptions.cs @@ -3,19 +3,20 @@ namespace LibGit2Sharp { /// - /// Options controlling Checkout behavior. + /// Options controlling Checkout behavior. /// [Flags] + [Obsolete("This type will be removed in the next release.")] public enum CheckoutOptions { /// - /// No checkout flags - use default behavior. + /// No checkout flags - use default behavior. /// None = 0, /// - /// Proceed with checkout even if the index or the working tree differs from HEAD. - /// This will throw away local changes. + /// Proceed with checkout even if the index or the working tree differs from HEAD. + /// This will throw away local changes. /// Force, } diff --git a/LibGit2Sharp/Commit.cs b/LibGit2Sharp/Commit.cs index 62f47d62a..9a2b755ab 100644 --- a/LibGit2Sharp/Commit.cs +++ b/LibGit2Sharp/Commit.cs @@ -11,7 +11,7 @@ namespace LibGit2Sharp { /// - /// A Commit + /// A Commit /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class Commit : GitObject @@ -28,7 +28,7 @@ public class Commit : GitObject private readonly Lazy> lazyNotes; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Commit() { } @@ -51,52 +51,52 @@ internal Commit(Repository repo, ObjectId id) } /// - /// Gets the pointed at by the in the . + /// Gets the pointed at by the in the . /// - /// The relative path to the from the working directory. - /// null if nothing has been found, the otherwise. + /// The relative path to the from the working directory. + /// null if nothing has been found, the otherwise. public virtual TreeEntry this[string relativePath] { get { return Tree[relativePath]; } } /// - /// Gets the commit message. + /// Gets the commit message. /// public virtual string Message { get { return lazyMessage.Value; } } /// - /// Gets the short commit message which is usually the first line of the commit. + /// Gets the short commit message which is usually the first line of the commit. /// public virtual string MessageShort { get { return lazyShortMessage.Value; } } /// - /// Gets the encoding of the message. + /// Gets the encoding of the message. /// public virtual string Encoding { get { return lazyEncoding.Value; } } /// - /// Gets the author of this commit. + /// Gets the author of this commit. /// public virtual Signature Author { get { return lazyAuthor.Value; } } /// - /// Gets the committer. + /// Gets the committer. /// public virtual Signature Committer { get { return lazyCommitter.Value; } } /// - /// Gets the Tree associated to this commit. + /// Gets the Tree associated to this commit. /// public virtual Tree Tree { get { return lazyTree.Value; } } /// - /// 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. + /// 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. /// public virtual IEnumerable Parents { get { return parents; } } /// - /// Gets the notes of this commit. + /// Gets the notes of this commit. /// public virtual IEnumerable Notes { get { return lazyNotes.Value; } } diff --git a/LibGit2Sharp/CommitFilter.cs b/LibGit2Sharp/CommitFilter.cs new file mode 100644 index 000000000..17d91b725 --- /dev/null +++ b/LibGit2Sharp/CommitFilter.cs @@ -0,0 +1,87 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace LibGit2Sharp +{ + /// + /// Criterias used to filter out and order the commits of the repository when querying its history. + /// + public class CommitFilter + { + /// + /// Initializes a new instance of . + /// + public CommitFilter() + { + SortBy = CommitSortStrategies.Time; + Since = "HEAD"; + } + + /// + /// The ordering stragtegy to use. + /// + /// By default, the commits are shown in reverse chronological order. + /// + /// + public CommitSortStrategies SortBy { get; set; } + + /// + /// A pointer to a commit object or a list of pointers to consider as starting points. + /// + /// Can be either a containing the sha or reference canonical name to use, + /// a , a , a , a , + /// a , an or even a mixed collection of all of the above. + /// By default, the will be used as boundary. + /// + /// + public object Since { get; set; } + + internal IList SinceList + { + get { return ToList(Since); } + } + + /// + /// A pointer to a commit object or a list of pointers which will be excluded (along with ancestors) from the enumeration. + /// + /// Can be either a containing the sha or reference canonical name to use, + /// a , a , a , a , + /// a , an or even a mixed collection of all of the above. + /// + /// + public object Until { get; set; } + + internal IList UntilList + { + get { return ToList(Until); } + } + + private static IList ToList(object obj) + { + var list = new List(); + + if (obj == null) + { + return list; + } + + var types = new[] + { + typeof(string), typeof(ObjectId), + typeof(Commit), typeof(TagAnnotation), + typeof(Tag), typeof(Branch), typeof(DetachedHead), + typeof(Reference), typeof(DirectReference), typeof(SymbolicReference) + }; + + if (types.Contains(obj.GetType())) + { + list.Add(obj); + return list; + } + + list.AddRange(((IEnumerable)obj).Cast()); + return list; + } + } +} diff --git a/LibGit2Sharp/CommitLog.cs b/LibGit2Sharp/CommitLog.cs index 9618cd859..2bc6163f9 100644 --- a/LibGit2Sharp/CommitLog.cs +++ b/LibGit2Sharp/CommitLog.cs @@ -9,44 +9,44 @@ namespace LibGit2Sharp { /// - /// A log of commits in a + /// A log of commits in a /// public class CommitLog : IQueryableCommitLog { private readonly Repository repo; - private readonly Filter queryFilter; + private readonly CommitFilter queryFilter; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected CommitLog() { } /// - /// Initializes a new instance of the class. - /// The commits will be enumerated according in reverse chronological order. + /// Initializes a new instance of the class. + /// The commits will be enumerated according in reverse chronological order. /// - /// The repository. + /// The repository. internal CommitLog(Repository repo) - : this(repo, new Filter()) + : this(repo, new CommitFilter()) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The repository. + /// The repository. /// The filter to use in querying commits - internal CommitLog(Repository repo, Filter queryFilter) + internal CommitLog(Repository repo, CommitFilter queryFilter) { this.repo = repo; this.queryFilter = queryFilter; } /// - /// Gets the current sorting strategy applied when enumerating the log + /// Gets the current sorting strategy applied when enumerating the log /// - public virtual GitSortOptions SortedBy + public virtual CommitSortStrategies SortedBy { get { return queryFilter.SortBy; } } @@ -54,18 +54,18 @@ public virtual GitSortOptions SortedBy #region IEnumerable Members /// - /// Returns an enumerator that iterates through the log. + /// Returns an enumerator that iterates through the log. /// - /// An object that can be used to iterate through the log. + /// An object that can be used to iterate through the log. public virtual IEnumerator GetEnumerator() { return new CommitEnumerator(repo, queryFilter); } /// - /// Returns an enumerator that iterates through the log. + /// Returns an enumerator that iterates through the log. /// - /// An object that can be used to iterate through the log. + /// An object that can be used to iterate through the log. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); @@ -74,11 +74,11 @@ IEnumerator IEnumerable.GetEnumerator() #endregion /// - /// Returns the list of commits of the repository matching the specified . + /// Returns the list of commits of the repository matching the specified . /// - /// The options used to control which commits will be returned. + /// The options used to control which commits will be returned. /// A list of commits, ready to be enumerated. - public virtual ICommitLog QueryBy(Filter filter) + public virtual ICommitLog QueryBy(CommitFilter filter) { Ensure.ArgumentNotNull(filter, "filter"); Ensure.ArgumentNotNull(filter.Since, "filter.Since"); @@ -88,10 +88,25 @@ public virtual ICommitLog QueryBy(Filter filter) } /// - /// Find the best possible common ancestor given two s. + /// Returns the list of commits of the repository matching the specified . + /// + /// The options used to control which commits will be returned. + /// A list of commits, ready to be enumerated. + [Obsolete("This method will be removed in the next release. Please use QueryBy(CommitFilter) instead.")] + public virtual ICommitLog QueryBy(Filter filter) + { + Ensure.ArgumentNotNull(filter, "filter"); + Ensure.ArgumentNotNull(filter.Since, "filter.Since"); + Ensure.ArgumentNotNullOrEmptyString(filter.Since.ToString(), "filter.Since"); + + return new CommitLog(repo, filter.ToCommitFilter()); + } + + /// + /// Find the best possible common ancestor given two s. /// - /// The first . - /// The second . + /// The first . + /// The second . /// The common ancestor or null if none found. public virtual Commit FindCommonAncestor(Commit first, Commit second) { @@ -104,9 +119,9 @@ public virtual Commit FindCommonAncestor(Commit first, Commit second) } /// - /// Find the best possible common ancestor given two or more . + /// Find the best possible common ancestor given two or more . /// - /// The s for which to find the common ancestor. + /// The s for which to find the common ancestor. /// The common ancestor or null if none found. public virtual Commit FindCommonAncestor(IEnumerable commits) { @@ -151,7 +166,7 @@ private class CommitEnumerator : IEnumerator private readonly RevWalkerSafeHandle handle; private ObjectId currentOid; - public CommitEnumerator(Repository repo, Filter filter) + public CommitEnumerator(Repository repo, CommitFilter filter) { this.repo = repo; handle = Proxy.git_revwalk_new(repo.Handle); @@ -233,7 +248,7 @@ private void Hide(IList identifier) InternalHidePush(identifier, Proxy.git_revwalk_hide); } - private void Sort(GitSortOptions options) + private void Sort(CommitSortStrategies options) { Proxy.git_revwalk_sorting(handle, options); } diff --git a/LibGit2Sharp/CommitRewriteInfo.cs b/LibGit2Sharp/CommitRewriteInfo.cs new file mode 100644 index 000000000..a341daf5f --- /dev/null +++ b/LibGit2Sharp/CommitRewriteInfo.cs @@ -0,0 +1,61 @@ +namespace LibGit2Sharp +{ + /// + /// Commit metadata when rewriting history + /// + public class CommitRewriteInfo + { + /// + /// The author to be used for the new commit + /// + public Signature Author { get; set; } + + /// + /// The committer to be used for the new commit + /// + public Signature Committer { get; set; } + + /// + /// The message to be used for the new commit + /// + public string Message { get; set; } + + /// + /// Build a from the passed in + /// + /// The whose information is to be copied + /// A new object that matches the info for the . + public static CommitRewriteInfo From(Commit commit) + { + return new CommitRewriteInfo + { + Author = commit.Author, + Committer = commit.Committer, + Message = commit.Message + }; + } + + /// + /// Build a from the passed in, + /// optionally overriding some of its properties + /// + /// The whose information is to be copied + /// Optional override for the author + /// Optional override for the committer + /// Optional override for the message + /// A new object that matches the info for the + /// with the optional parameters replaced.. + public static CommitRewriteInfo From(Commit commit, + Signature author = null, + Signature committer = null, + string message = null) + { + var cri = From(commit); + cri.Author = author ?? cri.Author; + cri.Committer = committer ?? cri.Committer; + cri.Message = message ?? cri.Message; + + return cri; + } + } +} diff --git a/LibGit2Sharp/CommitSortStrategies.cs b/LibGit2Sharp/CommitSortStrategies.cs new file mode 100644 index 000000000..46dc5a085 --- /dev/null +++ b/LibGit2Sharp/CommitSortStrategies.cs @@ -0,0 +1,39 @@ +using System; + +namespace LibGit2Sharp +{ + /// + /// Determines the sorting strategy when iterating through the commits of the repository + /// + [Flags] + public enum CommitSortStrategies + { + /// + /// Sort the commits in no particular ordering; + /// this sorting is arbitrary, implementation-specific + /// and subject to change at any time. + /// + None = 0, + + /// + /// Sort the commits in topological order + /// (parents before children); this sorting mode + /// can be combined with time sorting. + /// + Topological = (1 << 0), + + /// + /// Sort the commits by commit time; + /// this sorting mode can be combined with + /// topological sorting. + /// + Time = (1 << 1), + + /// + /// Iterate through the commits in reverse + /// order; this sorting mode can be combined with + /// any of the above. + /// + Reverse = (1 << 2) + } +} diff --git a/LibGit2Sharp/CompareOptions.cs b/LibGit2Sharp/CompareOptions.cs index c5bee7ed1..b45d41fb4 100644 --- a/LibGit2Sharp/CompareOptions.cs +++ b/LibGit2Sharp/CompareOptions.cs @@ -1,12 +1,12 @@ namespace LibGit2Sharp { /// - /// Options to define file comparison behavior. + /// Options to define file comparison behavior. /// public class CompareOptions { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public CompareOptions() { @@ -15,14 +15,14 @@ public CompareOptions() } /// - /// The number of unchanged lines that define the boundary of a hunk (and to display before and after). - /// (Default = 3) + /// The number of unchanged lines that define the boundary of a hunk (and to display before and after). + /// (Default = 3) /// public int ContextLines { get; set; } /// - /// The maximum number of unchanged lines between hunk boundaries before the hunks will be merged into a one. - /// (Default = 0) + /// The maximum number of unchanged lines between hunk boundaries before the hunks will be merged into a one. + /// (Default = 0) /// public int InterhunkLines { get; set; } } diff --git a/LibGit2Sharp/Configuration.cs b/LibGit2Sharp/Configuration.cs index c47be9600..ed69ad344 100644 --- a/LibGit2Sharp/Configuration.cs +++ b/LibGit2Sharp/Configuration.cs @@ -9,7 +9,7 @@ namespace LibGit2Sharp { /// - /// Provides access to configuration variables for a repository. + /// Provides access to configuration variables for a repository. /// public class Configuration : IDisposable, IEnumerable> @@ -23,7 +23,7 @@ public class Configuration : IDisposable, private ConfigurationSafeHandle configHandle; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Configuration() { } @@ -73,7 +73,7 @@ private void Init() } /// - /// Access configuration values without a repository. Generally you want to access configuration via an instance of instead. + /// Access configuration values without a repository. Generally you want to access configuration via an instance of instead. /// /// Path to a Global configuration file. If null, the default path for a global configuration file will be probed. /// Path to a XDG configuration file. If null, the default path for a XDG configuration file will be probed. @@ -84,7 +84,7 @@ public Configuration(string globalConfigurationFileLocation = null, string xdgCo } /// - /// Determines which configuration file has been found. + /// Determines which configuration file has been found. /// public virtual bool HasConfig(ConfigurationLevel level) { @@ -97,8 +97,8 @@ public virtual bool HasConfig(ConfigurationLevel level) #region IDisposable Members /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// Saves any open configuration files. + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// Saves any open configuration files. /// public void Dispose() { @@ -109,10 +109,10 @@ public void Dispose() #endregion /// - /// Unset a configuration variable (key and value). + /// Unset a configuration variable (key and value). /// - /// The key to unset. - /// The configuration file which should be considered as the target of this operation + /// The key to unset. + /// The configuration file which should be considered as the target of this operation public virtual void Unset(string key, ConfigurationLevel level = ConfigurationLevel.Local) { Ensure.ArgumentNotNullOrEmptyString(key, "key"); @@ -124,7 +124,7 @@ public virtual void Unset(string key, ConfigurationLevel level = ConfigurationLe } /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// protected virtual void Dispose(bool disposing) { @@ -132,33 +132,33 @@ protected virtual void Dispose(bool disposing) } /// - /// Get a configuration value for a key. Keys are in the form 'section.name'. - /// - /// The same escalation logic than in git.git will be used when looking for the key in the config files: - /// - local: the Git file in the current repository - /// - global: the Git file specific to the current interactive user (usually in `$HOME/.gitconfig`) - /// - xdg: another Git file specific to the current interactive user (usually in `$HOME/.config/git/config`) - /// - system: the system-wide Git file + /// Get a configuration value for a key. Keys are in the form 'section.name'. + /// + /// The same escalation logic than in git.git will be used when looking for the key in the config files: + /// - local: the Git file in the current repository + /// - global: the Git file specific to the current interactive user (usually in `$HOME/.gitconfig`) + /// - xdg: another Git file specific to the current interactive user (usually in `$HOME/.config/git/config`) + /// - system: the system-wide Git file /// - /// The first occurence of the key will be returned. - /// - /// - /// For example in order to get the value for this in a .git\config file: + /// The first occurence of the key will be returned. + /// + /// + /// For example in order to get the value for this in a .git\config file: /// - /// - /// [core] - /// bare = true - /// + /// + /// [core] + /// bare = true + /// /// - /// You would call: + /// You would call: /// - /// - /// bool isBare = repo.Config.Get<bool>("core.bare").Value; - /// - /// + /// + /// bool isBare = repo.Config.Get<bool>("core.bare").Value; + /// + /// /// - /// The configuration value type - /// The key + /// The configuration value type + /// The key /// The , or null if not set public virtual ConfigurationEntry Get(string key) { @@ -168,25 +168,25 @@ public virtual ConfigurationEntry Get(string key) } /// - /// Get a configuration value for a key. Keys are in the form 'section.name'. - /// - /// For example in order to get the value for this in a .git\config file: + /// Get a configuration value for a key. Keys are in the form 'section.name'. + /// + /// For example in order to get the value for this in a .git\config file: /// - /// - /// [core] - /// bare = true - /// + /// + /// [core] + /// bare = true + /// /// - /// You would call: + /// You would call: /// - /// - /// bool isBare = repo.Config.Get<bool>("core.bare").Value; - /// - /// + /// + /// bool isBare = repo.Config.Get<bool>("core.bare").Value; + /// + /// /// - /// The configuration value type - /// The key - /// The configuration file into which the key should be searched for + /// The configuration value type + /// The key + /// The configuration file into which the key should be searched for /// The , or null if not set public virtual ConfigurationEntry Get(string key, ConfigurationLevel level) { @@ -204,22 +204,22 @@ public virtual ConfigurationEntry Get(string key, ConfigurationLevel level } /// - /// Set a configuration value for a key. Keys are in the form 'section.name'. - /// - /// For example in order to set the value for this in a .git\config file: + /// Set a configuration value for a key. Keys are in the form 'section.name'. + /// + /// For example in order to set the value for this in a .git\config file: /// - /// [test] - /// boolsetting = true + /// [test] + /// boolsetting = true /// - /// You would call: + /// You would call: /// - /// repo.Config.Set("test.boolsetting", true); - /// + /// repo.Config.Set("test.boolsetting", true); + /// /// - /// The configuration value type - /// The key parts - /// The value - /// The configuration file which should be considered as the target of this operation + /// The configuration value type + /// The key parts + /// The value + /// The configuration file which should be considered as the target of this operation public virtual void Set(string key, T value, ConfigurationLevel level = ConfigurationLevel.Local) { Ensure.ArgumentNotNullOrEmptyString(key, "key"); diff --git a/LibGit2Sharp/ConfigurationEntry.cs b/LibGit2Sharp/ConfigurationEntry.cs index 129dcc6b7..2a46373ea 100644 --- a/LibGit2Sharp/ConfigurationEntry.cs +++ b/LibGit2Sharp/ConfigurationEntry.cs @@ -26,7 +26,7 @@ public class ConfigurationEntry public virtual ConfigurationLevel Level { get; private set; } /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected ConfigurationEntry() { } diff --git a/LibGit2Sharp/ConfigurationExtensions.cs b/LibGit2Sharp/ConfigurationExtensions.cs index e9aed40a8..a84a7f9df 100644 --- a/LibGit2Sharp/ConfigurationExtensions.cs +++ b/LibGit2Sharp/ConfigurationExtensions.cs @@ -3,30 +3,30 @@ namespace LibGit2Sharp { /// - /// Provides helper overloads to a . + /// Provides helper overloads to a . /// public static class ConfigurationExtensions { /// - /// Get a configuration value for the given key parts. - /// - /// For example in order to get the value for this in a .git\config file: + /// Get a configuration value for the given key parts. + /// + /// For example in order to get the value for this in a .git\config file: /// - /// - /// [core] - /// bare = true - /// + /// + /// [core] + /// bare = true + /// /// - /// You would call: + /// You would call: /// - /// - /// bool isBare = repo.Config.Get<bool>(new []{ "core", "bare" }).Value; - /// - /// + /// + /// bool isBare = repo.Config.Get<bool>(new []{ "core", "bare" }).Value; + /// + /// /// - /// The configuration value type - /// The configuration being worked with. - /// The key parts + /// The configuration value type + /// The configuration being worked with. + /// The key parts /// The , or null if not set public static ConfigurationEntry Get(this Configuration config, string[] keyParts) { @@ -36,27 +36,27 @@ public static ConfigurationEntry Get(this Configuration config, string[] k } /// - /// Get a configuration value for the given key parts. - /// - /// For example in order to get the value for this in a .git\config file: + /// Get a configuration value for the given key parts. + /// + /// For example in order to get the value for this in a .git\config file: /// - /// - /// [difftool "kdiff3"] - /// path = c:/Program Files/KDiff3/kdiff3.exe - /// + /// + /// [difftool "kdiff3"] + /// path = c:/Program Files/KDiff3/kdiff3.exe + /// /// - /// You would call: + /// You would call: /// - /// - /// string where = repo.Config.Get<string>("difftool", "kdiff3", "path").Value; - /// - /// + /// + /// string where = repo.Config.Get<string>("difftool", "kdiff3", "path").Value; + /// + /// /// - /// The configuration value type - /// The configuration being worked with. - /// The first key part - /// The second key part - /// The third key part + /// The configuration value type + /// The configuration being worked with. + /// The first key part + /// The second key part + /// The third key part /// The , or null if not set public static ConfigurationEntry Get(this Configuration config, string firstKeyPart, string secondKeyPart, string thirdKeyPart) { diff --git a/LibGit2Sharp/ConfigurationLevel.cs b/LibGit2Sharp/ConfigurationLevel.cs index 605d2f335..b8ab12097 100644 --- a/LibGit2Sharp/ConfigurationLevel.cs +++ b/LibGit2Sharp/ConfigurationLevel.cs @@ -1,27 +1,27 @@ namespace LibGit2Sharp { /// - /// Specifies the level of configuration to use. + /// Specifies the level of configuration to use. /// public enum ConfigurationLevel { /// - /// The local .git/config of the current repository. + /// The local .git/config of the current repository. /// Local = 4, /// - /// The global ~/.gitconfig of the current user. + /// The global ~/.gitconfig of the current user. /// Global = 3, /// - /// The global ~/.config/git/config of the current user. + /// The global ~/.config/git/config of the current user. /// Xdg = 2, /// - /// The system wide .gitconfig. + /// The system wide .gitconfig. /// System = 1, } diff --git a/LibGit2Sharp/Conflict.cs b/LibGit2Sharp/Conflict.cs index 64c2c9272..252535af1 100644 --- a/LibGit2Sharp/Conflict.cs +++ b/LibGit2Sharp/Conflict.cs @@ -21,7 +21,7 @@ public class Conflict : IEquatable new LambdaEqualityHelper(x => x.Ancestor, x => x.Ours, x => x.Theirs); /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Conflict() { } @@ -61,13 +61,13 @@ public virtual IndexEntry Theirs } /// - /// Determines whether the specified is - /// equal to the current . + /// Determines whether the specified is + /// equal to the current . /// - /// The to compare with - /// the current . - /// true if the specified is equal - /// to the current ; otherwise, + /// The to compare with + /// the current . + /// true if the specified is equal + /// to the current ; otherwise, /// false. public override bool Equals(object obj) { @@ -75,13 +75,13 @@ public override bool Equals(object obj) } /// - /// Determines whether the specified - /// is equal to the current . + /// Determines whether the specified + /// is equal to the current . /// - /// The to compare - /// with the current . - /// true if the specified is equal - /// to the current ; otherwise, + /// The to compare + /// with the current . + /// true if the specified is equal + /// to the current ; otherwise, /// false. public bool Equals(Conflict other) { @@ -89,7 +89,7 @@ public bool Equals(Conflict other) } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -98,10 +98,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(Conflict left, Conflict right) { @@ -109,10 +109,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(Conflict left, Conflict right) { diff --git a/LibGit2Sharp/ConflictCollection.cs b/LibGit2Sharp/ConflictCollection.cs index e0b38a422..ff54ee2e0 100644 --- a/LibGit2Sharp/ConflictCollection.cs +++ b/LibGit2Sharp/ConflictCollection.cs @@ -16,7 +16,7 @@ public class ConflictCollection : IEnumerable private readonly Repository repo; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected ConflictCollection() { } @@ -27,7 +27,7 @@ internal ConflictCollection(Repository repo) } /// - /// Gets the for the + /// Gets the for the /// specified relative path. /// /// The relative path to query @@ -94,18 +94,18 @@ private List AllConflicts() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { return AllConflicts().GetEnumerator(); } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); diff --git a/LibGit2Sharp/ContentChanges.cs b/LibGit2Sharp/ContentChanges.cs index 207dc9055..55e6f58c1 100644 --- a/LibGit2Sharp/ContentChanges.cs +++ b/LibGit2Sharp/ContentChanges.cs @@ -5,12 +5,12 @@ namespace LibGit2Sharp { /// - /// Holds the changes between two s. + /// Holds the changes between two s. /// public class ContentChanges : Changes { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected ContentChanges() { } diff --git a/LibGit2Sharp/CopyNativeDependencies.targets b/LibGit2Sharp/CopyNativeDependencies.targets new file mode 100644 index 000000000..64f78d5b0 --- /dev/null +++ b/LibGit2Sharp/CopyNativeDependencies.targets @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/LibGit2Sharp/Core/ArrayMarshaler.cs b/LibGit2Sharp/Core/ArrayMarshaler.cs new file mode 100644 index 000000000..b831f6dbc --- /dev/null +++ b/LibGit2Sharp/Core/ArrayMarshaler.cs @@ -0,0 +1,40 @@ +using System; +using System.Runtime.InteropServices; + +namespace LibGit2Sharp.Core +{ + internal class ArrayMarshaler : IDisposable + { + private readonly IntPtr[] ptrs; + + public ArrayMarshaler(T[] objs) + { + ptrs = new IntPtr[objs.Length]; + + for (var i = 0; i < objs.Length; i++) + { + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T))); + ptrs[i] = ptr; + Marshal.StructureToPtr(objs[i], ptr, false); + } + } + + public int Count + { + get { return ptrs.Length; } + } + + public IntPtr[] ToArray() + { + return ptrs; + } + + public void Dispose() + { + foreach (var ptr in ptrs) + { + Marshal.FreeHGlobal(ptr); + } + } + } +} diff --git a/LibGit2Sharp/Core/Compat/Lazy.cs b/LibGit2Sharp/Core/Compat/Lazy.cs index 2891920c2..2f08a24a9 100644 --- a/LibGit2Sharp/Core/Compat/Lazy.cs +++ b/LibGit2Sharp/Core/Compat/Lazy.cs @@ -4,9 +4,9 @@ namespace LibGit2Sharp.Core.Compat { /// - /// Provides support for lazy initialization. + /// Provides support for lazy initialization. /// - /// Specifies the type of object that is being lazily initialized. + /// Specifies the type of object that is being lazily initialized. [DebuggerStepThrough] public class Lazy { @@ -16,9 +16,9 @@ public class Lazy private readonly object padLock = new object(); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// + /// The that will be called to evaluate the value of this Lazy instance. public Lazy(Func evaluator) { Ensure.ArgumentNotNull(evaluator, "evaluator"); @@ -27,7 +27,7 @@ public Lazy(Func evaluator) } /// - /// Gets the lazily initialized value of the current instance. + /// Gets the lazily initialized value of the current instance. /// public TType Value { diff --git a/LibGit2Sharp/Core/Compat/Tuple.cs b/LibGit2Sharp/Core/Compat/Tuple.cs index cc863032c..b8cf7f005 100644 --- a/LibGit2Sharp/Core/Compat/Tuple.cs +++ b/LibGit2Sharp/Core/Compat/Tuple.cs @@ -3,16 +3,16 @@ namespace LibGit2Sharp.Core.Compat { /// - /// Represents a 2-tuple, or pair. + /// Represents a 2-tuple, or pair. /// - /// The type of the tuple's first component. - /// The type of the tuple's second component. + /// The type of the tuple's first component. + /// The type of the tuple's second component. public class Tuple { private readonly KeyValuePair kvp; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The value of the tuple's first component. /// The value of the tuple's second component. @@ -22,7 +22,7 @@ public Tuple(T1 item1, T2 item2) } /// - /// Gets the value of the current object's second component. + /// Gets the value of the current object's second component. /// public T2 Item2 { @@ -30,7 +30,7 @@ public T2 Item2 } /// - /// Gets the value of the current object's first component. + /// Gets the value of the current object's first component. /// public T1 Item1 { @@ -38,7 +38,7 @@ public T1 Item1 } /// - /// Returns the hash code for the current object. + /// Returns the hash code for the current object. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -47,9 +47,9 @@ public override int GetHashCode() } /// - /// Returns a value that indicates whether the current object is equal to a specified object. + /// Returns a value that indicates whether the current object is equal to a specified object. /// - /// The object to compare with this instance. + /// The object to compare with this instance. /// true if the current instance is equal to the specified object; otherwise, false. public override bool Equals(object obj) { diff --git a/LibGit2Sharp/Core/DisposableEnumerable.cs b/LibGit2Sharp/Core/DisposableEnumerable.cs deleted file mode 100644 index c885c3544..000000000 --- a/LibGit2Sharp/Core/DisposableEnumerable.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace LibGit2Sharp.Core -{ - internal class DisposableEnumerable : IEnumerable, IDisposable where T : IDisposable - { - private readonly IList enumerable; - - public DisposableEnumerable(IList enumerable) - { - this.enumerable = enumerable; - } - - public int Count - { - get { return enumerable.Count; } - } - - public IEnumerator GetEnumerator() - { - return enumerable.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public void Dispose() - { - foreach (var entry in enumerable) - { - entry.Dispose(); - } - } - } -} diff --git a/LibGit2Sharp/Core/Ensure.cs b/LibGit2Sharp/Core/Ensure.cs index d09ec6162..d5afe80d5 100644 --- a/LibGit2Sharp/Core/Ensure.cs +++ b/LibGit2Sharp/Core/Ensure.cs @@ -5,16 +5,16 @@ namespace LibGit2Sharp.Core { /// - /// Ensure input parameters + /// Ensure input parameters /// [DebuggerStepThrough] internal static class Ensure { /// - /// Checks an argument to ensure it isn't null. + /// Checks an argument to ensure it isn't null. /// - /// The argument value to check. - /// The name of the argument. + /// The argument value to check. + /// The name of the argument. public static void ArgumentNotNull(object argumentValue, string argumentName) { if (argumentValue == null) @@ -24,10 +24,10 @@ public static void ArgumentNotNull(object argumentValue, string argumentName) } /// - /// Checks a string argument to ensure it isn't null or empty. + /// Checks a string argument to ensure it isn't null or empty. /// - /// The argument value to check. - /// The name of the argument. + /// The argument value to check. + /// The name of the argument. public static void ArgumentNotNullOrEmptyString(string argumentValue, string argumentName) { ArgumentNotNull(argumentValue, argumentName); @@ -55,6 +55,9 @@ private static void HandleError(int result) switch (result) { + case (int) GitErrorCode.User: + throw new UserCancelledException(errorMessage, (GitErrorCode)result, error.Category); + case (int)GitErrorCode.BareRepo: throw new BareRepositoryException(errorMessage, (GitErrorCode)result, error.Category); @@ -79,13 +82,13 @@ private static void HandleError(int result) } /// - /// Check that the result of a C call was successful - /// - /// The native function is expected to return strictly 0 for - /// success or a negative value in the case of failure. - /// + /// Check that the result of a C call was successful + /// + /// The native function is expected to return strictly 0 for + /// success or a negative value in the case of failure. + /// /// - /// The result to examine. + /// The result to examine. public static void ZeroResult(int result) { if (result == (int)GitErrorCode.Ok) @@ -97,14 +100,14 @@ public static void ZeroResult(int result) } /// - /// Check that the result of a C call that returns a boolean value - /// was successful - /// - /// The native function is expected to return strictly 0 for - /// success or a negative value in the case of failure. - /// + /// Check that the result of a C call that returns a boolean value + /// was successful + /// + /// The native function is expected to return strictly 0 for + /// success or a negative value in the case of failure. + /// /// - /// The result to examine. + /// The result to examine. public static void BooleanResult(int result) { if (result == (int)GitErrorCode.Ok || result == 1) @@ -116,14 +119,14 @@ public static void BooleanResult(int result) } /// - /// Check that the result of a C call that returns an integer value - /// was successful - /// - /// The native function is expected to return strictly 0 for - /// success or a negative value in the case of failure. - /// + /// Check that the result of a C call that returns an integer value + /// was successful + /// + /// The native function is expected to return strictly 0 for + /// success or a negative value in the case of failure. + /// /// - /// The result to examine. + /// The result to examine. public static void Int32Result(int result) { if (result >= (int)GitErrorCode.Ok) @@ -135,11 +138,11 @@ public static void Int32Result(int result) } /// - /// Checks an argument by applying provided checker. + /// Checks an argument by applying provided checker. /// - /// The argument value to check. - /// The predicate which has to be satisfied - /// The name of the argument. + /// The argument value to check. + /// The predicate which has to be satisfied + /// The name of the argument. public static void ArgumentConformsTo(T argumentValue, Func checker, string argumentName) { if (checker(argumentValue)) diff --git a/LibGit2Sharp/Core/Epoch.cs b/LibGit2Sharp/Core/Epoch.cs index 101883f65..963314d08 100644 --- a/LibGit2Sharp/Core/Epoch.cs +++ b/LibGit2Sharp/Core/Epoch.cs @@ -3,18 +3,18 @@ namespace LibGit2Sharp.Core { /// - /// Provides helper methods to help converting between Epoch (unix timestamp) and . + /// Provides helper methods to help converting between Epoch (unix timestamp) and . /// public static class Epoch { private static readonly DateTimeOffset epochDateTimeOffset = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero); /// - /// Builds a from a Unix timestamp and a timezone offset. + /// Builds a from a Unix timestamp and a timezone offset. /// - /// The number of seconds since 00:00:00 UTC on 1 January 1970. - /// The number of minutes from UTC in a timezone. - /// A representing this instant. + /// The number of seconds since 00:00:00 UTC on 1 January 1970. + /// The number of minutes from UTC in a timezone. + /// A representing this instant. public static DateTimeOffset ToDateTimeOffset(long secondsSinceEpoch, int timeZoneOffsetInMinutes) { DateTimeOffset utcDateTime = epochDateTimeOffset.AddSeconds(secondsSinceEpoch); @@ -23,9 +23,9 @@ public static DateTimeOffset ToDateTimeOffset(long secondsSinceEpoch, int timeZo } /// - /// Converts the part of a into a Unix timestamp. + /// Converts the part of a into a Unix timestamp. /// - /// The to convert. + /// The to convert. /// The number of seconds since 00:00:00 UTC on 1 January 1970. public static Int32 ToSecondsSinceEpoch(this DateTimeOffset date) { diff --git a/LibGit2Sharp/Core/FilePathMarshaler.cs b/LibGit2Sharp/Core/FilePathMarshaler.cs index 97f81fa2e..5c7f72247 100644 --- a/LibGit2Sharp/Core/FilePathMarshaler.cs +++ b/LibGit2Sharp/Core/FilePathMarshaler.cs @@ -5,14 +5,14 @@ namespace LibGit2Sharp.Core { /// - /// This marshaler is to be used for capturing a UTF-8 string owned by libgit2 and - /// converting it to a managed FilePath instance. The marshaler will not attempt to - /// free the native pointer after conversion, because the memory is owned by libgit2. + /// This marshaler is to be used for capturing a UTF-8 string owned by libgit2 and + /// converting it to a managed FilePath instance. The marshaler will not attempt to + /// free the native pointer after conversion, because the memory is owned by libgit2. /// - /// Use this marshaler for return values, for example: - /// [return: MarshalAs(UnmanagedType.CustomMarshaler, - /// MarshalCookie = UniqueId.UniqueIdentifier, - /// MarshalTypeRef = typeof(FilePathNoCleanupMarshaler))] + /// Use this marshaler for return values, for example: + /// [return: MarshalAs(UnmanagedType.CustomMarshaler, + /// MarshalCookie = UniqueId.UniqueIdentifier, + /// MarshalTypeRef = typeof(FilePathNoCleanupMarshaler))] /// internal class FilePathNoCleanupMarshaler : FilePathMarshaler { @@ -33,18 +33,18 @@ public override void CleanUpNativeData(IntPtr pNativeData) } /// - /// This marshaler is to be used for sending managed FilePath instances to libgit2. - /// The marshaler will allocate a buffer in native memory to hold the UTF-8 string - /// and perform the encoding conversion using that buffer as the target. The pointer - /// received by libgit2 will be to this buffer. After the function call completes, the - /// native buffer is freed. + /// This marshaler is to be used for sending managed FilePath instances to libgit2. + /// The marshaler will allocate a buffer in native memory to hold the UTF-8 string + /// and perform the encoding conversion using that buffer as the target. The pointer + /// received by libgit2 will be to this buffer. After the function call completes, the + /// native buffer is freed. /// - /// Use this marshaler for function parameters, for example: - /// [DllImport(libgit2)] - /// internal static extern int git_index_open(out IndexSafeHandle index, - /// [MarshalAs(UnmanagedType.CustomMarshaler, - /// MarshalCookie = UniqueId.UniqueIdentifier, - /// MarshalTypeRef = typeof(FilePathMarshaler))] FilePath indexpath); + /// Use this marshaler for function parameters, for example: + /// [DllImport(libgit2)] + /// internal static extern int git_index_open(out IndexSafeHandle index, + /// [MarshalAs(UnmanagedType.CustomMarshaler, + /// MarshalCookie = UniqueId.UniqueIdentifier, + /// MarshalTypeRef = typeof(FilePathMarshaler))] FilePath indexpath); /// internal class FilePathMarshaler : ICustomMarshaler { diff --git a/LibGit2Sharp/Core/GitCheckoutOpts.cs b/LibGit2Sharp/Core/GitCheckoutOpts.cs index 159ba5810..eedec66ad 100644 --- a/LibGit2Sharp/Core/GitCheckoutOpts.cs +++ b/LibGit2Sharp/Core/GitCheckoutOpts.cs @@ -7,22 +7,22 @@ namespace LibGit2Sharp.Core internal enum CheckoutStrategy { /// - /// Default is a dry run, no actual updates. + /// Default is a dry run, no actual updates. /// GIT_CHECKOUT_NONE = 0, /// - /// Allow safe updates that cannot overwrite uncommited data. + /// Allow safe updates that cannot overwrite uncommited data. /// GIT_CHECKOUT_SAFE = (1 << 0), /// - /// Allow safe updates plus creation of missing files. + /// Allow safe updates plus creation of missing files. /// GIT_CHECKOUT_SAFE_CREATE = (1 << 1), /// - /// Allow update of entries in working dir that are modified from HEAD. + /// Allow update of entries in working dir that are modified from HEAD. /// GIT_CHECKOUT_FORCE = (1 << 2), @@ -80,19 +80,8 @@ internal enum CheckoutStrategy GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1 << 17), } - [Flags] - internal enum NotifyFlags - { - GIT_CHECKOUT_NOTIFY_NONE = 0, - GIT_CHECKOUT_NOTIFY_CONFLICT = (1 << 0), - GIT_CHECKOUT_NOTIFY_DIRTY = (1 << 1), - GIT_CHECKOUT_NOTIFY_UPDATED = (1 << 2), - GIT_CHECKOUT_NOTIFY_UNTRACKED = (1 << 3), - GIT_CHECKOUT_NOTIFY_IGNORED = (1 << 4), - } - internal delegate int checkout_notify_cb( - NotifyFlags why, + CheckoutNotifyFlags why, IntPtr path, IntPtr baseline, IntPtr target, @@ -106,7 +95,7 @@ internal delegate void progress_cb( IntPtr payload); [StructLayout(LayoutKind.Sequential)] - internal struct GitCheckoutOpts + internal struct GitCheckoutOpts :IDisposable { public uint version; @@ -117,15 +106,26 @@ internal struct GitCheckoutOpts public uint FileMode; public int FileOpenFlags; - public NotifyFlags notify_flags; + public CheckoutNotifyFlags notify_flags; public checkout_notify_cb notify_cb; public IntPtr notify_payload; public progress_cb progress_cb; public IntPtr progress_payload; - public UnSafeNativeMethods.git_strarray paths; + public GitStrArrayIn paths; public IntPtr baseline; + public IntPtr target_directory; + + public void Dispose() + { + if (paths == null) + { + return; + } + + paths.Dispose(); + } } } diff --git a/LibGit2Sharp/Core/GitDiff.cs b/LibGit2Sharp/Core/GitDiff.cs index fc4ea3ae7..5fd121ec7 100644 --- a/LibGit2Sharp/Core/GitDiff.cs +++ b/LibGit2Sharp/Core/GitDiff.cs @@ -7,65 +7,65 @@ namespace LibGit2Sharp.Core internal enum GitDiffOptionFlags { /// - /// Normal diff, the default. + /// Normal diff, the default. /// GIT_DIFF_NORMAL = 0, /// - /// Reverse the sides of the diff. + /// Reverse the sides of the diff. /// GIT_DIFF_REVERSE = (1 << 0), /// - /// Treat all files as text, disabling binary attributes and detection. + /// Treat all files as text, disabling binary attributes and detection. /// GIT_DIFF_FORCE_TEXT = (1 << 1), /// - /// Ignore all whitespace. + /// Ignore all whitespace. /// GIT_DIFF_IGNORE_WHITESPACE = (1 << 2), /// - /// Ignore changes in amount of whitespace. + /// Ignore changes in amount of whitespace. /// GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1 << 3), /// - /// Ignore whitespace at end of line. + /// Ignore whitespace at end of line. /// GIT_DIFF_IGNORE_WHITESPACE_EOL = (1 << 4), /// - /// Exclude submodules from the diff completely. + /// Exclude submodules from the diff completely. /// GIT_DIFF_IGNORE_SUBMODULES = (1 << 5), /// - /// Use the "patience diff" algorithm (currently unimplemented). + /// Use the "patience diff" algorithm (currently unimplemented). /// GIT_DIFF_PATIENCE = (1 << 6), /// - /// Include ignored files in the diff list. + /// Include ignored files in the diff list. /// GIT_DIFF_INCLUDE_IGNORED = (1 << 7), /// - /// Include untracked files in the diff list. + /// Include untracked files in the diff list. /// GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8), /// - /// Include unmodified files in the diff list. + /// Include unmodified files in the diff list. /// GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9), /// - /// Even with the GIT_DIFF_INCLUDE_UNTRACKED flag, when an untracked - /// directory is found, only a single entry for the directory is added - /// to the diff list; with this flag, all files under the directory will - /// be included, too. + /// Even with the GIT_DIFF_INCLUDE_UNTRACKED flag, when an untracked + /// directory is found, only a single entry for the directory is added + /// to the diff list; with this flag, all files under the directory will + /// be included, too. /// GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10), @@ -76,12 +76,12 @@ internal enum GitDiffOptionFlags GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11), /// - /// Use case insensitive filename comparisons. + /// Use case insensitive filename comparisons. /// GIT_DIFF_DELTAS_ARE_ICASE = (1 << 12), /// - /// When generating patch text, include the content of untracked files. + /// When generating patch text, include the content of untracked files. /// GIT_DIFF_INCLUDE_UNTRACKED_CONTENT = (1 << 13), @@ -108,57 +108,11 @@ internal enum GitDiffOptionFlags GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1 << 16), /// - /// Ignore file mode changes. + /// Ignore file mode changes. /// GIT_DIFF_IGNORE_FILEMODE = (1 << 17), } - [StructLayout(LayoutKind.Sequential)] - internal class GitStrArrayIn : IDisposable - { - public IntPtr strings; - public uint size; - - public static GitStrArrayIn BuildFrom(FilePath[] paths) - { - var nbOfPaths = paths.Length; - var pathPtrs = new IntPtr[nbOfPaths]; - - for (int i = 0; i < nbOfPaths; i++) - { - var s = paths[i].Posix; - pathPtrs[i] = FilePathMarshaler.FromManaged(s); - } - - int dim = IntPtr.Size * nbOfPaths; - - IntPtr arrayPtr = Marshal.AllocHGlobal(dim); - Marshal.Copy(pathPtrs, 0, arrayPtr, nbOfPaths); - - return new GitStrArrayIn { strings = arrayPtr, size = (uint)nbOfPaths }; - } - - public void Dispose() - { - if (size == 0) - { - return; - } - - var nbOfPaths = (int)size; - - var pathPtrs = new IntPtr[nbOfPaths]; - Marshal.Copy(strings, pathPtrs, 0, nbOfPaths); - - for (int i = 0; i < nbOfPaths; i ++) - { - Marshal.FreeHGlobal(pathPtrs[i]); - } - - Marshal.FreeHGlobal(strings); - } - } - internal delegate int diff_notify_cb( IntPtr diff_so_far, IntPtr delta_to_add, @@ -191,8 +145,6 @@ public void Dispose() } PathSpec.Dispose(); - - PathSpec.size = 0; } } diff --git a/LibGit2Sharp/Core/GitErrorCode.cs b/LibGit2Sharp/Core/GitErrorCode.cs index 0b59fcf50..67eeadfdb 100644 --- a/LibGit2Sharp/Core/GitErrorCode.cs +++ b/LibGit2Sharp/Core/GitErrorCode.cs @@ -6,67 +6,67 @@ internal enum GitErrorCode Error = -1, /// - /// Input does not exist in the scope searched. + /// Input does not exist in the scope searched. /// NotFound = -3, /// - /// Input already exists in the processed scope. + /// Input already exists in the processed scope. /// Exists = -4, /// - /// The given short oid is ambiguous. + /// The given short oid is ambiguous. /// Ambiguous = -5, /// - /// Buffer related issue. + /// Buffer related issue. /// Buffer = -6, /// - /// Callback error. + /// Callback error. /// User = -7, /// - /// Operation cannot be performed against a bare repository. + /// Operation cannot be performed against a bare repository. /// BareRepo = -8, /// - /// Operation cannot be performed against an orphaned HEAD. + /// Operation cannot be performed against an orphaned HEAD. /// OrphanedHead = -9, /// - /// Operation cannot be performed against a not fully merged index. + /// Operation cannot be performed against a not fully merged index. /// UnmergedEntries = -10, /// - /// Push cannot be performed against the remote without losing commits. + /// Push cannot be performed against the remote without losing commits. /// NonFastForward = -11, /// - /// Input is not a valid specification. + /// Input is not a valid specification. /// InvalidSpecification = -12, /// - /// A conflicting change has been detected. + /// A conflicting change has been detected. /// MergeConflict = -13, /// - /// Skip and passthrough the given ODB backend. + /// Skip and passthrough the given ODB backend. /// PassThrough = -30, /// - /// There are no more entries left to iterate. + /// There are no more entries left to iterate. /// IterOver = -31, } diff --git a/LibGit2Sharp/Core/GitObjectType.cs b/LibGit2Sharp/Core/GitObjectType.cs index 43fff2445..a099c4806 100644 --- a/LibGit2Sharp/Core/GitObjectType.cs +++ b/LibGit2Sharp/Core/GitObjectType.cs @@ -3,57 +3,57 @@ namespace LibGit2Sharp.Core { /// - /// Underlying type of a + /// Underlying type of a /// internal enum GitObjectType { /// - /// Object can be of any type. + /// Object can be of any type. /// Any = -2, /// - /// Object is invalid. + /// Object is invalid. /// Bad = -1, /// - /// Reserved for future use. + /// Reserved for future use. /// Ext1 = 0, /// - /// A commit object. + /// A commit object. /// Commit = 1, /// - /// A tree (directory listing) object. + /// A tree (directory listing) object. /// Tree = 2, /// - /// A file revision object. + /// A file revision object. /// Blob = 3, /// - /// An annotated tag object. + /// An annotated tag object. /// Tag = 4, /// - /// Reserved for future use. + /// Reserved for future use. /// Ext2 = 5, /// - /// A delta, base is given by an offset. + /// A delta, base is given by an offset. /// OfsDelta = 6, /// - /// A delta, base is given by object id. + /// A delta, base is given by object id. /// RefDelta = 7 } diff --git a/LibGit2Sharp/Core/GitOid.cs b/LibGit2Sharp/Core/GitOid.cs index 027335719..8b6947a8d 100644 --- a/LibGit2Sharp/Core/GitOid.cs +++ b/LibGit2Sharp/Core/GitOid.cs @@ -3,12 +3,12 @@ namespace LibGit2Sharp.Core { /// - /// Represents a unique id in git which is the sha1 hash of this id's content. + /// Represents a unique id in git which is the sha1 hash of this id's content. /// internal struct GitOid { /// - /// The raw binary 20 byte Id. + /// The raw binary 20 byte Id. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] Id; diff --git a/LibGit2Sharp/Core/GitRemoteCallbacks.cs b/LibGit2Sharp/Core/GitRemoteCallbacks.cs index 123655ce8..b1b2f7bcc 100644 --- a/LibGit2Sharp/Core/GitRemoteCallbacks.cs +++ b/LibGit2Sharp/Core/GitRemoteCallbacks.cs @@ -4,7 +4,7 @@ namespace LibGit2Sharp.Core { /// - /// Structure for git_remote_callbacks + /// Structure for git_remote_callbacks /// [StructLayout(LayoutKind.Sequential)] internal struct GitRemoteCallbacks diff --git a/LibGit2Sharp/Core/GitRepositoryInitOptions.cs b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs new file mode 100644 index 000000000..da202b94e --- /dev/null +++ b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs @@ -0,0 +1,64 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace LibGit2Sharp.Core +{ + [StructLayout(LayoutKind.Sequential)] + internal class GitRepositoryInitOptions : IDisposable + { + public uint Version = 1; + public GitRepositoryInitFlags Flags; + public int Mode; + public IntPtr WorkDirPath; + public IntPtr Description; + public IntPtr TemplatePath; + public IntPtr InitialHead; + public IntPtr OriginUrl; + + public static GitRepositoryInitOptions BuildFrom(FilePath workdirPath, bool isBare) + { + var opts = new GitRepositoryInitOptions + { + Flags = GitRepositoryInitFlags.GIT_REPOSITORY_INIT_MKPATH, + Mode = 0 /* GIT_REPOSITORY_INIT_SHARED_UMASK */ + }; + + if (workdirPath != null) + { + Debug.Assert(!isBare); + + opts.WorkDirPath = FilePathMarshaler.FromManaged(workdirPath); + } + + if (isBare) + { + opts.Flags |= GitRepositoryInitFlags.GIT_REPOSITORY_INIT_BARE; + } + + return opts; + } + + public void Dispose() + { + if (WorkDirPath == IntPtr.Zero) + { + return; + } + + Marshal.FreeHGlobal(WorkDirPath); + WorkDirPath = IntPtr.Zero; + } + } + + [Flags] + internal enum GitRepositoryInitFlags + { + GIT_REPOSITORY_INIT_BARE = (1 << 0), + GIT_REPOSITORY_INIT_NO_REINIT = (1 << 1), + GIT_REPOSITORY_INIT_NO_DOTGIT_DIR = (1 << 2), + GIT_REPOSITORY_INIT_MKDIR = (1 << 3), + GIT_REPOSITORY_INIT_MKPATH = (1 << 4), + GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1 << 5), + } +} diff --git a/LibGit2Sharp/Core/GitStrArrayIn.cs b/LibGit2Sharp/Core/GitStrArrayIn.cs new file mode 100644 index 000000000..6ec4256c6 --- /dev/null +++ b/LibGit2Sharp/Core/GitStrArrayIn.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace LibGit2Sharp.Core +{ + [StructLayout(LayoutKind.Sequential)] + internal class GitStrArrayIn : IDisposable + { + public IntPtr strings; + public uint size; + + public static GitStrArrayIn BuildFrom(FilePath[] paths) + { + var nbOfPaths = paths.Length; + var pathPtrs = new IntPtr[nbOfPaths]; + + for (int i = 0; i < nbOfPaths; i++) + { + var s = paths[i].Posix; + pathPtrs[i] = FilePathMarshaler.FromManaged(s); + } + + int dim = IntPtr.Size * nbOfPaths; + + IntPtr arrayPtr = Marshal.AllocHGlobal(dim); + Marshal.Copy(pathPtrs, 0, arrayPtr, nbOfPaths); + + return new GitStrArrayIn { strings = arrayPtr, size = (uint)nbOfPaths }; + } + + public void Dispose() + { + if (size == 0) + { + return; + } + + var nbOfPaths = (int)size; + + var pathPtrs = new IntPtr[nbOfPaths]; + Marshal.Copy(strings, pathPtrs, 0, nbOfPaths); + + for (int i = 0; i < nbOfPaths; i++) + { + Marshal.FreeHGlobal(pathPtrs[i]); + } + + Marshal.FreeHGlobal(strings); + size = 0; + } + } +} diff --git a/LibGit2Sharp/Core/GitTransferProgress.cs b/LibGit2Sharp/Core/GitTransferProgress.cs index b57dadf55..29456c154 100644 --- a/LibGit2Sharp/Core/GitTransferProgress.cs +++ b/LibGit2Sharp/Core/GitTransferProgress.cs @@ -4,7 +4,7 @@ namespace LibGit2Sharp.Core { /// - /// Managed structure corresponding to git_transfer_progress native structure. + /// Managed structure corresponding to git_transfer_progress native structure. /// [StructLayout(LayoutKind.Sequential)] internal struct GitTransferProgress diff --git a/LibGit2Sharp/Core/Handles/SafeHandleBase.cs b/LibGit2Sharp/Core/Handles/SafeHandleBase.cs index c6ab59ad4..ae386bd39 100644 --- a/LibGit2Sharp/Core/Handles/SafeHandleBase.cs +++ b/LibGit2Sharp/Core/Handles/SafeHandleBase.cs @@ -3,7 +3,7 @@ using System.Globalization; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; -using Interlocked = System.Threading.Interlocked; +using System.Threading; namespace LibGit2Sharp.Core.Handles { diff --git a/LibGit2Sharp/Core/HistoryRewriter.cs b/LibGit2Sharp/Core/HistoryRewriter.cs new file mode 100644 index 000000000..1dd29504b --- /dev/null +++ b/LibGit2Sharp/Core/HistoryRewriter.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace LibGit2Sharp.Core +{ + internal class HistoryRewriter + { + private readonly Repository repo; + + private readonly HashSet targetedCommits; + private readonly Dictionary shaMap = new Dictionary(); + + private readonly Func headerRewriter; + private readonly Func treeRewriter; + private readonly string backupRefsNamespace; + private readonly Func, IEnumerable> parentsRewriter; + private readonly Func tagNameRewriter; + + public HistoryRewriter( + Repository repo, + IEnumerable commitsToRewrite, + Func headerRewriter, + Func treeRewriter, + Func, IEnumerable> parentsRewriter, + Func tagNameRewriter, + string backupRefsNamespace) + { + this.repo = repo; + targetedCommits = new HashSet(commitsToRewrite); + + this.headerRewriter = headerRewriter ?? CommitRewriteInfo.From; + this.treeRewriter = treeRewriter; + this.tagNameRewriter = tagNameRewriter; + this.parentsRewriter = parentsRewriter ?? (ps => ps); + + this.backupRefsNamespace = backupRefsNamespace; + } + + public void Execute() + { + // Find out which refs lead to at least one the commits + var refsToRewrite = repo.Refs.ReachableFrom(targetedCommits).ToList(); + + var filter = new CommitFilter + { + Since = refsToRewrite, + SortBy = CommitSortStrategies.Reverse | CommitSortStrategies.Topological + }; + + var commits = repo.Commits.QueryBy(filter); + foreach (var commit in commits) + { + RewriteCommit(commit); + } + + var rollbackActions = new Queue(); + + try + { + // Ordering matters. In the case of `A -> B -> commit`, we need to make sure B is rewritten + // before A. + foreach (var reference in refsToRewrite.OrderBy(ReferenceDepth)) + { + // TODO: Check how rewriting of notes actually behaves + + var dref = reference as DirectReference; + if (dref == null) + { + // TODO: Handle a cornercase where a symbolic reference + // points to a Tag which name has been rewritten + continue; + } + + var newTarget = RewriteTarget(dref.Target); + + RewriteReference(dref, newTarget, backupRefsNamespace, rollbackActions); + } + } + catch (Exception) + { + foreach (var action in rollbackActions) + { + action(); + } + + throw; + } + } + + private void RewriteReference(DirectReference oldRef, ObjectId newTarget, string backupNamePrefix, Queue rollbackActions) + { + string newRefName = oldRef.CanonicalName; + if (oldRef.IsTag() && tagNameRewriter != null) + { + newRefName = Reference.TagPrefix + + tagNameRewriter(oldRef.CanonicalName.Substring(Reference.TagPrefix.Length), false, oldRef.Target); + } + + if (oldRef.Target.Id == newTarget && oldRef.CanonicalName == newRefName) + { + // The reference isn't rewritten + return; + } + + string backupName = backupNamePrefix + oldRef.CanonicalName.Substring("refs/".Length); + + if (repo.Refs.Resolve(backupName) != null) + { + throw new InvalidOperationException( + String.Format("Can't back up reference '{0}' - '{1}' already exists", oldRef.CanonicalName, backupName)); + } + + repo.Refs.Add(backupName, oldRef.TargetIdentifier, false, "filter-branch: backup"); + rollbackActions.Enqueue(() => repo.Refs.Remove(backupName)); + + Reference newRef = repo.Refs.UpdateTarget(oldRef, newTarget, "filter-branch: rewrite"); + rollbackActions.Enqueue(() => repo.Refs.UpdateTarget(oldRef, oldRef.Target.Id, "filter-branch: abort")); + + if (newRef.CanonicalName == newRefName) + { + return; + } + + repo.Refs.Move(newRef, newRefName); + rollbackActions.Enqueue(() => repo.Refs.Move(newRef, oldRef.CanonicalName)); + } + + private void RewriteCommit(Commit commit) + { + var newHeader = CommitRewriteInfo.From(commit); + var newTree = commit.Tree; + + // Find the new parents + var newParents = commit.Parents + .Select(oldParent => + shaMap.ContainsKey(oldParent.Id) + ? shaMap[oldParent.Id] + : oldParent.Id) + .Select(id => repo.Lookup(id)); + + if (targetedCommits.Contains(commit)) + { + // Get the new commit header + newHeader = headerRewriter(commit); + + if (treeRewriter != null) + { + // Get the new commit tree + var newTreeDefinition = treeRewriter(commit); + newTree = repo.ObjectDatabase.CreateTree(newTreeDefinition); + } + + // Retrieve new parents + newParents = parentsRewriter(newParents); + } + + // Create the new commit + var newCommit = repo.ObjectDatabase.CreateCommit(newHeader.Message, newHeader.Author, + newHeader.Committer, newTree, + newParents); + + // Record the rewrite + shaMap[commit.Id] = newCommit.Id; + } + + private ObjectId RewriteTarget(GitObject oldTarget) + { + // Has this target already been rewritten? + if (shaMap.ContainsKey(oldTarget.Id)) + { + return shaMap[oldTarget.Id]; + } + + Debug.Assert((oldTarget as Commit) == null); + + var annotation = oldTarget as TagAnnotation; + if (annotation == null) + { + //TODO: Probably a Tree or a Blob. This is not covered by any test + return oldTarget.Id; + } + + // Recursively rewrite annotations if necessary + ObjectId newTargetId = RewriteTarget(annotation.Target); + + var newTarget = repo.Lookup(newTargetId); + + string newName = annotation.Name; + + if (tagNameRewriter != null) + { + newName = tagNameRewriter(annotation.Name, true, annotation.Target); + } + + var newAnnotation = repo.ObjectDatabase.CreateTagAnnotation(newName, newTarget, annotation.Tagger, + annotation.Message); + shaMap[annotation.Id] = newAnnotation.Id; + return newAnnotation.Id; + } + + private int ReferenceDepth(Reference reference) + { + var dref = reference as DirectReference; + return dref == null + ? 1 + ReferenceDepth(((SymbolicReference)reference).Target) + : 1; + } + } +} diff --git a/LibGit2Sharp/Core/NativeDllName.cs b/LibGit2Sharp/Core/NativeDllName.cs index ec665f71e..1dfd3e672 100644 --- a/LibGit2Sharp/Core/NativeDllName.cs +++ b/LibGit2Sharp/Core/NativeDllName.cs @@ -2,6 +2,6 @@ namespace LibGit2Sharp.Core { internal static class NativeDllName { - public const string Name = "git2-9d9fff3"; + public const string Name = "git2-7940036"; } } diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 7074d95e0..5a4a08735 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -208,7 +208,7 @@ internal static extern int git_clone( internal static extern IntPtr git_commit_committer(GitObjectSafeHandle commit); [DllImport(libgit2)] - internal static extern int git_commit_create( + internal static extern int git_commit_create_from_oids( out GitOid id, RepositorySafeHandle repo, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(Utf8Marshaler))] string updateRef, @@ -216,7 +216,7 @@ internal static extern int git_commit_create( SignatureSafeHandle committer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(Utf8Marshaler))] string encoding, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(Utf8Marshaler))] string message, - GitObjectSafeHandle tree, + ref GitOid tree, int parentCount, [MarshalAs(UnmanagedType.LPArray)] [In] IntPtr[] parents); @@ -408,7 +408,9 @@ internal static extern int git_diff_print_patch( [DllImport(libgit2)] internal static extern int git_diff_blobs( GitObjectSafeHandle oldBlob, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath old_as_path, GitObjectSafeHandle newBlob, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath new_as_path, GitDiffOptions options, git_diff_file_cb fileCallback, git_diff_hunk_cb hunkCallback, @@ -756,6 +758,9 @@ internal static extern int git_refspec_rtransform( GitRefSpecHandle refSpec, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(Utf8Marshaler))] string name); + [DllImport(libgit2)] + internal static extern int git_remote_autotag(RemoteSafeHandle remote); + [DllImport(libgit2)] internal static extern int git_remote_connect(RemoteSafeHandle remote, GitDirection direction); @@ -873,10 +878,10 @@ internal static extern int git_repository_fetchhead_foreach( internal static extern int git_repository_index(out IndexSafeHandle index, RepositorySafeHandle repo); [DllImport(libgit2)] - internal static extern int git_repository_init( + internal static extern int git_repository_init_ext( out RepositorySafeHandle repository, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath path, - [MarshalAs(UnmanagedType.Bool)] bool isBare); + GitRepositoryInitOptions options); [DllImport(libgit2)] internal static extern int git_repository_is_bare(RepositorySafeHandle handle); @@ -956,8 +961,9 @@ internal static extern int git_reset( ResetOptions reset_type); [DllImport(libgit2)] - internal static extern int git_revparse_single( + internal static extern int git_revparse_ext( out GitObjectSafeHandle obj, + out ReferenceSafeHandle reference, RepositorySafeHandle repo, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(Utf8Marshaler))] string spec); @@ -980,7 +986,7 @@ internal static extern int git_revparse_single( internal static extern void git_revwalk_reset(RevWalkerSafeHandle walker); [DllImport(libgit2)] - internal static extern void git_revwalk_sorting(RevWalkerSafeHandle walk, GitSortOptions sort); + internal static extern void git_revwalk_sorting(RevWalkerSafeHandle walk, CommitSortStrategies sort); [DllImport(libgit2)] internal static extern void git_signature_free(IntPtr signature); @@ -999,7 +1005,7 @@ internal static extern int git_stash_save( RepositorySafeHandle repo, SignatureSafeHandle stasher, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(Utf8Marshaler))] string message, - StashOptions flags); + StashModifiers flags); internal delegate int git_stash_cb( UIntPtr index, diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index d9ebbacc6..691136931 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -251,20 +251,22 @@ public static ObjectId git_commit_create( Signature committer, string prettifiedMessage, Tree tree, - IEnumerable parentIds) + GitOid[] parentIds) { using (ThreadAffinity()) - using (var treePtr = new ObjectSafeWrapper(tree.Id, repo)) - using (var parentObjectPtrs = new DisposableEnumerable(parentIds.Select(id => new ObjectSafeWrapper(id, repo)).ToList())) using (SignatureSafeHandle authorHandle = author.BuildHandle()) using (SignatureSafeHandle committerHandle = committer.BuildHandle()) + using (var parentPtrs = new ArrayMarshaler(parentIds)) { GitOid commitOid; - string encoding = null; //TODO: Handle the encoding of the commit to be created - IntPtr[] parentsPtrs = parentObjectPtrs.Select(o => o.ObjectPtr.DangerousGetHandle()).ToArray(); - int res = NativeMethods.git_commit_create(out commitOid, repo, referenceName, authorHandle, - committerHandle, encoding, prettifiedMessage, treePtr.ObjectPtr, parentObjectPtrs.Count, parentsPtrs); + var treeOid = tree.Id.Oid; + + int res = NativeMethods.git_commit_create_from_oids( + out commitOid, repo, referenceName, authorHandle, + committerHandle, null, prettifiedMessage, + ref treeOid, parentPtrs.Count, parentPtrs.ToArray()); + Ensure.ZeroResult(res); return commitOid; @@ -506,7 +508,10 @@ public static void git_diff_blobs( using (var osw1 = new ObjectSafeWrapper(oldBlob, repo, true)) using (var osw2 = new ObjectSafeWrapper(newBlob, repo, true)) { - int res = NativeMethods.git_diff_blobs(osw1.ObjectPtr, osw2.ObjectPtr, options, fileCallback, hunkCallback, lineCallback, IntPtr.Zero); + int res = NativeMethods.git_diff_blobs( + osw1.ObjectPtr, null, osw2.ObjectPtr, null, + options, fileCallback, hunkCallback, lineCallback, IntPtr.Zero); + Ensure.ZeroResult(res); } } @@ -1368,6 +1373,11 @@ public static string git_refspec_rtransform(GitRefSpecHandle refSpecPtr, string #region git_remote_ + public static TagFetchMode git_remote_autotag(RemoteSafeHandle remote) + { + return (TagFetchMode) NativeMethods.git_remote_autotag(remote); + } + public static RemoteSafeHandle git_remote_create(RepositorySafeHandle repo, string name, string url) { using (ThreadAffinity()) @@ -1569,12 +1579,16 @@ public static IndexSafeHandle git_repository_index(RepositorySafeHandle repo) } } - public static RepositorySafeHandle git_repository_init(FilePath path, bool isBare) + public static RepositorySafeHandle git_repository_init_ext( + FilePath workdirPath, + FilePath gitdirPath, + bool isBare) { using (ThreadAffinity()) + using (var opts = GitRepositoryInitOptions.BuildFrom(workdirPath, isBare)) { RepositorySafeHandle repo; - int res = NativeMethods.git_repository_init(out repo, path, isBare); + int res = NativeMethods.git_repository_init_ext(out repo, gitdirPath, opts); Ensure.ZeroResult(res); return repo; @@ -1751,12 +1765,13 @@ public static void git_reset( #region git_revparse_ - public static GitObjectSafeHandle git_revparse_single(RepositorySafeHandle repo, string objectish) + public static Tuple git_revparse_ext(RepositorySafeHandle repo, string objectish) { using (ThreadAffinity()) { GitObjectSafeHandle obj; - int res = NativeMethods.git_revparse_single(out obj, repo, objectish); + ReferenceSafeHandle reference; + int res = NativeMethods.git_revparse_ext(out obj, out reference, repo, objectish); switch (res) { @@ -1771,8 +1786,22 @@ public static GitObjectSafeHandle git_revparse_single(RepositorySafeHandle repo, break; } - return obj; + return new Tuple(obj, reference); + } + } + + public static GitObjectSafeHandle git_revparse_single(RepositorySafeHandle repo, string objectish) + { + var handles = git_revparse_ext(repo, objectish); + + if (handles == null) + { + return null; } + + handles.Item2.Dispose(); + + return handles.Item1; } #endregion @@ -1839,7 +1868,7 @@ public static void git_revwalk_reset(RevWalkerSafeHandle walker) NativeMethods.git_revwalk_reset(walker); } - public static void git_revwalk_sorting(RevWalkerSafeHandle walker, GitSortOptions options) + public static void git_revwalk_sorting(RevWalkerSafeHandle walker, CommitSortStrategies options) { NativeMethods.git_revwalk_sorting(walker, options); } @@ -1874,7 +1903,7 @@ public static ObjectId git_stash_save( RepositorySafeHandle repo, Signature stasher, string prettifiedMessage, - StashOptions options) + StashModifiers options) { using (ThreadAffinity()) using (SignatureSafeHandle stasherHandle = stasher.BuildHandle()) @@ -1952,8 +1981,8 @@ public static ICollection git_status_foreach(RepositorySafeHan #region git_submodule_ /// - /// Returns a handle to the corresponding submodule, - /// or an invalid handle if a submodule is not found. + /// Returns a handle to the corresponding submodule, + /// or an invalid handle if a submodule is not found. /// public static SubmoduleSafeHandle git_submodule_lookup(RepositorySafeHandle repo, string name) { diff --git a/LibGit2Sharp/Core/RepositoryOpenFlags.cs b/LibGit2Sharp/Core/RepositoryOpenFlags.cs index 28d9ac17f..e0e6a31bb 100644 --- a/LibGit2Sharp/Core/RepositoryOpenFlags.cs +++ b/LibGit2Sharp/Core/RepositoryOpenFlags.cs @@ -9,18 +9,18 @@ namespace LibGit2Sharp.Core internal enum RepositoryOpenFlags { /// - /// Only open the repository if it can be - /// * immediately found in the start_path. Do not walk up from the - /// * start_path looking at parent directories. + /// Only open the repository if it can be + /// * immediately found in the start_path. Do not walk up from the + /// * start_path looking at parent directories. /// NoSearch = (1 << 0), /* GIT_REPOSITORY_OPEN_NO_SEARCH */ /// - /// Unless this flag is set, open will not - /// * continue searching across filesystem boundaries (i.e. when `st_dev` - /// * changes from the `stat` system call). (E.g. Searching in a user's home - /// * directory "/home/user/source/" will not return "/.git/" as the found - /// * repo if "/" is a different filesystem than "/home".) + /// Unless this flag is set, open will not + /// * continue searching across filesystem boundaries (i.e. when `st_dev` + /// * changes from the `stat` system call). (E.g. Searching in a user's home + /// * directory "/home/user/source/" will not return "/.git/" as the found + /// * repo if "/" is a different filesystem than "/home".) /// CrossFS = (1 << 1), /* GIT_REPOSITORY_OPEN_CROSS_FS */ } diff --git a/LibGit2Sharp/Core/Utf8Marshaler.cs b/LibGit2Sharp/Core/Utf8Marshaler.cs index 79fd2a6c4..ad199db7b 100644 --- a/LibGit2Sharp/Core/Utf8Marshaler.cs +++ b/LibGit2Sharp/Core/Utf8Marshaler.cs @@ -5,14 +5,14 @@ namespace LibGit2Sharp.Core { /// - /// This marshaler is to be used for capturing a UTF-8 string owned by libgit2 and - /// converting it to a managed String instance. The marshaler will not attempt to - /// free the native pointer after conversion, because the memory is owned by libgit2. + /// This marshaler is to be used for capturing a UTF-8 string owned by libgit2 and + /// converting it to a managed String instance. The marshaler will not attempt to + /// free the native pointer after conversion, because the memory is owned by libgit2. /// - /// Use this marshaler for return values, for example: - /// [return: MarshalAs(UnmanagedType.CustomMarshaler, - /// MarshalCookie = UniqueId.UniqueIdentifier, - /// MarshalTypeRef = typeof(Utf8NoCleanupMarshaler))] + /// Use this marshaler for return values, for example: + /// [return: MarshalAs(UnmanagedType.CustomMarshaler, + /// MarshalCookie = UniqueId.UniqueIdentifier, + /// MarshalTypeRef = typeof(Utf8NoCleanupMarshaler))] /// internal class Utf8NoCleanupMarshaler : Utf8Marshaler { @@ -33,18 +33,18 @@ public override void CleanUpNativeData(IntPtr pNativeData) } /// - /// This marshaler is to be used for sending managed String instances to libgit2. - /// The marshaler will allocate a buffer in native memory to hold the UTF-8 string - /// and perform the encoding conversion using that buffer as the target. The pointer - /// received by libgit2 will be to this buffer. After the function call completes, the - /// native buffer is freed. + /// This marshaler is to be used for sending managed String instances to libgit2. + /// The marshaler will allocate a buffer in native memory to hold the UTF-8 string + /// and perform the encoding conversion using that buffer as the target. The pointer + /// received by libgit2 will be to this buffer. After the function call completes, the + /// native buffer is freed. /// - /// Use this marshaler for function parameters, for example: - /// [DllImport(libgit2)] - /// internal static extern int git_tag_delete(RepositorySafeHandle repo, - /// [MarshalAs(UnmanagedType.CustomMarshaler, - /// MarshalCookie = UniqueId.UniqueIdentifier, - /// MarshalTypeRef = typeof(Utf8Marshaler))] String tagName); + /// Use this marshaler for function parameters, for example: + /// [DllImport(libgit2)] + /// internal static extern int git_tag_delete(RepositorySafeHandle repo, + /// [MarshalAs(UnmanagedType.CustomMarshaler, + /// MarshalCookie = UniqueId.UniqueIdentifier, + /// MarshalTypeRef = typeof(Utf8Marshaler))] String tagName); /// internal class Utf8Marshaler : ICustomMarshaler { diff --git a/LibGit2Sharp/CurrentOperation.cs b/LibGit2Sharp/CurrentOperation.cs index be0ffebc8..58f7064ae 100644 --- a/LibGit2Sharp/CurrentOperation.cs +++ b/LibGit2Sharp/CurrentOperation.cs @@ -1,58 +1,58 @@ namespace LibGit2Sharp { /// - /// Determines the pending operation of a git repository - ie, whether - /// an operation (merge, cherry-pick, etc) is in progress. + /// Determines the pending operation of a git repository - ie, whether + /// an operation (merge, cherry-pick, etc) is in progress. /// public enum CurrentOperation { /// - /// No operation is in progress. + /// No operation is in progress. /// None = 0, /// - /// A merge is in progress. + /// A merge is in progress. /// Merge = 1, /// - /// A revert is in progress. + /// A revert is in progress. /// Revert = 2, /// - /// A cherry-pick is in progress. + /// A cherry-pick is in progress. /// CherryPick = 3, /// - /// A bisect is in progress. + /// A bisect is in progress. /// Bisect = 4, /// - /// A rebase is in progress. + /// A rebase is in progress. /// Rebase = 5, /// - /// A rebase --interactive is in progress. + /// A rebase --interactive is in progress. /// RebaseInteractive = 6, /// - /// A rebase --merge is in progress. + /// A rebase --merge is in progress. /// RebaseMerge = 7, /// - /// A mailbox application (am) is in progress. + /// A mailbox application (am) is in progress. /// ApplyMailbox = 8, /// - /// A mailbox application (am) or rebase is in progress. + /// A mailbox application (am) or rebase is in progress. /// ApplyMailboxOrRebase = 9, } diff --git a/LibGit2Sharp/DetachedHead.cs b/LibGit2Sharp/DetachedHead.cs index 0d7b31406..094d9d263 100644 --- a/LibGit2Sharp/DetachedHead.cs +++ b/LibGit2Sharp/DetachedHead.cs @@ -13,7 +13,7 @@ protected override string Shorten() } /// - /// Gets the remote branch which is connected to this local one, or null if there is none. + /// Gets the remote branch which is connected to this local one, or null if there is none. /// public override Branch TrackedBranch { diff --git a/LibGit2Sharp/Diff.cs b/LibGit2Sharp/Diff.cs index c5e1f12ea..a6e855060 100644 --- a/LibGit2Sharp/Diff.cs +++ b/LibGit2Sharp/Diff.cs @@ -10,16 +10,16 @@ namespace LibGit2Sharp { /// - /// 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. - /// - /// Copied and renamed files currently cannot be detected, as the feature is not supported by libgit2 yet. - /// These files will be shown as a pair of Deleted/Added files. + /// 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. + /// + /// Copied and renamed files currently cannot be detected, as the feature is not supported by libgit2 yet. + /// These files will be shown as a pair of Deleted/Added files. /// public class Diff { private readonly Repository repo; - private static GitDiffOptions BuildOptions(DiffOptions diffOptions, FilePath[] filePaths = null, MatchedPathsAggregator matchedPathsAggregator = null, CompareOptions compareOptions = null) + private static GitDiffOptions BuildOptions(DiffModifiers diffOptions, FilePath[] filePaths = null, MatchedPathsAggregator matchedPathsAggregator = null, CompareOptions compareOptions = null) { var options = new GitDiffOptions(); @@ -29,24 +29,24 @@ private static GitDiffOptions BuildOptions(DiffOptions diffOptions, FilePath[] f options.ContextLines = (ushort)compareOptions.ContextLines; options.InterhunkLines = (ushort)compareOptions.InterhunkLines; - if (diffOptions.HasFlag(DiffOptions.IncludeUntracked)) + if (diffOptions.HasFlag(DiffModifiers.IncludeUntracked)) { options.Flags |= GitDiffOptionFlags.GIT_DIFF_INCLUDE_UNTRACKED | GitDiffOptionFlags.GIT_DIFF_RECURSE_UNTRACKED_DIRS | GitDiffOptionFlags.GIT_DIFF_INCLUDE_UNTRACKED_CONTENT; } - if (diffOptions.HasFlag(DiffOptions.IncludeIgnored)) + if (diffOptions.HasFlag(DiffModifiers.IncludeIgnored)) { options.Flags |= GitDiffOptionFlags.GIT_DIFF_INCLUDE_IGNORED; } - if (diffOptions.HasFlag(DiffOptions.IncludeUnmodified)) + if (diffOptions.HasFlag(DiffModifiers.IncludeUnmodified)) { options.Flags |= GitDiffOptionFlags.GIT_DIFF_INCLUDE_UNMODIFIED; } - if (diffOptions.HasFlag(DiffOptions.DisablePathspecMatch)) + if (diffOptions.HasFlag(DiffModifiers.DisablePathspecMatch)) { options.Flags |= GitDiffOptionFlags.GIT_DIFF_DISABLE_PATHSPEC_MATCH; } @@ -65,35 +65,8 @@ private static GitDiffOptions BuildOptions(DiffOptions diffOptions, FilePath[] f return options; } - private static FilePath[] ToFilePaths(Repository repo, IEnumerable paths) - { - if (paths == null) - { - return null; - } - - var filePaths = new List(); - - foreach (string path in paths) - { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentException("At least one provided path is either null or empty.", "paths"); - } - - filePaths.Add(repo.BuildRelativePathFrom(path)); - } - - if (filePaths.Count == 0) - { - throw new ArgumentException("No path has been provided.", "paths"); - } - - return filePaths.ToArray(); - } - /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Diff() { } @@ -104,32 +77,32 @@ internal Diff(Repository repo) } /// - /// Show changes between two s. + /// Show changes between two s. /// - /// The you want to compare from. - /// The you want to compare to. - /// The list of paths (either files or directories) that should be compared. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The you want to compare from. + /// The you want to compare to. + /// The list of paths (either files or directories) that should be compared. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// - /// Additional options to define comparison behavior. - /// A containing the changes between the and the . + /// Additional options to define comparison behavior. + /// A containing the changes between the and the . public virtual TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var comparer = TreeToTree(repo); ObjectId oldTreeId = oldTree != null ? oldTree.Id : null; ObjectId newTreeId = newTree != null ? newTree.Id : null; - var diffOptions = DiffOptions.None; + var diffOptions = DiffModifiers.None; if (explicitPathsOptions != null) { - diffOptions |= DiffOptions.DisablePathspecMatch; + diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { - diffOptions |= DiffOptions.IncludeUnmodified; + diffOptions |= DiffModifiers.IncludeUnmodified; } } @@ -137,15 +110,15 @@ public virtual TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable - /// Show changes between two s. + /// Show changes between two s. /// - /// The you want to compare from. - /// The you want to compare to. - /// Additional options to define comparison behavior. - /// A containing the changes between the and the . + /// The you want to compare from. + /// The you want to compare to. + /// Additional options to define comparison behavior. + /// A containing the changes between the and the . public virtual ContentChanges Compare(Blob oldBlob, Blob newBlob, CompareOptions compareOptions = null) { - using (GitDiffOptions options = BuildOptions(DiffOptions.None, compareOptions: compareOptions)) + using (GitDiffOptions options = BuildOptions(DiffModifiers.None, compareOptions: compareOptions)) { return new ContentChanges(repo, oldBlob, newBlob, options); } @@ -164,33 +137,33 @@ private static IDictionary - /// Show changes between a and the Index, the Working Directory, or both. + /// Show changes between a and the Index, the Working Directory, or both. /// - /// The to compare from. - /// The targets to compare to. - /// The list of paths (either files or directories) that should be compared. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The to compare from. + /// The targets to compare to. + /// The list of paths (either files or directories) that should be compared. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// - /// Additional options to define comparison behavior. - /// A containing the changes between the and the selected target. + /// Additional options to define comparison behavior. + /// A containing the changes between the and the selected target. public virtual TreeChanges Compare(Tree oldTree, DiffTargets diffTargets, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var comparer = handleRetrieverDispatcher[diffTargets](repo); ObjectId oldTreeId = oldTree != null ? oldTree.Id : null; - DiffOptions diffOptions = diffTargets.HasFlag(DiffTargets.WorkingDirectory) ? - DiffOptions.IncludeUntracked : DiffOptions.None; + DiffModifiers diffOptions = diffTargets.HasFlag(DiffTargets.WorkingDirectory) ? + DiffModifiers.IncludeUntracked : DiffModifiers.None; if (explicitPathsOptions != null) { - diffOptions |= DiffOptions.DisablePathspecMatch; + diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { - diffOptions |= DiffOptions.IncludeUnmodified; + diffOptions |= DiffModifiers.IncludeUnmodified; } } @@ -198,34 +171,34 @@ public virtual TreeChanges Compare(Tree oldTree, DiffTargets diffTargets, IEnume } /// - /// Show changes between the working directory and the index. + /// Show changes between the working directory and the index. /// - /// The list of paths (either files or directories) that should be compared. - /// If true, include untracked files from the working dir as additions. Otherwise ignore them. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The list of paths (either files or directories) that should be compared. + /// If true, include untracked files from the working dir as additions. Otherwise ignore them. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// - /// Additional options to define comparison behavior. - /// A containing the changes between the working directory and the index. + /// Additional options to define comparison behavior. + /// A containing the changes between the working directory and the index. public virtual TreeChanges Compare(IEnumerable paths = null, bool includeUntracked = false, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { - return Compare(includeUntracked ? DiffOptions.IncludeUntracked : DiffOptions.None, paths, explicitPathsOptions, compareOptions); + return Compare(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions, compareOptions); } - internal virtual TreeChanges Compare(DiffOptions diffOptions, IEnumerable paths = null, + internal virtual TreeChanges Compare(DiffModifiers diffOptions, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var comparer = WorkdirToIndex(repo); if (explicitPathsOptions != null) { - diffOptions |= DiffOptions.DisablePathspecMatch; + diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { - diffOptions |= DiffOptions.IncludeUnmodified; + diffOptions |= DiffModifiers.IncludeUnmodified; } } @@ -284,10 +257,10 @@ private static TreeComparisonHandleRetriever IndexToTree(Repository repo) private TreeChanges BuildTreeChangesFromComparer( ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, - DiffOptions diffOptions, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) + DiffModifiers diffOptions, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var matchedPaths = new MatchedPathsAggregator(); - var filePaths = ToFilePaths(repo, paths); + var filePaths = repo.ToFilePaths(paths); using (GitDiffOptions options = BuildOptions(diffOptions, filePaths, matchedPaths, compareOptions)) using (DiffListSafeHandle diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options)) diff --git a/LibGit2Sharp/DiffModifiers.cs b/LibGit2Sharp/DiffModifiers.cs new file mode 100644 index 000000000..af9ccb75c --- /dev/null +++ b/LibGit2Sharp/DiffModifiers.cs @@ -0,0 +1,40 @@ +using System; + +namespace LibGit2Sharp +{ + /// + /// Additional behaviors the diffing should take into account + /// when performing the comparison. + /// + [Flags] + internal enum DiffModifiers + { + /// + /// No special behavior. + /// + None = 0, + + /// + /// Include untracked files among the files to be processed, when + /// diffing against the working directory. + /// + IncludeUntracked = (1 << 1), + + /// + /// Include unmodified files among the files to be processed, when + /// diffing against the working directory. + /// + IncludeUnmodified = (1 << 2), + + /// + /// Treats the passed pathspecs as explicit paths (no pathspec match). + /// + DisablePathspecMatch = (1 << 3), + + /// + /// Include ignored files among the files to be processed, when + /// diffing against the working directory. + /// + IncludeIgnored = (1 << 4), + } +} diff --git a/LibGit2Sharp/DiffOptions.cs b/LibGit2Sharp/DiffOptions.cs deleted file mode 100644 index 761a52a82..000000000 --- a/LibGit2Sharp/DiffOptions.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; - -namespace LibGit2Sharp -{ - /// - /// Additional behaviors the diffing should take into account - /// when performing the comparison. - /// - [Flags] - internal enum DiffOptions - { - /// - /// No special behavior. - /// - None = 0, - - /// - /// Include untracked files among the files to be processed, when - /// diffing against the working directory. - /// - IncludeUntracked = (1 << 1), - - /// - /// Include unmodified files among the files to be processed, when - /// diffing against the working directory. - /// - IncludeUnmodified = (1 << 2), - - /// - /// Treats the passed pathspecs as explicit paths (no pathspec match). - /// - DisablePathspecMatch = (1 << 3), - - /// - /// Include ignored files among the files to be processed, when - /// diffing against the working directory. - /// - IncludeIgnored = (1 << 4), - } -} diff --git a/LibGit2Sharp/DiffTargets.cs b/LibGit2Sharp/DiffTargets.cs index 8488a9a03..58e3f2f4d 100644 --- a/LibGit2Sharp/DiffTargets.cs +++ b/LibGit2Sharp/DiffTargets.cs @@ -3,18 +3,18 @@ namespace LibGit2Sharp { /// - /// The targets of a Tree based diff comparison. + /// The targets of a Tree based diff comparison. /// [Flags] public enum DiffTargets { /// - /// The repository index. + /// The repository index. /// Index = 1, /// - /// The working directory. + /// The working directory. /// WorkingDirectory = 2, } diff --git a/LibGit2Sharp/DirectReference.cs b/LibGit2Sharp/DirectReference.cs index a79825c15..ca02b7bc4 100644 --- a/LibGit2Sharp/DirectReference.cs +++ b/LibGit2Sharp/DirectReference.cs @@ -3,14 +3,14 @@ namespace LibGit2Sharp { /// - /// A DirectReference points directly to a + /// A DirectReference points directly to a /// public class DirectReference : Reference { private readonly Lazy targetBuilder; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected DirectReference() { } @@ -22,7 +22,7 @@ internal DirectReference(string canonicalName, Repository repo, ObjectId targetI } /// - /// Gets the target of this + /// Gets the target of this /// public virtual GitObject Target { @@ -30,7 +30,7 @@ public virtual GitObject Target } /// - /// As a is already peeled, invoking this will return the same . + /// As a is already peeled, invoking this will return the same . /// /// This instance. public override DirectReference ResolveToDirectReference() diff --git a/LibGit2Sharp/ExplicitPathsOptions.cs b/LibGit2Sharp/ExplicitPathsOptions.cs index 02e81c72d..f5c2e2e27 100644 --- a/LibGit2Sharp/ExplicitPathsOptions.cs +++ b/LibGit2Sharp/ExplicitPathsOptions.cs @@ -3,17 +3,17 @@ namespace LibGit2Sharp { /// - /// Allows callers to specify how unmatched paths should be handled - /// by operations such as Reset(), Compare(), Unstage(), ... - /// - /// By passing these options, the passed paths will be treated as - /// explicit paths, and NOT pathspecs containing globs. - /// + /// Allows callers to specify how unmatched paths should be handled + /// by operations such as Reset(), Compare(), Unstage(), ... + /// + /// By passing these options, the passed paths will be treated as + /// explicit paths, and NOT pathspecs containing globs. + /// /// public class ExplicitPathsOptions { /// - /// Associated paths will be treated as explicit paths. + /// Associated paths will be treated as explicit paths. /// public ExplicitPathsOptions() { @@ -21,16 +21,16 @@ public ExplicitPathsOptions() } /// - /// When set to true, the called operation will throw a when an unmatched - /// path is encountered. - /// - /// Set to true by default. - /// + /// When set to true, the called operation will throw a when an unmatched + /// path is encountered. + /// + /// Set to true by default. + /// /// public bool ShouldFailOnUnmatchedPath { get; set; } /// - /// Sets a callback that will be called once for each unmatched path. + /// Sets a callback that will be called once for each unmatched path. /// public UnmatchedPathHandler OnUnmatchedPath { get; set; } } diff --git a/LibGit2Sharp/FetchHead.cs b/LibGit2Sharp/FetchHead.cs index df1b4006c..c57eda240 100644 --- a/LibGit2Sharp/FetchHead.cs +++ b/LibGit2Sharp/FetchHead.cs @@ -4,13 +4,13 @@ namespace LibGit2Sharp { /// - /// Represents a local reference data from a remote repository which - /// has been retreived through a Fetch process. + /// Represents a local reference data from a remote repository which + /// has been retreived through a Fetch process. /// public class FetchHead : ReferenceWrapper { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected FetchHead() { } @@ -27,7 +27,7 @@ internal FetchHead(Repository repo, string remoteCanonicalName, } /// - /// Returns "FETCH_HEAD[i]", where i is the index of this fetch head. + /// Returns "FETCH_HEAD[i]", where i is the index of this fetch head. /// protected override string Shorten() { @@ -35,13 +35,13 @@ protected override string Shorten() } /// - /// Gets the canonical name of the reference this - /// points to in the remote repository it's been fetched from. + /// Gets the canonical name of the reference this + /// points to in the remote repository it's been fetched from. /// public virtual string RemoteCanonicalName { get; private set; } /// - /// Gets the that this fetch head points to. + /// Gets the that this fetch head points to. /// public virtual GitObject Target { @@ -49,13 +49,13 @@ public virtual GitObject Target } /// - /// The URL of the remote repository this - /// has been built from. + /// The URL of the remote repository this + /// has been built from. /// public virtual String Url { get; private set; } /// - /// Determines if this fetch head entry has been explicitly fetched. + /// Determines if this fetch head entry has been explicitly fetched. /// public virtual bool ForMerge { get; private set; } } diff --git a/LibGit2Sharp/FileStatus.cs b/LibGit2Sharp/FileStatus.cs index c0d2df000..bf6975d0d 100644 --- a/LibGit2Sharp/FileStatus.cs +++ b/LibGit2Sharp/FileStatus.cs @@ -3,68 +3,68 @@ namespace LibGit2Sharp { /// - /// Calculated status of a filepath in the working directory considering the current and the . + /// Calculated status of a filepath in the working directory considering the current and the . /// [Flags] public enum FileStatus { /// - /// The file doesn't exist. + /// The file doesn't exist. /// Nonexistent = (1 << 31), /// - /// The file hasn't been modified. + /// The file hasn't been modified. /// Unaltered = 0, /* GIT_STATUS_CURRENT */ /// - /// New file has been added to the Index. It's unknown from the Head. + /// New file has been added to the Index. It's unknown from the Head. /// Added = (1 << 0), /* GIT_STATUS_INDEX_NEW */ /// - /// New version of a file has been added to the Index. A previous version exists in the Head. + /// New version of a file has been added to the Index. A previous version exists in the Head. /// Staged = (1 << 1), /* GIT_STATUS_INDEX_MODIFIED */ /// - /// The deletion of a file has been promoted from the working directory to the Index. A previous version exists in the Head. + /// The deletion of a file has been promoted from the working directory to the Index. A previous version exists in the Head. /// Removed = (1 << 2), /* GIT_STATUS_INDEX_DELETED */ /// - /// The renaming of a file has been promoted from the working directory to the Index. A previous version exists in the Head. + /// The renaming of a file has been promoted from the working directory to the Index. A previous version exists in the Head. /// Renamed = (1 << 3), /* GIT_STATUS_INDEX_RENAMED */ /// - /// A change in type for a file has been promoted from the working directory to the Index. A previous version exists in the Head. + /// A change in type for a file has been promoted from the working directory to the Index. A previous version exists in the Head. /// StagedTypeChange = (1 << 4), /* GIT_STATUS_INDEX_TYPECHANGE */ /// - /// New file in the working directory, unknown from the Index and the Head. + /// New file in the working directory, unknown from the Index and the Head. /// Untracked = (1 << 7), /* GIT_STATUS_WT_NEW */ /// - /// The file has been updated in the working directory. A previous version exists in the Index. + /// The file has been updated in the working directory. A previous version exists in the Index. /// Modified = (1 << 8), /* GIT_STATUS_WT_MODIFIED */ /// - /// The file has been deleted from the working directory. A previous version exists in the Index. + /// The file has been deleted from the working directory. A previous version exists in the Index. /// Missing = (1 << 9), /* GIT_STATUS_WT_DELETED */ /// - /// The file type has been changed in the working directory. A previous version exists in the Index. + /// The file type has been changed in the working directory. A previous version exists in the Index. /// TypeChanged = (1 << 10), /* GIT_STATUS_WT_TYPECHANGE */ /// - /// The file is but its name and/or path matches an exclude pattern in a gitignore file. + /// The file is but its name and/or path matches an exclude pattern in a gitignore file. /// Ignored = (1 << 14), /* GIT_STATUS_IGNORED */ } diff --git a/LibGit2Sharp/Filter.cs b/LibGit2Sharp/Filter.cs index a2a441c49..62028b584 100644 --- a/LibGit2Sharp/Filter.cs +++ b/LibGit2Sharp/Filter.cs @@ -1,16 +1,15 @@ -using System.Collections; -using System.Collections.Generic; -using System.Linq; +using System; namespace LibGit2Sharp { /// - /// Criterias used to filter out and order the commits of the repository when querying its history. + /// Criterias used to filter out and order the commits of the repository when querying its history. /// + [Obsolete("This type will be removed in the next release.")] public class Filter { /// - /// Initializes a new instance of . + /// Initializes a new instance of . /// public Filter() { @@ -19,69 +18,44 @@ public Filter() } /// - /// The ordering stragtegy to use. - /// - /// By default, the commits are shown in reverse chronological order. - /// + /// The ordering stragtegy to use. + /// + /// By default, the commits are shown in reverse chronological order. + /// /// public GitSortOptions SortBy { get; set; } /// - /// A pointer to a commit object or a list of pointers to consider as starting points. - /// - /// Can be either a containing the sha or reference canonical name to use, - /// a , a , a , a , - /// a , an or even a mixed collection of all of the above. - /// By default, the will be used as boundary. - /// + /// A pointer to a commit object or a list of pointers to consider as starting points. + /// + /// Can be either a containing the sha or reference canonical name to use, + /// a , a , a , a , + /// a , an or even a mixed collection of all of the above. + /// By default, the will be used as boundary. + /// /// public object Since { get; set; } - internal IList SinceList - { - get { return ToList(Since); } - } - /// - /// A pointer to a commit object or a list of pointers which will be excluded (along with ancestors) from the enumeration. - /// - /// Can be either a containing the sha or reference canonical name to use, - /// a , a , a , a , - /// a , an or even a mixed collection of all of the above. - /// + /// A pointer to a commit object or a list of pointers which will be excluded (along with ancestors) from the enumeration. + /// + /// Can be either a containing the sha or reference canonical name to use, + /// a , a , a , a , + /// a , an or even a mixed collection of all of the above. + /// /// public object Until { get; set; } - internal IList UntilList - { - get { return ToList(Until); } - } - - private static IList ToList(object obj) + internal CommitFilter ToCommitFilter() { - var list = new List(); - - if (obj == null) - { - return list; - } - - var types = new[] - { - typeof(string), typeof(ObjectId), - typeof(Commit), typeof(TagAnnotation), - typeof(Tag), typeof(Branch), typeof(DetachedHead), - typeof(Reference), typeof(DirectReference), typeof(SymbolicReference) - }; - - if (types.Contains(obj.GetType())) - { - list.Add(obj); - return list; - } - - list.AddRange(((IEnumerable)obj).Cast()); - return list; + var cf = new CommitFilter + { + Since = Since, + SortBy = (CommitSortStrategies) SortBy, + Until = Until + }; + + return cf; } } } diff --git a/LibGit2Sharp/GitLink.cs b/LibGit2Sharp/GitLink.cs index ec06cbcc9..398ab3217 100644 --- a/LibGit2Sharp/GitLink.cs +++ b/LibGit2Sharp/GitLink.cs @@ -3,13 +3,13 @@ namespace LibGit2Sharp { /// - /// Represents a gitlink (a reference to a commit in another Git repository) + /// Represents a gitlink (a reference to a commit in another Git repository) /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class GitLink : GitObject { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected GitLink() { } diff --git a/LibGit2Sharp/GitObject.cs b/LibGit2Sharp/GitObject.cs index a595f931a..ad4614dc4 100644 --- a/LibGit2Sharp/GitObject.cs +++ b/LibGit2Sharp/GitObject.cs @@ -8,7 +8,7 @@ namespace LibGit2Sharp { /// - /// A GitObject + /// A GitObject /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public abstract class GitObject : IEquatable @@ -26,21 +26,21 @@ public abstract class GitObject : IEquatable new LambdaEqualityHelper(x => x.Id); /// - /// The containing the object. + /// The containing the object. /// protected readonly Repository repo; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected GitObject() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The containing the object. - /// The it should be identified by. + /// The containing the object. + /// The it should be identified by. protected GitObject(Repository repo, ObjectId id) { this.repo = repo; @@ -48,12 +48,12 @@ protected GitObject(Repository repo, ObjectId id) } /// - /// Gets the id of this object + /// Gets the id of this object /// public virtual ObjectId Id { get; private set; } /// - /// Gets the 40 character sha1 of this object. + /// Gets the 40 character sha1 of this object. /// public virtual string Sha { @@ -91,27 +91,27 @@ internal Commit DereferenceToCommit(bool throwsIfCanNotBeDereferencedToACommit) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as GitObject); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(GitObject other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -120,10 +120,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(GitObject left, GitObject right) { @@ -131,10 +131,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(GitObject left, GitObject right) { @@ -142,9 +142,9 @@ public override int GetHashCode() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// - /// The that represents the current . + /// The that represents the current . public override string ToString() { return Id.ToString(); diff --git a/LibGit2Sharp/GitSortOptions.cs b/LibGit2Sharp/GitSortOptions.cs index d56f97952..0ab76f960 100644 --- a/LibGit2Sharp/GitSortOptions.cs +++ b/LibGit2Sharp/GitSortOptions.cs @@ -3,36 +3,37 @@ namespace LibGit2Sharp { /// - /// Determines the sorting strategy when iterating through the content of the repository + /// Determines the sorting strategy when iterating through the content of the repository /// [Flags] + [Obsolete("This type will be removed in the next release.")] public enum GitSortOptions { /// - /// Sort the repository contents in no particular ordering; - /// this sorting is arbitrary, implementation-specific - /// and subject to change at any time. + /// 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. + /// 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. + /// 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. + /// Iterate through the repository contents in reverse + /// order; this sorting mode can be combined with + /// any of the above. /// Reverse = (1 << 2) } diff --git a/LibGit2Sharp/Handlers.cs b/LibGit2Sharp/Handlers.cs index eb2dc03f5..4d8ceefe4 100644 --- a/LibGit2Sharp/Handlers.cs +++ b/LibGit2Sharp/Handlers.cs @@ -1,19 +1,19 @@ namespace LibGit2Sharp.Handlers { /// - /// Delegate definition to handle Progress callback. - /// Returns the text as reported by the server. The text - /// in the serverProgressOutput parameter is not delivered - /// in any particular units (i.e. not necessarily delivered - /// as whole lines) and is likely to be chunked as partial lines. + /// Delegate definition to handle Progress callback. + /// Returns the text as reported by the server. The text + /// in the serverProgressOutput parameter is not delivered + /// in any particular units (i.e. not necessarily delivered + /// as whole lines) and is likely to be chunked as partial lines. /// /// text reported by the server. - /// Text can be chunked at arbitrary increments (i.e. can be composed - /// of a partial line of text). + /// Text can be chunked at arbitrary increments (i.e. can be composed + /// of a partial line of text). public delegate void ProgressHandler(string serverProgressOutput); /// - /// Delegate definition to handle UpdateTips callback. + /// Delegate definition to handle UpdateTips callback. /// /// Name of the updated reference. /// Old ID of the reference. @@ -22,25 +22,25 @@ public delegate int UpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId); /// - /// Delegate definition to handle Completion callback. + /// Delegate definition to handle Completion callback. /// public delegate int CompletionHandler(RemoteCompletionType remoteCompletionType); /// - /// Delegate definition for transfer progress callback. + /// Delegate definition for transfer progress callback. /// - /// The object containing progress information. + /// The object containing progress information. /// Return negative integer to cancel. public delegate int TransferProgressHandler(TransferProgress progress); /// - /// Delegate definition to handle reporting errors when updating references on the remote. + /// Delegate definition to handle reporting errors when updating references on the remote. /// /// The reference name and error from the server. public delegate void PushStatusErrorHandler(PushStatusError pushStatusErrors); /// - /// Delegate definition for checkout progress callback. + /// Delegate definition for checkout progress callback. /// /// Path of the updated file. /// Number of completed steps. @@ -48,10 +48,18 @@ public delegate void CheckoutProgressHandler(string path, int completedSteps, int totalSteps); /// - /// Delegate definition for unmatched path callback. - /// - /// This callback will be called to notify the caller of unmatched path. - /// + /// Delegate definition for checkout notification callback. + /// + /// The path the callback corresponds to. + /// The checkout notification type. + /// True to continue checkout operation; false to cancel checkout operation. + public delegate bool CheckoutNotifyHandler(string path, CheckoutNotifyFlags notifyFlags); + + /// + /// Delegate definition for unmatched path callback. + /// + /// This callback will be called to notify the caller of unmatched path. + /// /// /// The unmatched path. public delegate void UnmatchedPathHandler(string unmatchedPath); diff --git a/LibGit2Sharp/ICommitLog.cs b/LibGit2Sharp/ICommitLog.cs index 652e6832a..f773532fe 100644 --- a/LibGit2Sharp/ICommitLog.cs +++ b/LibGit2Sharp/ICommitLog.cs @@ -1,16 +1,15 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace LibGit2Sharp { /// - /// A log of commits in a . + /// A log of commits in a . /// public interface ICommitLog : IEnumerable { /// - /// Gets the current sorting strategy applied when enumerating the log. + /// Gets the current sorting strategy applied when enumerating the log. /// - GitSortOptions SortedBy { get; } + CommitSortStrategies SortedBy { get; } } } diff --git a/LibGit2Sharp/IQueryableCommitLog.cs b/LibGit2Sharp/IQueryableCommitLog.cs index 292a0c3f8..716a798a4 100644 --- a/LibGit2Sharp/IQueryableCommitLog.cs +++ b/LibGit2Sharp/IQueryableCommitLog.cs @@ -1,31 +1,40 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace LibGit2Sharp { /// - /// A log of commits in a that can be filtered with queries. + /// A log of commits in a that can be filtered with queries. /// public interface IQueryableCommitLog : ICommitLog { /// - /// Returns the list of commits of the repository matching the specified . + /// Returns the list of commits of the repository matching the specified . /// - /// The options used to control which commits will be returned. + /// The options used to control which commits will be returned. /// A list of commits, ready to be enumerated. + [Obsolete("This method will be removed in the next release. Please use QueryBy(CommitFilter) instead.")] ICommitLog QueryBy(Filter filter); /// - /// Find the best possible common ancestor given two s. + /// Returns the list of commits of the repository matching the specified . /// - /// The first . - /// The second . + /// The options used to control which commits will be returned. + /// A list of commits, ready to be enumerated. + ICommitLog QueryBy(CommitFilter filter); + + /// + /// Find the best possible common ancestor given two s. + /// + /// The first . + /// The second . /// The common ancestor or null if none found. Commit FindCommonAncestor(Commit first, Commit second); /// - /// Find the best possible common ancestor given two or more s. + /// Find the best possible common ancestor given two or more s. /// - /// The for which to find the common ancestor. + /// The for which to find the common ancestor. /// The common ancestor or null if none found. Commit FindCommonAncestor(IEnumerable commits); } diff --git a/LibGit2Sharp/IRepository.cs b/LibGit2Sharp/IRepository.cs index f1acef0d5..b011a4da6 100644 --- a/LibGit2Sharp/IRepository.cs +++ b/LibGit2Sharp/IRepository.cs @@ -5,148 +5,224 @@ namespace LibGit2Sharp { /// - /// A Repository is the primary interface into a git repository + /// A Repository is the primary interface into a git repository /// public interface IRepository : IDisposable { /// - /// Shortcut to return the branch pointed to by HEAD + /// Shortcut to return the branch pointed to by HEAD /// - /// Branch Head { get; } /// - /// Provides access to the configuration settings for this repository. + /// Provides access to the configuration settings for this repository. /// Configuration Config { get; } /// - /// Gets the index. + /// Gets the index. /// Index Index { get; } /// - /// Lookup and enumerate references in the repository. + /// Lookup and enumerate references in the repository. /// ReferenceCollection Refs { get; } /// - /// Lookup and enumerate commits in the repository. - /// Iterating this collection directly starts walking from the HEAD. + /// Lookup and enumerate commits in the repository. + /// Iterating this collection directly starts walking from the HEAD. /// IQueryableCommitLog Commits { get; } /// - /// Lookup and enumerate branches in the repository. + /// Lookup and enumerate branches in the repository. /// BranchCollection Branches { get; } /// - /// Lookup and enumerate tags in the repository. + /// Lookup and enumerate tags in the repository. /// TagCollection Tags { get; } /// - /// Provides high level information about this repository. + /// Provides high level information about this repository. /// RepositoryInformation Info { get; } /// - /// 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. + /// 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. /// Diff Diff {get;} /// - /// Gets the database. + /// Gets the database. /// ObjectDatabase ObjectDatabase { get; } /// - /// Lookup notes in the repository. + /// Lookup notes in the repository. /// NoteCollection Notes { get; } /// - /// Submodules in the repository. + /// Submodules in the repository. /// SubmoduleCollection Submodules { get; } /// - /// Checkout the specified . + /// Checkout the commit pointed at by the tip of the specified . + /// + /// If this commit is the current tip of the branch as it exists in the repository, the HEAD + /// will point to this branch. Otherwise, the HEAD will be detached, pointing at the commit sha. + /// /// - /// The to check out. - /// controlling checkout behavior. - /// that checkout progress is reported through. - /// The that was checked out. + /// The to check out. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// The that was checked out. + [Obsolete("This method will be removed in the next release. Please use Checkout(Branch, CheckoutModifiers, CheckoutProgressHandler, CheckoutNotificationOptions) instead.")] Branch Checkout(Branch branch, CheckoutOptions checkoutOptions, CheckoutProgressHandler onCheckoutProgress); /// - /// Checkout the specified branch, reference or SHA. + /// Checkout the commit pointed at by the tip of the specified . + /// + /// If this commit is the current tip of the branch as it exists in the repository, the HEAD + /// will point to this branch. Otherwise, the HEAD will be detached, pointing at the commit sha. + /// /// - /// A revparse spec for the commit or branch to checkout. + /// The to check out. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// to manage checkout notifications. + /// The that was checked out. + Branch Checkout(Branch branch, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions); + + /// + /// Checkout the specified branch, reference or SHA. + /// + /// If the committishOrBranchSpec parameter resolves to a branch name, then the checked out HEAD will + /// will point to the branch. Otherwise, the HEAD will be detached, pointing at the commit sha. + /// + /// + /// A revparse spec for the commit or branch to checkout. /// Options controlling checkout behavior. /// Callback method to report checkout progress updates through. - /// The new HEAD. + /// The that was checked out. + [Obsolete("This method will be removed in the next release. Please use Checkout(string, CheckoutModifiers, CheckoutProgressHandler, CheckoutNotificationOptions) instead.")] Branch Checkout(string committishOrBranchSpec, CheckoutOptions checkoutOptions, CheckoutProgressHandler onCheckoutProgress); /// - /// Try to lookup an object by its . If no matching object is found, null will be returned. + /// Checkout the specified branch, reference or SHA. + /// + /// If the committishOrBranchSpec parameter resolves to a branch name, then the checked out HEAD will + /// will point to the branch. Otherwise, the HEAD will be detached, pointing at the commit sha. + /// + /// + /// A revparse spec for the commit or branch to checkout. + /// Options controlling checkout behavior. + /// Callback method to report checkout progress updates through. + /// to manage checkout notifications. + /// The that was checked out. + Branch Checkout(string committishOrBranchSpec, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions); + + /// + /// Checkout the specified . + /// + /// Will detach the HEAD and make it point to this commit sha. + /// + /// + /// The to check out. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// The that was checked out. + [Obsolete("This method will be removed in the next release. Please use Checkout(Commit, CheckoutModifiers, CheckoutProgressHandler, CheckoutNotificationOptions) instead.")] + Branch Checkout(Commit commit, CheckoutOptions checkoutOptions, CheckoutProgressHandler onCheckoutProgress); + + /// + /// Checkout the specified . + /// + /// Will detach the HEAD and make it point to this commit sha. + /// + /// + /// The to check out. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// to manage checkout notifications. + /// The that was checked out. + Branch Checkout(Commit commit, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions); + + /// + /// Checkout files from the specified branch, reference or SHA. + /// + /// This method does not switch branches or update the current repository HEAD. + /// + /// + /// A revparse spec for the commit or branch to checkout paths from. + /// The paths to checkout. + /// Options controlling checkout behavior. + /// Callback method to report checkout progress updates through. + /// to manage checkout notifications. + void CheckoutPaths(string committishOrBranchSpec, IList paths, CheckoutModifiers checkoutOptions, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions); + + /// + /// Try to lookup an object by its . If no matching object is found, null will be returned. /// - /// The id to lookup. - /// The or null if it was not found. + /// The id to lookup. + /// The or null if it was not found. GitObject Lookup(ObjectId id); /// - /// Try to lookup an object by its sha or a reference canonical name. If no matching object is found, null will be returned. + /// Try to lookup an object by its sha or a reference canonical name. If no matching object is found, null will be returned. /// - /// A revparse spec for the object to lookup. - /// The or null if it was not found. + /// A revparse spec for the object to lookup. + /// The or null if it was not found. GitObject Lookup(string objectish); /// - /// Try to lookup an object by its and . If no matching object is found, null will be returned. + /// Try to lookup an object by its and . If no matching object is found, null will be returned. /// - /// The id to lookup. - /// The kind of GitObject being looked up - /// The or null if it was not found. + /// The id to lookup. + /// The kind of GitObject being looked up + /// The or null if it was not found. GitObject Lookup(ObjectId id, ObjectType type); /// - /// Try to lookup an object by its sha or a reference canonical name and . If no matching object is found, null will be returned. + /// Try to lookup an object by its sha or a reference canonical name and . If no matching object is found, null will be returned. /// - /// A revparse spec for the object to lookup. - /// The kind of being looked up - /// The or null if it was not found. + /// A revparse spec for the object to lookup. + /// The kind of being looked up + /// The or null if it was not found. GitObject Lookup(string objectish, ObjectType type); /// - /// Stores the content of the as a new into the repository. - /// The tip of the will be used as the parent of this new Commit. - /// Once the commit is created, the will move forward to point at it. + /// Stores the content of the as a new into the repository. + /// The tip of the will be used as the parent of this new Commit. + /// Once the commit is created, the will move forward to point at it. /// - /// The description of why a change was made to the repository. - /// The of who made the change. - /// The of who added the change to the repository. - /// True to amend the current pointed at by , false otherwise. - /// The generated . + /// The description of why a change was made to the repository. + /// The of who made the change. + /// The of who added the change to the repository. + /// True to amend the current pointed at by , false otherwise. + /// The generated . Commit Commit(string message, Signature author, Signature committer, bool amendPreviousCommit = false); /// - /// Sets the current to the specified commit and optionally resets the and - /// the content of the working tree to match. + /// Sets the current to the specified commit and optionally resets the and + /// the content of the working tree to match. /// - /// Flavor of reset operation to perform. - /// The target commit object. + /// Flavor of reset operation to perform. + /// The target commit object. void Reset(ResetOptions resetOptions, Commit commit); /// - /// Replaces entries in the with entries from the specified commit. + /// Replaces entries in the with entries from the specified commit. /// - /// The target commit object. - /// The list of paths (either files or directories) that should be considered. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The target commit object. + /// The list of paths (either files or directories) that should be considered. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// void Reset(Commit commit, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null); @@ -156,12 +232,12 @@ public interface IRepository : IDisposable void RemoveUntrackedFiles(); /// - /// Gets the references to the tips that are currently being merged. + /// Gets the references to the tips that are currently being merged. /// IEnumerable MergeHeads { get; } /// - /// Provides access to network functionality for a repository. + /// Provides access to network functionality for a repository. /// Network Network { get; } } diff --git a/LibGit2Sharp/Ignore.cs b/LibGit2Sharp/Ignore.cs index d31789389..63ec6b264 100644 --- a/LibGit2Sharp/Ignore.cs +++ b/LibGit2Sharp/Ignore.cs @@ -6,15 +6,15 @@ namespace LibGit2Sharp { /// - /// Provides methods to manage the rules ensuring that some specific - /// untracked files are ignored. + /// Provides methods to manage the rules ensuring that some specific + /// untracked files are ignored. /// public class Ignore { private readonly Repository repo; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Ignore() { } @@ -25,8 +25,8 @@ internal Ignore(Repository repo) } /// - /// Adds a custom .gitignore rule that will be applied to futher operations to the Index. This is in addition - /// to the standard .gitignore rules that would apply as a result of the system/user/repo .gitignore + /// Adds a custom .gitignore rule that will be applied to futher operations to the Index. This is in addition + /// to the standard .gitignore rules that would apply as a result of the system/user/repo .gitignore /// /// The content of a .gitignore file that will be applied. public virtual void AddTemporaryRules(IEnumerable rules) @@ -44,9 +44,9 @@ public virtual void AddTemporaryRules(IEnumerable rules) } /// - /// Resets all custom rules that were applied via calls to - /// - note that this will not affect - /// the application of the user/repo .gitignores. + /// Resets all custom rules that were applied via calls to + /// - note that this will not affect + /// the application of the user/repo .gitignores. /// public virtual void ResetAllTemporaryRules() { @@ -54,8 +54,8 @@ public virtual void ResetAllTemporaryRules() } /// - /// Given a relative path, this method determines whether a path should be ignored, checking - /// both the custom ignore rules as well as the "normal" .gitignores. + /// Given a relative path, this method determines whether a path should be ignored, checking + /// both the custom ignore rules as well as the "normal" .gitignores. /// /// A path relative to the repository /// true if the path should be ignored. diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index 4ab480992..e17005f44 100644 --- a/LibGit2Sharp/Index.cs +++ b/LibGit2Sharp/Index.cs @@ -13,8 +13,8 @@ namespace LibGit2Sharp { /// - /// The Index is a staging area between the Working directory and the Repository. - /// It's used to prepare and aggregate the changes that will be part of the next commit. + /// The Index is a staging area between the Working directory and the Repository. + /// It's used to prepare and aggregate the changes that will be part of the next commit. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class Index : IEnumerable @@ -24,7 +24,7 @@ public class Index : IEnumerable private readonly ConflictCollection conflicts; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Index() { } @@ -56,7 +56,7 @@ internal IndexSafeHandle Handle } /// - /// Gets the number of in the index. + /// Gets the number of in the index. /// public virtual int Count { @@ -64,7 +64,7 @@ public virtual int Count } /// - /// Determines if the index is free from conflicts. + /// Determines if the index is free from conflicts. /// public virtual bool IsFullyMerged { @@ -72,7 +72,7 @@ public virtual bool IsFullyMerged } /// - /// Gets the with the specified relative path. + /// Gets the with the specified relative path. /// public virtual IndexEntry this[string path] { @@ -110,18 +110,18 @@ private List AllIndexEntries() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { return AllIndexEntries().GetEnumerator(); } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); @@ -130,12 +130,12 @@ IEnumerator IEnumerable.GetEnumerator() #endregion /// - /// Promotes to the staging area the latest modifications of a file in the working directory (addition, updation or removal). + /// Promotes to the staging area the latest modifications of a file in the working directory (addition, updation or removal). /// - /// The path of the file within the working directory. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The path of the file within the working directory. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// public virtual void Stage(string path, ExplicitPathsOptions explicitPathsOptions = null) { @@ -145,18 +145,18 @@ public virtual void Stage(string path, ExplicitPathsOptions explicitPathsOptions } /// - /// Promotes to the staging area the latest modifications of a collection of files in the working directory (addition, updation or removal). + /// Promotes to the staging area the latest modifications of a collection of files in the working directory (addition, updation or removal). /// - /// The collection of paths of the files within the working directory. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The collection of paths of the files within the working directory. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// public virtual void Stage(IEnumerable paths, ExplicitPathsOptions explicitPathsOptions = null) { Ensure.ArgumentNotNull(paths, "paths"); - TreeChanges changes = repo.Diff.Compare(DiffOptions.IncludeUntracked | DiffOptions.IncludeIgnored, paths, explicitPathsOptions); + TreeChanges changes = repo.Diff.Compare(DiffModifiers.IncludeUntracked | DiffModifiers.IncludeIgnored, paths, explicitPathsOptions); foreach (var treeEntryChanges in changes) { @@ -185,12 +185,12 @@ public virtual void Stage(IEnumerable paths, ExplicitPathsOptions explic } /// - /// Removes from the staging area all the modifications of a file since the latest commit (addition, updation or removal). + /// Removes from the staging area all the modifications of a file since the latest commit (addition, updation or removal). /// - /// The path of the file within the working directory. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The path of the file within the working directory. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// public virtual void Unstage(string path, ExplicitPathsOptions explicitPathsOptions = null) { @@ -200,12 +200,12 @@ public virtual void Unstage(string path, ExplicitPathsOptions explicitPathsOptio } /// - /// Removes from the staging area all the modifications of a collection of file since the latest commit (addition, updation or removal). + /// Removes from the staging area all the modifications of a collection of file since the latest commit (addition, updation or removal). /// - /// The collection of paths of the files within the working directory. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The collection of paths of the files within the working directory. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// public virtual void Unstage(IEnumerable paths, ExplicitPathsOptions explicitPathsOptions = null) { @@ -224,20 +224,20 @@ public virtual void Unstage(IEnumerable paths, ExplicitPathsOptions expl } /// - /// Moves and/or renames a file in the working directory and promotes the change to the staging area. + /// Moves and/or renames a file in the working directory and promotes the change to the staging area. /// - /// The path of the file within the working directory which has to be moved/renamed. - /// The target path of the file within the working directory. + /// The path of the file within the working directory which has to be moved/renamed. + /// The target path of the file within the working directory. public virtual void Move(string sourcePath, string destinationPath) { Move(new[] { sourcePath }, new[] { destinationPath }); } /// - /// Moves and/or renames a collection of files in the working directory and promotes the changes to the staging area. + /// Moves and/or renames a collection of files in the working directory and promotes the changes to the staging area. /// - /// The paths of the files within the working directory which have to be moved/renamed. - /// The target paths of the files within the working directory. + /// The paths of the files within the working directory which have to be moved/renamed. + /// The target paths of the files within the working directory. public virtual void Move(IEnumerable sourcePaths, IEnumerable destinationPaths) { Ensure.ArgumentNotNull(sourcePaths, "sourcePaths"); @@ -297,25 +297,25 @@ public virtual void Move(IEnumerable sourcePaths, IEnumerable de } /// - /// Removes a file from the staging area, and optionally removes it from the working directory as well. - /// - /// If the file has already been deleted from the working directory, this method will only deal - /// with promoting the removal to the staging area. - /// - /// - /// The default behavior is to remove the file from the working directory as well. - /// - /// - /// When not passing a , the passed path will be treated as - /// a pathspec. You can for example use it to pass the relative path to a folder inside the working directory, - /// so that all files beneath this folders, and the folder itself, will be removed. - /// + /// Removes a file from the staging area, and optionally removes it from the working directory as well. + /// + /// If the file has already been deleted from the working directory, this method will only deal + /// with promoting the removal to the staging area. + /// + /// + /// The default behavior is to remove the file from the working directory as well. + /// + /// + /// When not passing a , the passed path will be treated as + /// a pathspec. You can for example use it to pass the relative path to a folder inside the working directory, + /// so that all files beneath this folders, and the folder itself, will be removed. + /// /// - /// The path of the file within the working directory. - /// True to remove the file from the working directory, False otherwise. - /// - /// If set, the passed will be treated as an explicit path. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The path of the file within the working directory. + /// True to remove the file from the working directory, False otherwise. + /// + /// If set, the passed will be treated as an explicit path. + /// Use these options to determine how unmatched explicit paths should be handled. /// public virtual void Remove(string path, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { @@ -325,30 +325,30 @@ public virtual void Remove(string path, bool removeFromWorkingDirectory = true, } /// - /// Removes a collection of fileS from the staging, and optionally removes them from the working directory as well. - /// - /// If a file has already been deleted from the working directory, this method will only deal - /// with promoting the removal to the staging area. - /// - /// - /// The default behavior is to remove the files from the working directory as well. - /// - /// - /// When not passing a , the passed paths will be treated as - /// a pathspec. You can for example use it to pass the relative paths to folders inside the working directory, - /// so that all files beneath these folders, and the folders themselves, will be removed. - /// + /// Removes a collection of fileS from the staging, and optionally removes them from the working directory as well. + /// + /// If a file has already been deleted from the working directory, this method will only deal + /// with promoting the removal to the staging area. + /// + /// + /// The default behavior is to remove the files from the working directory as well. + /// + /// + /// When not passing a , the passed paths will be treated as + /// a pathspec. You can for example use it to pass the relative paths to folders inside the working directory, + /// so that all files beneath these folders, and the folders themselves, will be removed. + /// /// - /// The collection of paths of the files within the working directory. - /// True to remove the files from the working directory, False otherwise. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The collection of paths of the files within the working directory. + /// True to remove the files from the working directory, False otherwise. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// public virtual void Remove(IEnumerable paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { var pathsList = paths.ToList(); - TreeChanges changes = repo.Diff.Compare(DiffOptions.IncludeUnmodified | DiffOptions.IncludeUntracked, pathsList, explicitPathsOptions); + TreeChanges changes = repo.Diff.Compare(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, pathsList, explicitPathsOptions); var pathsTodelete = pathsList.Where(p => Directory.Exists(Path.Combine(repo.Info.WorkingDirectory, p))).ToList(); @@ -483,10 +483,10 @@ private void UpdatePhysicalIndex() } /// - /// Retrieves the state of a file in the working directory, comparing it against the staging area and the latest commmit. + /// Retrieves the state of a file in the working directory, comparing it against the staging area and the latest commmit. /// - /// The relative path within the working directory to the file. - /// A representing the state of the parameter. + /// The relative path within the working directory to the file. + /// A representing the state of the parameter. public virtual FileStatus RetrieveStatus(string filePath) { Ensure.ArgumentNotNullOrEmptyString(filePath, "filePath"); @@ -497,9 +497,9 @@ public virtual FileStatus RetrieveStatus(string filePath) } /// - /// Retrieves the state of all files in the working directory, comparing them against the staging area and the latest commmit. + /// Retrieves the state of all files in the working directory, comparing them against the staging area and the latest commmit. /// - /// A holding the state of all the files. + /// A holding the state of all the files. public virtual RepositoryStatus RetrieveStatus() { return new RepositoryStatus(repo); diff --git a/LibGit2Sharp/IndexEntry.cs b/LibGit2Sharp/IndexEntry.cs index 7a9c51bb8..c76a5e51d 100644 --- a/LibGit2Sharp/IndexEntry.cs +++ b/LibGit2Sharp/IndexEntry.cs @@ -7,31 +7,31 @@ namespace LibGit2Sharp { /// - /// A reference to a known by the . + /// A reference to a known by the . /// - [DebuggerDisplayAttribute("{DebuggerDisplay,nq}")] + [DebuggerDisplay("{DebuggerDisplay,nq}")] public class IndexEntry : IEquatable { private static readonly LambdaEqualityHelper equalityHelper = new LambdaEqualityHelper(x => x.Path, x => x.Id, x => x.Mode, x => x.StageLevel); /// - /// Gets the relative path to the file within the working directory. + /// Gets the relative path to the file within the working directory. /// public virtual string Path { get; private set; } /// - /// Gets the file mode. + /// Gets the file mode. /// public virtual Mode Mode { get; private set; } /// - /// Gets the stage number. + /// Gets the stage number. /// public virtual StageLevel StageLevel { get; private set; } /// - /// Gets the id of the pointed at by this index entry. + /// Gets the id of the pointed at by this index entry. /// public virtual ObjectId Id { get; private set; } @@ -56,27 +56,27 @@ internal static IndexEntry BuildFromPtr(Repository repo, IndexEntrySafeHandle ha } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as IndexEntry); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(IndexEntry other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -85,10 +85,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(IndexEntry left, IndexEntry right) { @@ -96,10 +96,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(IndexEntry left, IndexEntry right) { diff --git a/LibGit2Sharp/InvalidSpecificationException.cs b/LibGit2Sharp/InvalidSpecificationException.cs index 3d497b737..fdeb9a236 100644 --- a/LibGit2Sharp/InvalidSpecificationException.cs +++ b/LibGit2Sharp/InvalidSpecificationException.cs @@ -5,42 +5,42 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when the provided specification is syntactically incorrect. + /// The exception that is thrown when the provided specification is syntactically incorrect. /// [Serializable] public class InvalidSpecificationException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public InvalidSpecificationException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public InvalidSpecificationException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public InvalidSpecificationException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected InvalidSpecificationException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 0da4df39c..9c50b13bb 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -66,19 +66,30 @@ + + + + + + + + + + + @@ -123,7 +134,6 @@ - @@ -149,7 +159,7 @@ - + @@ -249,6 +259,7 @@ + diff --git a/LibGit2Sharp/LibGit2SharpException.cs b/LibGit2Sharp/LibGit2SharpException.cs index 20b51e5f4..6844f9509 100644 --- a/LibGit2Sharp/LibGit2SharpException.cs +++ b/LibGit2Sharp/LibGit2SharpException.cs @@ -6,42 +6,42 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when an error occurs during application execution. + /// The exception that is thrown when an error occurs during application execution. /// [Serializable] public class LibGit2SharpException : Exception { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public LibGit2SharpException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public LibGit2SharpException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public LibGit2SharpException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected LibGit2SharpException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/MatchedPathsAggregator.cs b/LibGit2Sharp/MatchedPathsAggregator.cs index 4ae2e359f..aa9a9f1c5 100644 --- a/LibGit2Sharp/MatchedPathsAggregator.cs +++ b/LibGit2Sharp/MatchedPathsAggregator.cs @@ -10,7 +10,7 @@ internal class MatchedPathsAggregator : IEnumerable private readonly List matchedPaths = new List(); /// - /// The delegate with a signature that matches the native diff git_diff_notify_cb function's signature. + /// The delegate with a signature that matches the native diff git_diff_notify_cb function's signature. /// /// The diff list so far, before the delta is inserted. /// The delta that is being diffed diff --git a/LibGit2Sharp/MergeConflictException.cs b/LibGit2Sharp/MergeConflictException.cs index 7ee86b008..802b8df58 100644 --- a/LibGit2Sharp/MergeConflictException.cs +++ b/LibGit2Sharp/MergeConflictException.cs @@ -5,43 +5,43 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when a merge cannot be performed because - /// of a conflicting change. + /// The exception that is thrown when a merge cannot be performed because + /// of a conflicting change. /// [Serializable] public class MergeConflictException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public MergeConflictException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public MergeConflictException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public MergeConflictException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected MergeConflictException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/MergeHead.cs b/LibGit2Sharp/MergeHead.cs index 4e0076cab..8881b26b4 100644 --- a/LibGit2Sharp/MergeHead.cs +++ b/LibGit2Sharp/MergeHead.cs @@ -3,12 +3,12 @@ namespace LibGit2Sharp { /// - /// A merge head is a parent for the next commit. + /// A merge head is a parent for the next commit. /// public class MergeHead : ReferenceWrapper { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected MergeHead() { } @@ -19,7 +19,7 @@ internal MergeHead(Repository repo, ObjectId targetId, int index) } /// - /// Gets the that this merge head points to. + /// Gets the that this merge head points to. /// public virtual Commit Tip { @@ -27,7 +27,7 @@ public virtual Commit Tip } /// - /// Returns "MERGE_HEAD[i]", where i is the index of this merge head. + /// Returns "MERGE_HEAD[i]", where i is the index of this merge head. /// protected override string Shorten() { diff --git a/LibGit2Sharp/Mode.cs b/LibGit2Sharp/Mode.cs index d164956d5..b15a2a97b 100644 --- a/LibGit2Sharp/Mode.cs +++ b/LibGit2Sharp/Mode.cs @@ -1,49 +1,49 @@ namespace LibGit2Sharp { /// - /// Git specific modes for entries. + /// Git specific modes for entries. /// public enum Mode { // Inspired from http://stackoverflow.com/a/8347325/335418 /// - /// 000000 file mode (the entry doesn't exist) + /// 000000 file mode (the entry doesn't exist) /// Nonexistent = 0, /// - /// 040000 file mode + /// 040000 file mode /// Directory = 0x4000, /// - /// 100644 file mode + /// 100644 file mode /// NonExecutableFile = 0x81A4, /// - /// Obsolete 100664 file mode. - /// 0100664 mode is an early Git design mistake. It's kept for - /// ascendant compatibility as some and - /// entries may still bear - /// this mode in some old git repositories, but it's now deprecated. - /// + /// Obsolete 100664 file mode. + /// 0100664 mode is an early Git design mistake. It's kept for + /// ascendant compatibility as some and + /// entries may still bear + /// this mode in some old git repositories, but it's now deprecated. + /// /// NonExecutableGroupWritableFile = 0x81B4, /// - /// 100755 file mode + /// 100755 file mode /// ExecutableFile = 0x81ED, /// - /// 120000 file mode + /// 120000 file mode /// SymbolicLink = 0xA000, /// - /// 160000 file mode + /// 160000 file mode /// GitLink = 0xE000 } diff --git a/LibGit2Sharp/NameConflictException.cs b/LibGit2Sharp/NameConflictException.cs index 989256ca2..75ec7807e 100644 --- a/LibGit2Sharp/NameConflictException.cs +++ b/LibGit2Sharp/NameConflictException.cs @@ -5,42 +5,42 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when a reference, a remote, a submodule... with the same name already exists in the repository + /// The exception that is thrown when a reference, a remote, a submodule... with the same name already exists in the repository /// [Serializable] public class NameConflictException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public NameConflictException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public NameConflictException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public NameConflictException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected NameConflictException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/Network.cs b/LibGit2Sharp/Network.cs index 628f9f45e..c57c28ef9 100644 --- a/LibGit2Sharp/Network.cs +++ b/LibGit2Sharp/Network.cs @@ -10,7 +10,7 @@ namespace LibGit2Sharp { /// - /// Provides access to network functionality for a repository. + /// Provides access to network functionality for a repository. /// public class Network { @@ -18,7 +18,7 @@ public class Network private readonly Lazy remotes; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Network() { } @@ -30,7 +30,7 @@ internal Network(Repository repository) } /// - /// The heads that have been updated during the last fetch. + /// The heads that have been updated during the last fetch. /// public virtual IEnumerable FetchHeads { @@ -45,7 +45,7 @@ public virtual IEnumerable FetchHeads } /// - /// Lookup and manage remotes in the repository. + /// Lookup and manage remotes in the repository. /// public virtual RemoteCollection Remotes { @@ -53,10 +53,10 @@ public virtual RemoteCollection Remotes } /// - /// List references in a repository. + /// List references in a repository. /// - /// The to list from. - /// The references in the repository. + /// The to list from. + /// The references in the repository. public virtual IEnumerable ListReferences(Remote remote) { Ensure.ArgumentNotNull(remote, "remote"); @@ -90,7 +90,7 @@ public virtual IEnumerable ListReferences(Remote remote) } /// - /// Fetch from the . + /// Fetch from the . /// /// The remote to fetch /// Optional parameter indicating what tags to download. @@ -98,11 +98,11 @@ public virtual IEnumerable ListReferences(Remote remote) /// Completion callback. Corresponds to libgit2 completion callback. /// UpdateTips callback. Corresponds to libgit2 update_tips callback. /// Callback method that transfer progress will be reported through. - /// Reports the client's state regarding the received and processed (bytes, objects) from the server. + /// Reports the client's state regarding the received and processed (bytes, objects) from the server. /// Credentials to use for username/password authentication. public virtual void Fetch( Remote remote, - TagFetchMode tagFetchMode = TagFetchMode.Auto, + TagFetchMode? tagFetchMode = null, ProgressHandler onProgress = null, CompletionHandler onCompletion = null, UpdateTipsHandler onUpdateTips = null, @@ -121,7 +121,10 @@ public virtual void Fetch( var callbacks = new RemoteCallbacks(onProgress, onCompletion, onUpdateTips); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); - Proxy.git_remote_set_autotag(remoteHandle, tagFetchMode); + if (tagFetchMode.HasValue) + { + Proxy.git_remote_set_autotag(remoteHandle, tagFetchMode.Value); + } if (credentials != null) { @@ -162,9 +165,9 @@ public virtual void Fetch( } /// - /// Push the objectish to the destination reference on the . + /// Push the objectish to the destination reference on the . /// - /// The to push to. + /// The to push to. /// The source objectish to push. /// The reference to update on the remote. /// Handler for reporting failed push updates. @@ -185,9 +188,9 @@ public virtual void Push( } /// - /// Push specified reference to the . + /// Push specified reference to the . /// - /// The to push to. + /// The to push to. /// The pushRefSpec to push. /// Handler for reporting failed push updates. /// Credentials to use for user/pass authentication @@ -204,9 +207,9 @@ public virtual void Push( } /// - /// Push specified references to the . + /// Push specified references to the . /// - /// The to push to. + /// The to push to. /// The pushRefSpecs to push. /// Handler for reporting failed push updates. /// Credentials to use for user/pass authentication @@ -283,7 +286,7 @@ public virtual void Push( } /// - /// Helper class to handle callbacks during push. + /// Helper class to handle callbacks during push. /// private class PushCallbacks { diff --git a/LibGit2Sharp/NetworkExtensions.cs b/LibGit2Sharp/NetworkExtensions.cs index b675c399c..0bb96c99d 100644 --- a/LibGit2Sharp/NetworkExtensions.cs +++ b/LibGit2Sharp/NetworkExtensions.cs @@ -1,18 +1,18 @@ -using System.Globalization; +using System.Collections.Generic; +using System.Globalization; using System.Linq; using LibGit2Sharp.Core; -using System.Collections.Generic; using LibGit2Sharp.Handlers; namespace LibGit2Sharp { /// - /// Provides helper overloads to a . + /// Provides helper overloads to a . /// public static class NetworkExtensions { /// - /// Push the specified branch to its tracked branch on the remote. + /// Push the specified branch to its tracked branch on the remote. /// /// The being worked with. /// The branch to push. @@ -29,7 +29,7 @@ public static void Push( } /// - /// Push the specified branches to their tracked branches on the remote. + /// Push the specified branches to their tracked branches on the remote. /// /// The being worked with. /// The branches to push. @@ -60,10 +60,10 @@ public static void Push( } /// - /// Push the objectish to the destination reference on the . + /// Push the objectish to the destination reference on the . /// /// The being worked with. - /// The to push to. + /// The to push to. /// The source objectish to push. /// The reference to update on the remote. /// Credentials to use for user/pass authentication @@ -84,10 +84,10 @@ public static PushResult Push( } /// - /// Push specified reference to the . + /// Push specified reference to the . /// /// The being worked with. - /// The to push to. + /// The to push to. /// The pushRefSpec to push. /// Credentials to use for user/pass authentication /// Results of the push operation. @@ -100,7 +100,7 @@ public static PushResult Push(this Network network, Remote remote, string pushRe } /// - /// Push specified references to the . + /// Push specified references to the . /// /// The being worked with. /// The to push to. diff --git a/LibGit2Sharp/NonFastForwardException.cs b/LibGit2Sharp/NonFastForwardException.cs index 7f28045cb..d12576c05 100644 --- a/LibGit2Sharp/NonFastForwardException.cs +++ b/LibGit2Sharp/NonFastForwardException.cs @@ -5,43 +5,43 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when push cannot be performed - /// against the remote without losing commits. + /// The exception that is thrown when push cannot be performed + /// against the remote without losing commits. /// [Serializable] public class NonFastForwardException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public NonFastForwardException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public NonFastForwardException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public NonFastForwardException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected NonFastForwardException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/Note.cs b/LibGit2Sharp/Note.cs index 321ebc8a2..56004e2a5 100644 --- a/LibGit2Sharp/Note.cs +++ b/LibGit2Sharp/Note.cs @@ -7,13 +7,13 @@ namespace LibGit2Sharp { /// - /// A note, attached to a given . + /// A note, attached to a given . /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class Note : IEquatable { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Note() { } @@ -27,23 +27,23 @@ private Note(ObjectId blobId, string message, ObjectId targetObjectId, string @n } /// - /// The of the blob containing the note message. + /// The of the blob containing the note message. /// public virtual ObjectId BlobId { get; private set; } /// - /// The message. + /// The message. /// public virtual string Message { get; private set; } /// - /// The namespace with which this note is associated. - /// This is the abbreviated namespace (e.g.: commits), and not the canonical namespace (e.g.: refs/notes/commits). + /// The namespace with which this note is associated. + /// This is the abbreviated namespace (e.g.: commits), and not the canonical namespace (e.g.: refs/notes/commits). /// public virtual string Namespace { get; private set; } /// - /// The of the target object. + /// The of the target object. /// public virtual ObjectId TargetObjectId { get; private set; } @@ -59,27 +59,27 @@ internal static Note BuildFromPtr(NoteSafeHandle note, string @namespace, Object new LambdaEqualityHelper(x => x.BlobId, x => x.TargetObjectId, x => x.Namespace); /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Note); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(Note other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -88,10 +88,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(Note left, Note right) { @@ -99,10 +99,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(Note left, Note right) { diff --git a/LibGit2Sharp/NoteCollection.cs b/LibGit2Sharp/NoteCollection.cs index 7a57d3d2f..2cda44f10 100644 --- a/LibGit2Sharp/NoteCollection.cs +++ b/LibGit2Sharp/NoteCollection.cs @@ -11,7 +11,7 @@ namespace LibGit2Sharp { /// - /// A collection of exposed in the . + /// A collection of exposed in the . /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class NoteCollection : IEnumerable @@ -20,7 +20,7 @@ public class NoteCollection : IEnumerable private readonly Lazy defaultNamespace; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected NoteCollection() { } @@ -34,18 +34,18 @@ internal NoteCollection(Repository repo) #region Implementation of IEnumerable /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { return this[DefaultNamespace].GetEnumerator(); } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); @@ -54,7 +54,7 @@ IEnumerator IEnumerable.GetEnumerator() #endregion /// - /// The default namespace for notes. + /// The default namespace for notes. /// public virtual string DefaultNamespace { @@ -62,7 +62,7 @@ public virtual string DefaultNamespace } /// - /// The list of canonicalized namespaces related to notes. + /// The list of canonicalized namespaces related to notes. /// public virtual IEnumerable Namespaces { @@ -85,7 +85,7 @@ where refCanonical.StartsWith(Reference.NotePrefix, StringComparison.Ordinal) && } /// - /// Gets the collection of associated with the specified . + /// Gets the collection of associated with the specified . /// public virtual IEnumerable this[ObjectId id] { @@ -100,8 +100,8 @@ public virtual IEnumerable this[ObjectId id] } /// - /// Gets the collection of associated with the specified namespace. - /// This is similar to the 'get notes list' command. + /// Gets the collection of associated with the specified namespace. + /// This is similar to the 'get notes list' command. /// public virtual IEnumerable this[string @namespace] { @@ -157,13 +157,13 @@ internal string UnCanonicalizeName(string name) } /// - /// Creates or updates a on the specified object, and for the given namespace. + /// Creates or updates a on the specified object, and for the given namespace. /// - /// The target , for which the note will be created. - /// The note message. - /// The author. - /// The committer. - /// The namespace on which the note will be created. It can be either a canonical namespace or an abbreviated namespace ('refs/notes/myNamespace' or just 'myNamespace'). + /// The target , for which the note will be created. + /// The note message. + /// The author. + /// The committer. + /// The namespace on which the note will be created. It can be either a canonical namespace or an abbreviated namespace ('refs/notes/myNamespace' or just 'myNamespace'). /// The note which was just saved. public virtual Note Add(ObjectId targetId, string message, Signature author, Signature committer, string @namespace) { @@ -183,12 +183,12 @@ public virtual Note Add(ObjectId targetId, string message, Signature author, Sig } /// - /// Deletes the note on the specified object, and for the given namespace. + /// Deletes the note on the specified object, and for the given namespace. /// - /// The target , for which the note will be created. - /// The author. - /// The committer. - /// The namespace on which the note will be removed. It can be either a canonical namespace or an abbreviated namespace ('refs/notes/myNamespace' or just 'myNamespace'). + /// The target , for which the note will be created. + /// The author. + /// The committer. + /// The namespace on which the note will be removed. It can be either a canonical namespace or an abbreviated namespace ('refs/notes/myNamespace' or just 'myNamespace'). public virtual void Remove(ObjectId targetId, Signature author, Signature committer, string @namespace) { Ensure.ArgumentNotNull(targetId, "targetId"); diff --git a/LibGit2Sharp/ObjectDatabase.cs b/LibGit2Sharp/ObjectDatabase.cs index 8b4795f19..ad2bf2591 100644 --- a/LibGit2Sharp/ObjectDatabase.cs +++ b/LibGit2Sharp/ObjectDatabase.cs @@ -10,8 +10,8 @@ namespace LibGit2Sharp { /// - /// Provides methods to directly work against the Git object database - /// without involving the index nor the working directory. + /// Provides methods to directly work against the Git object database + /// without involving the index nor the working directory. /// public class ObjectDatabase { @@ -19,7 +19,7 @@ public class ObjectDatabase private readonly ObjectDatabaseSafeHandle handle; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected ObjectDatabase() { } @@ -33,7 +33,7 @@ internal ObjectDatabase(Repository repo) } /// - /// Determines if the given object can be found in the object database. + /// Determines if the given object can be found in the object database. /// /// Identifier of the object being searched for. /// True if the object has been found; false otherwise. @@ -45,11 +45,11 @@ public virtual bool Contains(ObjectId objectId) } /// - /// Inserts a into the object database, created from the content of a file. + /// Inserts a into the object database, created from the content of a file. /// /// Path to the file to create the blob from. A relative path is allowed to - /// be passed if the is a standard, non-bare, repository. The path - /// will then be considered as a path relative to the root of the working directory. + /// be passed if the is a standard, non-bare, repository. The path + /// will then be considered as a path relative to the root of the working directory. /// The created . public virtual Blob CreateBlob(string path) { @@ -70,7 +70,7 @@ public virtual Blob CreateBlob(string path) } /// - /// Adds the provided backend to the object database with the specified priority. + /// Adds the provided backend to the object database with the specified priority. /// /// The backend to add /// The priority at which libgit2 should consult this backend (higher values are consulted first) @@ -84,17 +84,34 @@ public virtual void AddBackend(OdbBackend backend, int priority) private class Processor { - private readonly BinaryReader _reader; + private readonly Stream stream; + private readonly int? numberOfBytesToConsume; + private int totalNumberOfReadBytes; - public Processor(BinaryReader reader) + public Processor(Stream stream, int? numberOfBytesToConsume) { - _reader = reader; + this.stream = stream; + this.numberOfBytesToConsume = numberOfBytesToConsume; } public int Provider(IntPtr content, int max_length, IntPtr data) { var local = new byte[max_length]; - int numberOfReadBytes = _reader.Read(local, 0, max_length); + + int bytesToRead = max_length; + + if (numberOfBytesToConsume.HasValue) + { + int totalRemainingBytesToRead = numberOfBytesToConsume.Value - totalNumberOfReadBytes; + + if (totalRemainingBytesToRead < max_length) + { + bytesToRead = totalRemainingBytesToRead; + } + } + + int numberOfReadBytes = stream.Read(local, 0, bytesToRead); + totalNumberOfReadBytes += numberOfReadBytes; Marshal.Copy(local, 0, content, numberOfReadBytes); @@ -103,26 +120,46 @@ public int Provider(IntPtr content, int max_length, IntPtr data) } /// - /// Inserts a into the object database, created from the content of a data provider. + /// Inserts a into the object database, created from the content of a data provider. /// /// The reader that will provide the content of the blob to be created. /// The hintpath is used to determine what git filters should be applied to the object before it can be placed to the object database. /// The created . + [Obsolete("This method will be removed in the next release. Please use CreateBlob(Stream, string) instead.")] public virtual Blob CreateBlob(BinaryReader reader, string hintpath = null) { Ensure.ArgumentNotNull(reader, "reader"); - var proc = new Processor(reader); + return CreateBlob(reader.BaseStream, hintpath); + } + + /// + /// Inserts a into the object database, created from the content of a data provider. + /// + /// The stream from which will be read the content of the blob to be created. + /// The hintpath is used to determine what git filters should be applied to the object before it can be placed to the object database. + /// The number of bytes to consume from the stream. + /// The created . + public virtual Blob CreateBlob(Stream stream, string hintpath = null, int? numberOfBytesToConsume = null) + { + Ensure.ArgumentNotNull(stream, "stream"); + + if (!stream.CanRead) + { + throw new ArgumentException("The stream cannot be read from.", "stream"); + } + + var proc = new Processor(stream, numberOfBytesToConsume); ObjectId id = Proxy.git_blob_create_fromchunks(repo.Handle, hintpath, proc.Provider); return repo.Lookup(id); } /// - /// Inserts a into the object database, created from a . + /// Inserts a into the object database, created from a . /// - /// The . - /// The created . + /// The . + /// The created . public virtual Tree CreateTree(TreeDefinition treeDefinition) { Ensure.ArgumentNotNull(treeDefinition, "treeDefinition"); @@ -131,14 +168,14 @@ public virtual Tree CreateTree(TreeDefinition treeDefinition) } /// - /// Inserts a into the object database, referencing an existing . + /// Inserts a into the object database, referencing an existing . /// - /// The description of why a change was made to the repository. - /// The of who made the change. - /// The of who added the change to the repository. - /// The of the to be created. - /// The parents of the to be created. - /// The created . + /// The description of why a change was made to the repository. + /// The of who made the change. + /// The of who added the change to the repository. + /// The of the to be created. + /// The parents of the to be created. + /// The created . public virtual Commit CreateCommit(string message, Signature author, Signature committer, Tree tree, IEnumerable parents) { return CreateCommit(message, author, committer, tree, parents, null); @@ -153,7 +190,7 @@ internal Commit CreateCommit(string message, Signature author, Signature committ Ensure.ArgumentNotNull(parents, "parents"); string prettifiedMessage = Proxy.git_message_prettify(message); - IEnumerable parentIds = parents.Select(p => p.Id); + GitOid[] parentIds = parents.Select(p => p.Id.Oid).ToArray(); ObjectId commitId = Proxy.git_commit_create(repo.Handle, referenceName, author, committer, prettifiedMessage, tree, parentIds); @@ -161,14 +198,28 @@ internal Commit CreateCommit(string message, Signature author, Signature committ } /// - /// Inserts a into the object database, pointing to a specific . + /// Inserts a into the object database, pointing to a specific . /// /// The name. /// The being pointed at. /// The tagger. /// The message. - /// The created . + /// The created . + [Obsolete("This method will be removed in the next release. Please use CreateTagAnnontation(string, GitObject, Signature, string) instead.")] public virtual TagAnnotation CreateTag(string name, GitObject target, Signature tagger, string message) + { + return CreateTagAnnotation(name, target, tagger, message); + } + + /// + /// Inserts a into the object database, pointing to a specific . + /// + /// The name. + /// The being pointed at. + /// The tagger. + /// The message. + /// The created . + public virtual TagAnnotation CreateTagAnnotation(string name, GitObject target, Signature tagger, string message) { string prettifiedMessage = Proxy.git_message_prettify(message); diff --git a/LibGit2Sharp/ObjectId.cs b/LibGit2Sharp/ObjectId.cs index 38fc2a27b..d197e1525 100644 --- a/LibGit2Sharp/ObjectId.cs +++ b/LibGit2Sharp/ObjectId.cs @@ -6,7 +6,7 @@ namespace LibGit2Sharp { /// - /// Uniquely identifies a . + /// Uniquely identifies a . /// public class ObjectId : IEquatable { @@ -15,7 +15,7 @@ public class ObjectId : IEquatable private readonly string sha; /// - /// Size of the string-based representation of a SHA-1. + /// Size of the string-based representation of a SHA-1. /// protected const int HexSize = rawSize * 2; @@ -27,14 +27,14 @@ public class ObjectId : IEquatable new LambdaEqualityHelper(x => x.Sha); /// - /// Zero ObjectId + /// Zero ObjectId /// public static ObjectId Zero = new ObjectId(new string('0', HexSize)); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The oid. + /// The oid. internal ObjectId(GitOid oid) { this.oid = oid; @@ -42,9 +42,9 @@ internal ObjectId(GitOid oid) } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The byte array. + /// The byte array. public ObjectId(byte[] rawId) : this(new GitOid { Id = rawId }) { @@ -53,9 +53,9 @@ public ObjectId(byte[] rawId) } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The sha. + /// The sha. public ObjectId(string sha) { GitOid? parsedOid = BuildOidFrom(sha, true); @@ -75,7 +75,7 @@ internal GitOid Oid } /// - /// Gets the raw id. + /// Gets the raw id. /// public byte[] RawId { @@ -83,7 +83,7 @@ public byte[] RawId } /// - /// Gets the sha. + /// Gets the sha. /// public virtual string Sha { @@ -91,11 +91,11 @@ public virtual string Sha } /// - /// Converts the specified string representation of a Sha-1 to its equivalent and returns a value that indicates whether the conversion succeeded. + /// Converts the specified string representation of a Sha-1 to its equivalent and returns a value that indicates whether the conversion succeeded. /// - /// A string containing a Sha-1 to convert. - /// When this method returns, contains the value equivalent to the Sha-1 contained in , if the conversion succeeded, or null if the conversion failed. - /// true if the parameter was converted successfully; otherwise, false. + /// A string containing a Sha-1 to convert. + /// When this method returns, contains the value equivalent to the Sha-1 contained in , if the conversion succeeded, or null if the conversion failed. + /// true if the parameter was converted successfully; otherwise, false. public static bool TryParse(string sha, out ObjectId result) { result = BuildOidFrom(sha, false); @@ -114,27 +114,27 @@ public static bool TryParse(string sha, out ObjectId result) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as ObjectId); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(ObjectId other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -143,19 +143,19 @@ public override int GetHashCode() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// - /// The that represents the current . + /// The that represents the current . public override string ToString() { return Sha; } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// - /// The number of chars the should be truncated to. - /// The that represents the current . + /// The number of chars the should be truncated to. + /// The that represents the current . public string ToString(int prefixLength) { int normalizedLength = NormalizeLength(prefixLength); @@ -178,10 +178,10 @@ private static int NormalizeLength(int prefixLength) } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(ObjectId left, ObjectId right) { @@ -189,10 +189,10 @@ private static int NormalizeLength(int prefixLength) } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(ObjectId left, ObjectId right) { @@ -200,7 +200,7 @@ private static int NormalizeLength(int prefixLength) } /// - /// Create an for the given . + /// Create an for the given . /// /// The object SHA. /// An , or null if is null. diff --git a/LibGit2Sharp/ObjectType.cs b/LibGit2Sharp/ObjectType.cs index ac8402f6f..9b4e007d5 100644 --- a/LibGit2Sharp/ObjectType.cs +++ b/LibGit2Sharp/ObjectType.cs @@ -4,27 +4,27 @@ namespace LibGit2Sharp { /// - /// Underlying type of a + /// Underlying type of a /// public enum ObjectType { /// - /// A commit object. + /// A commit object. /// Commit = 1, /// - /// A tree (directory listing) object. + /// A tree (directory listing) object. /// Tree = 2, /// - /// A file revision object. + /// A file revision object. /// Blob = 3, /// - /// An annotated tag object. + /// An annotated tag object. /// Tag = 4, } diff --git a/LibGit2Sharp/OdbBackend.cs b/LibGit2Sharp/OdbBackend.cs index 5a2048690..593cd9230 100644 --- a/LibGit2Sharp/OdbBackend.cs +++ b/LibGit2Sharp/OdbBackend.cs @@ -6,12 +6,12 @@ namespace LibGit2Sharp { /// - /// Base class for all custom managed backends for the libgit2 object database (ODB). + /// Base class for all custom managed backends for the libgit2 object database (ODB). /// public abstract class OdbBackend { /// - /// Invoked by libgit2 when this backend is no longer needed. + /// Invoked by libgit2 when this backend is no longer needed. /// protected virtual void Dispose() { @@ -24,7 +24,7 @@ protected virtual void Dispose() } /// - /// In your subclass, override this member to provide the list of actions your backend supports. + /// In your subclass, override this member to provide the list of actions your backend supports. /// protected abstract OdbBackendOperations SupportedOperations { @@ -32,8 +32,8 @@ protected abstract OdbBackendOperations SupportedOperations } /// - /// Call this method from your implementations of Read and ReadPrefix to allocate a buffer in - /// which to return the object's data. + /// Call this method from your implementations of Read and ReadPrefix to allocate a buffer in + /// which to return the object's data. /// /// Number of bytes to allocate /// An Stream for you to write to and then return. Do not dispose this object before returning it. @@ -51,14 +51,14 @@ protected unsafe Stream Allocate(long bytes) } /// - /// Requests that this backend read an object. + /// Requests that this backend read an object. /// public abstract int Read(byte[] oid, out Stream data, out ObjectType objectType); /// - /// Requests that this backend read an object. The object ID may not be complete (may be a prefix). + /// Requests that this backend read an object. The object ID may not be complete (may be a prefix). /// public abstract int ReadPrefix(byte[] shortOid, out byte[] oid, @@ -66,15 +66,15 @@ public abstract int ReadPrefix(byte[] shortOid, out ObjectType objectType); /// - /// Requests that this backend read an object's header (length and object type) but not its contents. + /// Requests that this backend read an object's header (length and object type) but not its contents. /// public abstract int ReadHeader(byte[] oid, out int length, out ObjectType objectType); /// - /// Requests that this backend write an object to the backing store. The backend may need to compute the object ID - /// and return it to the caller. + /// Requests that this backend write an object to the backing store. The backend may need to compute the object ID + /// and return it to the caller. /// public abstract int Write(byte[] oid, Stream dataStream, @@ -83,31 +83,31 @@ public abstract int Write(byte[] oid, out byte[] finalOid); /// - /// Requests that this backend read an object. Returns a stream so that the caller can read the data in chunks. + /// Requests that this backend read an object. Returns a stream so that the caller can read the data in chunks. /// public abstract int ReadStream(byte[] oid, out OdbBackendStream stream); /// - /// Requests that this backend write an object to the backing store. Returns a stream so that the caller can write - /// the data in chunks. + /// Requests that this backend write an object to the backing store. Returns a stream so that the caller can write + /// the data in chunks. /// public abstract int WriteStream(long length, ObjectType objectType, out OdbBackendStream stream); /// - /// Requests that this backend check if an object ID exists. + /// Requests that this backend check if an object ID exists. /// public abstract bool Exists(byte[] oid); /// - /// Requests that this backend enumerate all items in the backing store. + /// Requests that this backend enumerate all items in the backing store. /// public abstract int ForEach(ForEachCallback callback); /// - /// The signature of the callback method provided to the Foreach method. + /// The signature of the callback method provided to the Foreach method. /// /// The object ID of the object in the backing store. /// A non-negative result indicates the enumeration should continue. Otherwise, the enumeration should stop. @@ -551,48 +551,48 @@ private int CallbackMethod(byte[] oid) } /// - /// Flags used by subclasses of OdbBackend to indicate which operations they support. + /// Flags used by subclasses of OdbBackend to indicate which operations they support. /// [Flags] protected enum OdbBackendOperations { /// - /// This OdbBackend declares that it supports the Read method. + /// This OdbBackend declares that it supports the Read method. /// Read = 1, /// - /// This OdbBackend declares that it supports the ReadPrefix method. + /// This OdbBackend declares that it supports the ReadPrefix method. /// ReadPrefix = 2, /// - /// This OdbBackend declares that it supports the ReadHeader method. + /// This OdbBackend declares that it supports the ReadHeader method. /// ReadHeader = 4, /// - /// This OdbBackend declares that it supports the Write method. + /// This OdbBackend declares that it supports the Write method. /// Write = 8, /// - /// This OdbBackend declares that it supports the ReadStream method. + /// This OdbBackend declares that it supports the ReadStream method. /// ReadStream = 16, /// - /// This OdbBackend declares that it supports the WriteStream method. + /// This OdbBackend declares that it supports the WriteStream method. /// WriteStream = 32, /// - /// This OdbBackend declares that it supports the Exists method. + /// This OdbBackend declares that it supports the Exists method. /// Exists = 64, /// - /// This OdbBackend declares that it supports the Foreach method. + /// This OdbBackend declares that it supports the Foreach method. /// ForEach = 128, } diff --git a/LibGit2Sharp/OdbBackendStream.cs b/LibGit2Sharp/OdbBackendStream.cs index b666ef72e..a1012f5f6 100644 --- a/LibGit2Sharp/OdbBackendStream.cs +++ b/LibGit2Sharp/OdbBackendStream.cs @@ -6,8 +6,8 @@ namespace LibGit2Sharp { /// - /// When an OdbBackend implements the WriteStream or ReadStream methods, it returns an OdbBackendStream to libgit2. - /// Libgit2 then uses the OdbBackendStream to read or write from the backend in a streaming fashion. + /// When an OdbBackend implements the WriteStream or ReadStream methods, it returns an OdbBackendStream to libgit2. + /// Libgit2 then uses the OdbBackendStream to read or write from the backend in a streaming fashion. /// public abstract class OdbBackendStream { @@ -30,7 +30,7 @@ protected OdbBackendStream(OdbBackend backend) } /// - /// Invoked by libgit2 when this stream is no longer needed. + /// Invoked by libgit2 when this stream is no longer needed. /// protected virtual void Dispose() { @@ -43,7 +43,7 @@ protected virtual void Dispose() } /// - /// If true, then it is legal to call the Read method. + /// If true, then it is legal to call the Read method. /// public abstract bool CanRead { @@ -51,7 +51,7 @@ public abstract bool CanRead } /// - /// If true, then it is legal to call the Write and FinalizeWrite methods. + /// If true, then it is legal to call the Write and FinalizeWrite methods. /// public abstract bool CanWrite { @@ -59,27 +59,27 @@ public abstract bool CanWrite } /// - /// Requests that the stream write the next length bytes of the stream to the provided Stream object. + /// Requests that the stream write the next length bytes of the stream to the provided Stream object. /// public abstract int Read( Stream dataStream, long length); /// - /// Requests that the stream write the first length bytes of the provided Stream object to the stream. + /// Requests that the stream write the first length bytes of the provided Stream object to the stream. /// public abstract int Write( Stream dataStream, long length); /// - /// After all bytes have been written to the stream, the object ID can be retrieved by calling FinalizeWrite. + /// After all bytes have been written to the stream, the object ID can be retrieved by calling FinalizeWrite. /// public abstract int FinalizeWrite( out byte[] oid); /// - /// The backend object this stream was created by. + /// The backend object this stream was created by. /// public virtual OdbBackend Backend { diff --git a/LibGit2Sharp/OrphanedHeadException.cs b/LibGit2Sharp/OrphanedHeadException.cs index 015dbfc40..aa5398bb6 100644 --- a/LibGit2Sharp/OrphanedHeadException.cs +++ b/LibGit2Sharp/OrphanedHeadException.cs @@ -4,43 +4,43 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when a operation requiring an existing - /// branch is performed against an unborn branch. + /// The exception that is thrown when a operation requiring an existing + /// branch is performed against an unborn branch. /// [Serializable] public class OrphanedHeadException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public OrphanedHeadException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public OrphanedHeadException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public OrphanedHeadException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected OrphanedHeadException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/Properties/AssemblyInfo.cs b/LibGit2Sharp/Properties/AssemblyInfo.cs index f3a5e7c25..3bc61373e 100644 --- a/LibGit2Sharp/Properties/AssemblyInfo.cs +++ b/LibGit2Sharp/Properties/AssemblyInfo.cs @@ -42,5 +42,5 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.12.0")] -[assembly: AssemblyFileVersion("0.12.0")] +[assembly: AssemblyVersion("0.13.0")] +[assembly: AssemblyFileVersion("0.13.0")] diff --git a/LibGit2Sharp/PushResult.cs b/LibGit2Sharp/PushResult.cs index 35dd59ca1..bf85e3ab8 100644 --- a/LibGit2Sharp/PushResult.cs +++ b/LibGit2Sharp/PushResult.cs @@ -3,18 +3,18 @@ namespace LibGit2Sharp { /// - /// Contains the results of a push operation. + /// Contains the results of a push operation. /// public class PushResult { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected PushResult() { } /// - /// s that failed to update. + /// s that failed to update. /// public virtual IEnumerable FailedPushUpdates { @@ -25,8 +25,8 @@ public virtual IEnumerable FailedPushUpdates } /// - /// Flag indicating if there were errors reported - /// when updating references on the remote. + /// Flag indicating if there were errors reported + /// when updating references on the remote. /// public virtual bool HasErrors { diff --git a/LibGit2Sharp/PushStatusError.cs b/LibGit2Sharp/PushStatusError.cs index 980f5a184..6675801a2 100644 --- a/LibGit2Sharp/PushStatusError.cs +++ b/LibGit2Sharp/PushStatusError.cs @@ -1,23 +1,23 @@ namespace LibGit2Sharp { /// - /// Information on an error updating reference on remote during a push. + /// Information on an error updating reference on remote during a push. /// public class PushStatusError { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected PushStatusError() { } /// - /// The reference this status refers to. + /// The reference this status refers to. /// public virtual string Reference { get; private set; } /// - /// The message regarding the update of this reference. + /// The message regarding the update of this reference. /// public virtual string Message { get; private set; } diff --git a/LibGit2Sharp/Reference.cs b/LibGit2Sharp/Reference.cs index 6ba98a11a..ac2bbcbe7 100644 --- a/LibGit2Sharp/Reference.cs +++ b/LibGit2Sharp/Reference.cs @@ -7,7 +7,7 @@ namespace LibGit2Sharp { /// - /// A Reference to another git object + /// A Reference to another git object /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public abstract class Reference : IEquatable @@ -19,13 +19,13 @@ public abstract class Reference : IEquatable private readonly string targetIdentifier; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Reference() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The canonical name. /// The target identifier. @@ -74,7 +74,7 @@ internal static T BuildFromPtr(ReferenceSafeHandle handle, Repository repo) w } /// - /// Gets the full name of this reference. + /// Gets the full name of this reference. /// public virtual string CanonicalName { @@ -82,17 +82,17 @@ public virtual string CanonicalName } /// - /// Recursively peels the target of the reference until a direct reference is encountered. + /// Recursively peels the target of the reference until a direct reference is encountered. /// - /// The this points to. + /// The this points to. public abstract DirectReference ResolveToDirectReference(); /// - /// Gets the target declared by the reference. - /// - /// If this reference is a , returns the canonical name of the target. - /// Otherwise, if this reference is a , returns the sha of the target. - /// + /// Gets the target declared by the reference. + /// + /// If this reference is a , returns the canonical name of the target. + /// Otherwise, if this reference is a , returns the sha of the target. + /// /// // TODO: Maybe find a better name for this property. public virtual string TargetIdentifier @@ -101,27 +101,27 @@ public virtual string TargetIdentifier } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Reference); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(Reference other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -130,10 +130,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(Reference left, Reference right) { @@ -141,10 +141,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(Reference left, Reference right) { @@ -152,9 +152,9 @@ public override int GetHashCode() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// - /// The that represents the current . + /// The that represents the current . public override string ToString() { return CanonicalName; diff --git a/LibGit2Sharp/ReferenceCollection.cs b/LibGit2Sharp/ReferenceCollection.cs index 76db39e7a..0841ec0b4 100644 --- a/LibGit2Sharp/ReferenceCollection.cs +++ b/LibGit2Sharp/ReferenceCollection.cs @@ -10,7 +10,7 @@ namespace LibGit2Sharp { /// - /// The Collection of references in a + /// The Collection of references in a /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class ReferenceCollection : IEnumerable @@ -18,25 +18,25 @@ public class ReferenceCollection : IEnumerable internal readonly Repository repo; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected ReferenceCollection() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The repo. + /// The repo. internal ReferenceCollection(Repository repo) { this.repo = repo; } /// - /// Gets the with the specified name. + /// Gets the with the specified name. /// - /// The canonical name of the reference to resolve. - /// The resolved if it has been found, null otherwise. + /// The canonical name of the reference to resolve. + /// The resolved if it has been found, null otherwise. public virtual Reference this[string name] { get { return Resolve(name); } @@ -45,9 +45,9 @@ public virtual Reference this[string name] #region IEnumerable Members /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { return Proxy.git_reference_list(repo.Handle) @@ -56,9 +56,9 @@ public virtual IEnumerator GetEnumerator() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); @@ -67,13 +67,13 @@ IEnumerator IEnumerable.GetEnumerator() #endregion /// - /// Creates a direct reference with the specified name and target + /// Creates a direct reference with the specified name and target /// - /// The canonical name of the reference to create. - /// Id of the target object. - /// True to allow silent overwriting a potentially existing reference, false otherwise. + /// The canonical name of the reference to create. + /// Id of the target object. + /// True to allow silent overwriting a potentially existing reference, false otherwise. /// The optional message to log in the when adding the - /// A new . + /// A new . public virtual DirectReference Add(string name, ObjectId targetId, bool allowOverwrite = false, string logMessage = null) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); @@ -90,13 +90,13 @@ public virtual DirectReference Add(string name, ObjectId targetId, bool allowOve } /// - /// Creates a symbolic reference with the specified name and target + /// Creates a symbolic reference with the specified name and target /// - /// The canonical name of the reference to create. - /// The target reference. - /// True to allow silent overwriting a potentially existing reference, false otherwise. + /// The canonical name of the reference to create. + /// The target reference. + /// True to allow silent overwriting a potentially existing reference, false otherwise. /// The optional message to log in the when adding the - /// A new . + /// A new . public virtual SymbolicReference Add(string name, Reference targetRef, bool allowOverwrite = false, string logMessage = null) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); @@ -113,9 +113,9 @@ public virtual SymbolicReference Add(string name, Reference targetRef, bool allo } /// - /// Remove a reference from the repository + /// Remove a reference from the repository /// - /// The reference to delete. + /// The reference to delete. public virtual void Remove(Reference reference) { Ensure.ArgumentNotNull(reference, "reference"); @@ -127,12 +127,12 @@ public virtual void Remove(Reference reference) } /// - /// Rename an existing reference with a new name + /// Rename an existing reference with a new name /// - /// The reference to rename. - /// The new canonical name. - /// True to allow silent overwriting a potentially existing reference, false otherwise. - /// A new . + /// The reference to rename. + /// The new canonical name. + /// True to allow silent overwriting a potentially existing reference, false otherwise. + /// A new . public virtual Reference Move(Reference reference, string newName, bool allowOverwrite = false) { Ensure.ArgumentNotNull(reference, "reference"); @@ -158,12 +158,12 @@ internal T Resolve(string name) where T : Reference } /// - /// Updates the target of a direct reference. + /// Updates the target of a direct reference. /// - /// The direct reference which target should be updated. - /// The new target. + /// The direct reference which target should be updated. + /// The new target. /// The optional message to log in the of the reference - /// A new . + /// A new . public virtual Reference UpdateTarget(Reference directRef, ObjectId targetId, string logMessage = null) { Ensure.ArgumentNotNull(directRef, "directRef"); @@ -178,12 +178,12 @@ public virtual Reference UpdateTarget(Reference directRef, ObjectId targetId, st } /// - /// Updates the target of a symbolic reference. + /// Updates the target of a symbolic reference. /// - /// The symbolic reference which target should be updated. - /// The new target. + /// The symbolic reference which target should be updated. + /// The new target. /// The optional message to log in the of the reference. - /// A new . + /// A new . public virtual Reference UpdateTarget(Reference symbolicRef, Reference targetRef, string logMessage = null) { Ensure.ArgumentNotNull(symbolicRef, "symbolicRef"); @@ -259,9 +259,9 @@ internal ReferenceSafeHandle RetrieveReferencePtr(string referenceName, bool sho } /// - /// Returns the list of references of the repository matching the specified . + /// Returns the list of references of the repository matching the specified . /// - /// The glob pattern the reference name should match. + /// The glob pattern the reference name should match. /// A list of references, ready to be enumerated. public virtual IEnumerable FromGlob(string pattern) { @@ -272,15 +272,15 @@ public virtual IEnumerable FromGlob(string pattern) } /// - /// Determines if the proposed reference name is well-formed. + /// Determines if the proposed reference name is well-formed. /// /// - /// - Top-level names must contain only capital letters and underscores, - /// and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). + /// - Top-level names must contain only capital letters and underscores, + /// and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). /// - /// - Names prefixed with "refs/" can be almost anything. You must avoid - /// the characters '~', '^', ':', '\\', '?', '[', and '*', and the - /// sequences ".." and "@{" which have special meaning to revparse. + /// - Names prefixed with "refs/" can be almost anything. You must avoid + /// the characters '~', '^', ':', '\\', '?', '[', and '*', and the + /// sequences ".." and "@{" which have special meaning to revparse. /// /// The name to be checked. /// true is the name is valid; false otherwise. @@ -290,11 +290,11 @@ public virtual bool IsValidName(string canonicalName) } /// - /// Shortcut to return the HEAD reference. + /// Shortcut to return the HEAD reference. /// /// - /// A if the HEAD is detached; - /// otherwise a . + /// A if the HEAD is detached; + /// otherwise a . /// public virtual Reference Head { @@ -311,7 +311,7 @@ private string DebuggerDisplay } /// - /// Returns as a the reflog of the named + /// Returns as a the reflog of the named /// /// The canonical name of the reference /// a , enumerable of @@ -323,7 +323,7 @@ public virtual ReflogCollection Log(string canonicalName) } /// - /// Returns as a the reflog of the + /// Returns as a the reflog of the /// /// The reference /// a , enumerable of @@ -333,5 +333,43 @@ public virtual ReflogCollection Log(Reference reference) return new ReflogCollection(repo, reference.CanonicalName); } + + /// + /// Rewrite some of the commits in the repository and all the references that can reach them. + /// + /// The objects to rewrite. + /// Visitor for rewriting commit metadata. + /// Visitor for rewriting commit trees. + /// Visitor for renaming tags. This is called with (OldTag.Name, OldTag.IsAnnotated, OldTarget). + /// Visitor for mangling parent links. + /// Namespace where to store the rewritten references (defaults to "refs/original/") + public virtual void RewriteHistory( + IEnumerable commitsToRewrite, + Func commitHeaderRewriter = null, + Func commitTreeRewriter = null, + Func tagNameRewriter = null, + Func, IEnumerable> commitParentsRewriter = null, + string backupRefsNamespace = "refs/original/") + { + Ensure.ArgumentNotNull(commitsToRewrite, "commitsToRewrite"); + Ensure.ArgumentNotNullOrEmptyString(backupRefsNamespace, "backupRefsNamespace"); + + if (!backupRefsNamespace.EndsWith("/")) + { + backupRefsNamespace += "/"; + } + + IList originalRefs = this.ToList(); + if (originalRefs.Count == 0) + { + // Nothing to do + return; + } + + var historyRewriter = new HistoryRewriter(repo, commitsToRewrite, commitHeaderRewriter, commitTreeRewriter, + commitParentsRewriter, tagNameRewriter, backupRefsNamespace); + + historyRewriter.Execute(); + } } } diff --git a/LibGit2Sharp/ReferenceCollectionExtensions.cs b/LibGit2Sharp/ReferenceCollectionExtensions.cs index 15cbaa50d..ecd37b458 100644 --- a/LibGit2Sharp/ReferenceCollectionExtensions.cs +++ b/LibGit2Sharp/ReferenceCollectionExtensions.cs @@ -1,12 +1,14 @@ using System; +using System.Collections.Generic; using System.Globalization; +using System.Linq; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Handles; namespace LibGit2Sharp { /// - /// Provides helper overloads to a . + /// Provides helper overloads to a . /// public static class ReferenceCollectionExtensions { @@ -31,14 +33,14 @@ private static RefState TryResolveReference(out Reference reference, ReferenceCo } /// - /// Creates a direct or symbolic reference with the specified name and target + /// Creates a direct or symbolic reference with the specified name and target /// - /// The name of the reference to create. - /// The target which can be either the canonical name of a reference or a revparse spec. - /// True to allow silent overwriting a potentially existing reference, false otherwise. - /// The being worked with. + /// The name of the reference to create. + /// The target which can be either the canonical name of a reference or a revparse spec. + /// True to allow silent overwriting a potentially existing reference, false otherwise. + /// The being worked with. /// The optional message to log in the when adding the - /// A new . + /// A new . public static Reference Add(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, bool allowOverwrite = false, string logMessage = null) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); @@ -67,13 +69,13 @@ public static Reference Add(this ReferenceCollection refsColl, string name, stri return refsColl.Add(name, gitObject.Id, allowOverwrite, logMessage); } /// - /// Updates the target of a direct reference. + /// Updates the target of a direct reference. /// - /// The direct reference which target should be updated. - /// The revparse spec of the target. - /// The being worked with. + /// The direct reference which target should be updated. + /// The revparse spec of the target. + /// The being worked with. /// The optional message to log in the of the reference. - /// A new . + /// A new . public static Reference UpdateTarget(this ReferenceCollection refsColl, Reference directRef, string objectish, string logMessage = null) { Ensure.ArgumentNotNull(directRef, "directRef"); @@ -87,13 +89,13 @@ public static Reference UpdateTarget(this ReferenceCollection refsColl, Referenc } /// - /// Rename an existing reference with a new name + /// Rename an existing reference with a new name /// - /// The canonical name of the reference to rename. - /// The new canonical name. - /// True to allow silent overwriting a potentially existing reference, false otherwise. - /// The being worked with. - /// A new . + /// The canonical name of the reference to rename. + /// The new canonical name. + /// True to allow silent overwriting a potentially existing reference, false otherwise. + /// The being worked with. + /// A new . public static Reference Move(this ReferenceCollection refsColl, string currentName, string newName, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(currentName, "currentName"); @@ -111,13 +113,13 @@ public static Reference Move(this ReferenceCollection refsColl, string currentNa } /// - /// Updates the target of a reference. + /// Updates the target of a reference. /// - /// The canonical name of the reference. - /// The target which can be either the canonical name of a reference or a revparse spec. - /// The being worked with. + /// The canonical name of the reference. + /// The target which can be either the canonical name of a reference or a revparse spec. + /// The being worked with. /// The optional message to log in the of the reference. - /// A new . + /// A new . public static Reference UpdateTarget(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, string logMessage = null) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); @@ -155,10 +157,10 @@ public static Reference UpdateTarget(this ReferenceCollection refsColl, string n } /// - /// Delete a reference with the specified name + /// Delete a reference with the specified name /// - /// The being worked with. - /// The canonical name of the reference to delete. + /// The being worked with. + /// The canonical name of the reference to delete. public static void Remove(this ReferenceCollection refsColl, string name) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); @@ -172,5 +174,68 @@ public static void Remove(this ReferenceCollection refsColl, string name) refsColl.Remove(reference); } + + /// + /// Find the s among + /// that can reach at least one in the specified . + /// + /// The being worked with. + /// The set of s to examine. + /// The set of s that are interesting. + /// A subset of that can reach at least one within . + public static IEnumerable ReachableFrom( + this ReferenceCollection refsColl, + IEnumerable refSubset, + IEnumerable targets) + { + Ensure.ArgumentNotNull(refSubset, "refSubset"); + Ensure.ArgumentNotNull(targets, "targets"); + + var refs = new List(refSubset); + if (refs.Count == 0) + { + return Enumerable.Empty(); + } + + var targetsSet = new HashSet(targets); + if (targetsSet.Count == 0) + { + return Enumerable.Empty(); + } + + var allCommits = refsColl.repo.Commits; + + var result = new List(); + + foreach (var reference in refs) + { + foreach (var commit in allCommits.QueryBy(new CommitFilter { Since = reference })) + { + if (!targetsSet.Contains(commit)) + { + continue; + } + + result.Add(reference); + break; + } + } + + return result; + } + + /// + /// Find the s + /// that can reach at least one in the specified . + /// + /// The being worked with. + /// The set of s that are interesting. + /// The list of that can reach at least one within . + public static IEnumerable ReachableFrom( + this ReferenceCollection refsColl, + IEnumerable targets) + { + return ReachableFrom(refsColl, refsColl, targets); + } } } diff --git a/LibGit2Sharp/ReferenceExtensions.cs b/LibGit2Sharp/ReferenceExtensions.cs index ebf12f8d1..8b33e1618 100644 --- a/LibGit2Sharp/ReferenceExtensions.cs +++ b/LibGit2Sharp/ReferenceExtensions.cs @@ -3,7 +3,7 @@ namespace LibGit2Sharp { /// - /// Provides helpers to a . + /// Provides helpers to a . /// public static class ReferenceExtensions { @@ -33,7 +33,7 @@ private static bool IsPrefixedBy(this string input, string prefix) } /// - /// Determine if the current is a local branch. + /// Determine if the current is a local branch. /// /// The to test. /// true if the current is a local branch, false otherwise. @@ -43,7 +43,7 @@ public static bool IsLocalBranch(this Reference reference) } /// - /// Determine if the current is a remote tracking branch. + /// Determine if the current is a remote tracking branch. /// /// The to test. /// true if the current is a remote tracking branch, false otherwise. @@ -53,7 +53,7 @@ public static bool IsRemoteTrackingBranch(this Reference reference) } /// - /// Determine if the current is a tag. + /// Determine if the current is a tag. /// /// The to test. /// true if the current is a tag, false otherwise. @@ -63,7 +63,7 @@ public static bool IsTag(this Reference reference) } /// - /// Determine if the current is a note. + /// Determine if the current is a note. /// /// The to test. /// true if the current is a note, false otherwise. diff --git a/LibGit2Sharp/ReferenceWrapper.cs b/LibGit2Sharp/ReferenceWrapper.cs index 25a9eda88..4a6eeb7ab 100644 --- a/LibGit2Sharp/ReferenceWrapper.cs +++ b/LibGit2Sharp/ReferenceWrapper.cs @@ -7,14 +7,14 @@ namespace LibGit2Sharp { /// - /// A base class for things that wrap a (branch, tag, etc). + /// A base class for things that wrap a (branch, tag, etc). /// /// The type of the referenced Git object. [DebuggerDisplay("{DebuggerDisplay,nq}")] public abstract class ReferenceWrapper : IEquatable> where TObject : GitObject { /// - /// The repository. + /// The repository. /// protected readonly Repository repo; private readonly Lazy objectBuilder; @@ -25,7 +25,7 @@ public abstract class ReferenceWrapper : IEquatable - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected ReferenceWrapper() { } @@ -45,7 +45,7 @@ protected internal ReferenceWrapper(Repository repo, Reference reference, Func - /// Gets the full name of this reference. + /// Gets the full name of this reference. /// public virtual string CanonicalName { @@ -53,7 +53,7 @@ public virtual string CanonicalName } /// - /// Gets the name of this reference. + /// Gets the name of this reference. /// public virtual string Name { @@ -61,16 +61,16 @@ public virtual string Name } /// - /// Returns the , a representation of the current reference. + /// Returns the , a representation of the current reference. /// - /// The that represents the current reference. + /// The that represents the current reference. public override string ToString() { return CanonicalName; } /// - /// Gets the this points to. + /// Gets the this points to. /// protected TObject TargetObject { @@ -78,8 +78,8 @@ protected TObject TargetObject } /// - /// Removes redundent leading namespaces (regarding the kind of - /// reference being wrapped) from the canonical name. + /// Removes redundent leading namespaces (regarding the kind of + /// reference being wrapped) from the canonical name. /// /// The friendly shortened name protected abstract string Shorten(); @@ -102,27 +102,27 @@ private TObject RetrieveTargetObject(Reference reference) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(ReferenceWrapper other) { return equalityHelper.Equals(this, other); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as ReferenceWrapper); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -131,10 +131,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(ReferenceWrapper left, ReferenceWrapper right) { @@ -142,10 +142,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(ReferenceWrapper left, ReferenceWrapper right) { diff --git a/LibGit2Sharp/ReflogCollection.cs b/LibGit2Sharp/ReflogCollection.cs index e2bfa3c3d..f9f9516b5 100644 --- a/LibGit2Sharp/ReflogCollection.cs +++ b/LibGit2Sharp/ReflogCollection.cs @@ -10,8 +10,8 @@ namespace LibGit2Sharp { /// - /// The is the reflog of a given , as a enumerable of . - /// Reflog is a mechanism to record when the tip of a is updated. + /// The is the reflog of a given , as a enumerable of . + /// Reflog is a mechanism to record when the tip of a is updated. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class ReflogCollection : IEnumerable @@ -21,15 +21,15 @@ public class ReflogCollection : IEnumerable private readonly string canonicalName; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected ReflogCollection() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The repo. + /// The repo. /// the canonical name of the to retrieve reflog entries on. internal ReflogCollection(Repository repo, string canonicalName) { @@ -43,12 +43,12 @@ internal ReflogCollection(Repository repo, string canonicalName) #region Implementation of IEnumerable /// - /// Returns an enumerator that iterates through the collection. - /// - /// The enumerator returns the by descending order (last reflog entry is returned first). - /// + /// Returns an enumerator that iterates through the collection. + /// + /// The enumerator returns the by descending order (last reflog entry is returned first). + /// /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public IEnumerator GetEnumerator() { var entries = new List(); @@ -69,9 +69,9 @@ public IEnumerator GetEnumerator() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); @@ -89,8 +89,8 @@ private string DebuggerDisplay } /// - /// Add a new to the current . It will be created as first item of the collection - /// The native reflog object will be saved right after inserting the entry. + /// Add a new to the current . It will be created as first item of the collection + /// The native reflog object will be saved right after inserting the entry. /// /// the of the new target the will point out to. /// the message associated with the new . @@ -106,11 +106,11 @@ internal virtual void Append(ObjectId target, string reflogMessage, Signature co } /// - /// Add a new to the current . It will be created as first item of the collection - /// The native reflog object will be saved right after inserting the entry. - /// - /// The will be built from the current Git configuration. - /// + /// Add a new to the current . It will be created as first item of the collection + /// The native reflog object will be saved right after inserting the entry. + /// + /// The will be built from the current Git configuration. + /// /// /// the of the new target the will point out to. /// the message associated with the new . diff --git a/LibGit2Sharp/ReflogEntry.cs b/LibGit2Sharp/ReflogEntry.cs index d9f53170f..def2e0b3e 100644 --- a/LibGit2Sharp/ReflogEntry.cs +++ b/LibGit2Sharp/ReflogEntry.cs @@ -4,8 +4,8 @@ namespace LibGit2Sharp { /// - /// As single entry of a - /// a describes one single update on a particular reference + /// As single entry of a + /// a describes one single update on a particular reference /// public class ReflogEntry { @@ -15,13 +15,13 @@ public class ReflogEntry private readonly string message; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected ReflogEntry() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// a to the reflog entry public ReflogEntry(SafeHandle entryHandle) @@ -33,7 +33,7 @@ public ReflogEntry(SafeHandle entryHandle) } /// - /// targeted before the reference update described by this + /// targeted before the reference update described by this /// public virtual ObjectId From { @@ -41,7 +41,7 @@ public virtual ObjectId From } /// - /// targeted after the reference update described by this + /// targeted after the reference update described by this /// public virtual ObjectId To { @@ -49,7 +49,7 @@ public virtual ObjectId To } /// - /// of the commiter of this reference update + /// of the commiter of this reference update /// public virtual Signature Commiter { @@ -57,7 +57,7 @@ public virtual Signature Commiter } /// - /// the message assiocated to this reference update + /// the message assiocated to this reference update /// public virtual string Message { diff --git a/LibGit2Sharp/Remote.cs b/LibGit2Sharp/Remote.cs index 8c402fe35..7feb1357c 100644 --- a/LibGit2Sharp/Remote.cs +++ b/LibGit2Sharp/Remote.cs @@ -7,7 +7,7 @@ namespace LibGit2Sharp { /// - /// A remote repository whose branches are tracked. + /// A remote repository whose branches are tracked. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class Remote : IEquatable @@ -18,40 +18,47 @@ public class Remote : IEquatable private readonly Repository repository; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Remote() { } - private Remote(Repository repository, string name, string url) + private Remote(Repository repository, string name, string url, TagFetchMode tagFetchMode) { this.repository = repository; Name = name; Url = url; + TagFetchMode = tagFetchMode; } internal static Remote BuildFromPtr(RemoteSafeHandle handle, Repository repo) { string name = Proxy.git_remote_name(handle); string url = Proxy.git_remote_url(handle); + TagFetchMode tagFetchMode = Proxy.git_remote_autotag(handle); - var remote = new Remote(repo, name, url); + var remote = new Remote(repo, name, url, tagFetchMode); return remote; } /// - /// Gets the alias of this remote repository. + /// Gets the alias of this remote repository. /// public virtual string Name { get; private set; } /// - /// Gets the url to use to communicate with this remote repository. + /// Gets the url to use to communicate with this remote repository. /// public virtual string Url { get; private set; } /// - /// Transform a reference to its source reference using the 's default fetchspec. + /// Gets the Tag Fetch Mode of the remote - indicating how tags are fetched. + /// + public virtual TagFetchMode TagFetchMode { get; private set; } + + /// + /// Transform a reference to its source reference using the 's default fetchspec. /// /// The reference to transform. /// The transformed reference. @@ -65,27 +72,27 @@ internal string FetchSpecTransformToSource(string reference) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Remote); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(Remote other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -94,10 +101,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(Remote left, Remote right) { @@ -105,10 +112,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(Remote left, Remote right) { diff --git a/LibGit2Sharp/RemoteCallbacks.cs b/LibGit2Sharp/RemoteCallbacks.cs index 3cc40cfae..3427e634a 100644 --- a/LibGit2Sharp/RemoteCallbacks.cs +++ b/LibGit2Sharp/RemoteCallbacks.cs @@ -5,10 +5,10 @@ namespace LibGit2Sharp { /// - /// Class to translate libgit2 callbacks into delegates exposed by LibGit2Sharp. - /// Handles generating libgit2 git_remote_callbacks datastructure given a set - /// of LibGit2Sharp delegates and handles propagating libgit2 callbacks into - /// corresponding LibGit2Sharp exposed delegates. + /// Class to translate libgit2 callbacks into delegates exposed by LibGit2Sharp. + /// Handles generating libgit2 git_remote_callbacks datastructure given a set + /// of LibGit2Sharp delegates and handles propagating libgit2 callbacks into + /// corresponding LibGit2Sharp exposed delegates. /// internal class RemoteCallbacks { @@ -22,17 +22,17 @@ internal RemoteCallbacks(ProgressHandler onProgress = null, CompletionHandler on #region Delegates /// - /// Progress callback. Corresponds to libgit2 progress callback. + /// Progress callback. Corresponds to libgit2 progress callback. /// private readonly ProgressHandler Progress; /// - /// UpdateTips callback. Corresponds to libgit2 update_tips callback. + /// UpdateTips callback. Corresponds to libgit2 update_tips callback. /// private readonly UpdateTipsHandler UpdateTips; /// - /// Completion callback. Corresponds to libgit2 Completion callback. + /// Completion callback. Corresponds to libgit2 Completion callback. /// private readonly CompletionHandler Completion; @@ -40,7 +40,7 @@ internal RemoteCallbacks(ProgressHandler onProgress = null, CompletionHandler on internal GitRemoteCallbacks GenerateCallbacks() { - GitRemoteCallbacks callbacks = new GitRemoteCallbacks {version = 1}; + var callbacks = new GitRemoteCallbacks {version = 1}; if (Progress != null) { @@ -63,13 +63,13 @@ internal GitRemoteCallbacks GenerateCallbacks() #region Handlers to respond to callbacks raised by libgit2 /// - /// Handler for libgit2 Progress callback. Converts values - /// received from libgit2 callback to more suitable types - /// and calls delegate provided by LibGit2Sharp consumer. + /// Handler for libgit2 Progress callback. Converts values + /// received from libgit2 callback to more suitable types + /// and calls delegate provided by LibGit2Sharp consumer. /// /// IntPtr to string from libgit2 /// length of string - /// + /// IntPtr to optional payload passed back to the callback. private void GitProgressHandler(IntPtr str, int len, IntPtr data) { ProgressHandler onProgress = Progress; @@ -82,15 +82,15 @@ private void GitProgressHandler(IntPtr str, int len, IntPtr data) } /// - /// Handler for libgit2 update_tips callback. Converts values - /// received from libgit2 callback to more suitable types - /// and calls delegate provided by LibGit2Sharp consumer. + /// Handler for libgit2 update_tips callback. Converts values + /// received from libgit2 callback to more suitable types + /// and calls delegate provided by LibGit2Sharp consumer. /// /// IntPtr to string /// Old reference ID /// New referene ID - /// - /// + /// IntPtr to optional payload passed back to the callback. + /// 0 on success; a negative value to abort the process. private int GitUpdateTipsHandler(IntPtr str, ref GitOid oldId, ref GitOid newId, IntPtr data) { UpdateTipsHandler onUpdateTips = UpdateTips; @@ -106,13 +106,13 @@ private int GitUpdateTipsHandler(IntPtr str, ref GitOid oldId, ref GitOid newId, } /// - /// Handler for libgit2 completion callback. Converts values - /// received from libgit2 callback to more suitable types - /// and calls delegate provided by LibGit2Sharp consumer. + /// Handler for libgit2 completion callback. Converts values + /// received from libgit2 callback to more suitable types + /// and calls delegate provided by LibGit2Sharp consumer. /// - /// - /// - /// + /// Which operation completed. + /// IntPtr to optional payload passed back to the callback. + /// 0 on success; a negative value to abort the process. private int GitCompletionHandler(RemoteCompletionType remoteCompletionType, IntPtr data) { CompletionHandler completion = Completion; diff --git a/LibGit2Sharp/RemoteCollection.cs b/LibGit2Sharp/RemoteCollection.cs index 05715fb7d..cef32f094 100644 --- a/LibGit2Sharp/RemoteCollection.cs +++ b/LibGit2Sharp/RemoteCollection.cs @@ -1,4 +1,5 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -9,7 +10,7 @@ namespace LibGit2Sharp { /// - /// The collection of in a + /// The collection of in a /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class RemoteCollection : IEnumerable @@ -17,7 +18,7 @@ public class RemoteCollection : IEnumerable private readonly Repository repository; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected RemoteCollection() { } @@ -28,10 +29,10 @@ internal RemoteCollection(Repository repository) } /// - /// Gets the with the specified name. + /// Gets the with the specified name. /// - /// The name of the remote to retrieve. - /// The retrived if it has been found, null otherwise. + /// The name of the remote to retrieve. + /// The retrived if it has been found, null otherwise. public virtual Remote this[string name] { get { return RemoteForName(name, false); } @@ -48,9 +49,27 @@ internal Remote RemoteForName(string name, bool shouldThrowIfNotFound = true) } /// - /// Returns an enumerator that iterates through the collection. + /// Update properties of a remote. /// - /// An object that can be used to iterate through the collection. + /// The remote to update. + /// Delegate to perform updates on the remote. + /// The updated remote. + public virtual Remote Update(Remote remote, params Action[] actions) + { + var updater = new RemoteUpdater(this.repository, remote); + + foreach (Action action in actions) + { + action(updater); + } + + return this[remote.Name]; + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { return Proxy @@ -60,23 +79,23 @@ public virtual IEnumerator GetEnumerator() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// - /// Creates a with the specified name and for the repository at the specified location. - /// - /// A default fetch refspec will be added for this remote. - /// + /// Creates a with the specified name and for the repository at the specified location. + /// + /// A default fetch refspec will be added for this remote. + /// /// - /// The name of the remote to create. - /// The location of the repository. - /// A new . + /// The name of the remote to create. + /// The location of the repository. + /// A new . public virtual Remote Add(string name, string url) { Ensure.ArgumentNotNull(name, "name"); @@ -89,12 +108,12 @@ public virtual Remote Add(string name, string url) } /// - /// Creates a with the specified name and for the repository at the specified location. + /// Creates a with the specified name and for the repository at the specified location. /// - /// The name of the remote to create. - /// The location of the repository. - /// The refSpec to be used when fetching from this remote. - /// A new . + /// The name of the remote to create. + /// The location of the repository. + /// The refSpec to be used when fetching from this remote. + /// A new . public virtual Remote Add(string name, string url, string fetchRefSpec) { Ensure.ArgumentNotNull(name, "name"); @@ -110,7 +129,7 @@ public virtual Remote Add(string name, string url, string fetchRefSpec) } /// - /// Determines if the proposed remote name is well-formed. + /// Determines if the proposed remote name is well-formed. /// /// The name to be checked. /// true is the name is valid; false otherwise. diff --git a/LibGit2Sharp/RemoteCompletionType.cs b/LibGit2Sharp/RemoteCompletionType.cs index 8e48e161e..9fb6c4406 100644 --- a/LibGit2Sharp/RemoteCompletionType.cs +++ b/LibGit2Sharp/RemoteCompletionType.cs @@ -1,22 +1,22 @@ namespace LibGit2Sharp { /// - /// git_remote_completion types. + /// git_remote_completion types. /// public enum RemoteCompletionType { /// - /// Download. + /// Download. /// Download = 0, /* GIT_REMOTE_COMPLETION_DOWNLOAD */ /// - /// Indexing. + /// Indexing. /// Indexing, /* GIT_REMOTE_COMPLETION_INDEXING */ /// - /// Error. + /// Error. /// Error, /* GIT_REMOTE_COMPLETION_ERROR */ } diff --git a/LibGit2Sharp/RemoteUpdater.cs b/LibGit2Sharp/RemoteUpdater.cs new file mode 100644 index 000000000..c0814e7c8 --- /dev/null +++ b/LibGit2Sharp/RemoteUpdater.cs @@ -0,0 +1,44 @@ +using LibGit2Sharp.Core; +using LibGit2Sharp.Core.Handles; + +namespace LibGit2Sharp +{ + /// + /// Exposes properties of a remote that can be updated. + /// + public class RemoteUpdater + { + private readonly Repository repo; + private readonly Remote remote; + + /// + /// Needed for mocking purposes. + /// + protected RemoteUpdater() + { } + + internal RemoteUpdater(Repository repo, Remote remote) + { + Ensure.ArgumentNotNull(repo, "repo"); + Ensure.ArgumentNotNull(remote, "remote"); + + this.repo = repo; + this.remote = remote; + } + + /// + /// Set the default TagFetchMode value for the remote. + /// + public virtual TagFetchMode TagFetchMode + { + set + { + using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repo.Handle, remote.Name, true)) + { + Proxy.git_remote_set_autotag(remoteHandle, value); + Proxy.git_remote_save(remoteHandle); + } + } + } + } +} diff --git a/LibGit2Sharp/RemoveFromIndexException.cs b/LibGit2Sharp/RemoveFromIndexException.cs index deb044b70..7e138120a 100644 --- a/LibGit2Sharp/RemoveFromIndexException.cs +++ b/LibGit2Sharp/RemoveFromIndexException.cs @@ -5,42 +5,42 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when a file cannot be removed from the index. + /// The exception that is thrown when a file cannot be removed from the index. /// [Serializable] public class RemoveFromIndexException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public RemoveFromIndexException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public RemoveFromIndexException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public RemoveFromIndexException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected RemoveFromIndexException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index 57cabb2e8..715b142e3 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -14,7 +14,7 @@ namespace LibGit2Sharp { /// - /// A Repository is the primary interface into a git repository + /// A Repository is the primary interface into a git repository /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class Repository : IRepository @@ -40,15 +40,15 @@ public class Repository : IRepository private readonly Lazy pathCase; /// - /// Initializes a new instance of the class, providing ooptional behavioral overrides through parameter. - /// For a standard repository, should either point to the ".git" folder or to the working directory. For a bare repository, should directly point to the repository folder. + /// Initializes a new instance of the class, providing ooptional behavioral overrides through parameter. + /// For a standard repository, should either point to the ".git" folder or to the working directory. For a bare repository, should directly point to the repository folder. /// - /// - /// The path to the git repository to open, can be either the path to the git directory (for non-bare repositories this - /// would be the ".git" folder inside the working directory) or the path to the working directory. + /// + /// The path to the git repository to open, can be either the path to the git directory (for non-bare repositories this + /// would be the ".git" folder inside the working directory) or the path to the working directory. /// /// - /// Overrides to the way a repository is opened. + /// Overrides to the way a repository is opened. /// public Repository(string path, RepositoryOptions options = null) { @@ -129,11 +129,11 @@ public Repository(string path, RepositoryOptions options = null) } /// - /// Check if parameter leads to a valid git repository. + /// Check if parameter leads to a valid git repository. /// - /// - /// The path to the git repository to check, can be either the path to the git directory (for non-bare repositories this - /// would be the ".git" folder inside the working directory) or the path to the working directory. + /// + /// The path to the git repository to check, can be either the path to the git directory (for non-bare repositories this + /// would be the ".git" folder inside the working directory) or the path to the working directory. /// /// True if a repository can be resolved through this path; false otherwise static public bool IsValid(string path) @@ -181,9 +181,8 @@ internal RepositorySafeHandle Handle } /// - /// Shortcut to return the branch pointed to by HEAD + /// Shortcut to return the branch pointed to by HEAD /// - /// public Branch Head { get @@ -205,7 +204,7 @@ public Branch Head } /// - /// Provides access to the configuration settings for this repository. + /// Provides access to the configuration settings for this repository. /// public Configuration Config { @@ -213,7 +212,7 @@ public Configuration Config } /// - /// Gets the index. + /// Gets the index. /// public Index Index { @@ -229,19 +228,7 @@ public Index Index } /// - /// Gets the conflicts that exist. - /// - [Obsolete("This property will be removed in the next release. Please use Index.Conflicts instead.")] - public ConflictCollection Conflicts - { - get - { - return Index.Conflicts; - } - } - - /// - /// Manipulate the currently ignored files. + /// Manipulate the currently ignored files. /// public Ignore Ignore { @@ -252,7 +239,7 @@ public Ignore Ignore } /// - /// Provides access to network functionality for a repository. + /// Provides access to network functionality for a repository. /// public Network Network { @@ -263,7 +250,7 @@ public Network Network } /// - /// Gets the database. + /// Gets the database. /// public ObjectDatabase ObjectDatabase { @@ -274,7 +261,7 @@ public ObjectDatabase ObjectDatabase } /// - /// Lookup and enumerate references in the repository. + /// Lookup and enumerate references in the repository. /// public ReferenceCollection Refs { @@ -282,8 +269,8 @@ public ReferenceCollection Refs } /// - /// Lookup and enumerate commits in the repository. - /// Iterating this collection directly starts walking from the HEAD. + /// Lookup and enumerate commits in the repository. + /// Iterating this collection directly starts walking from the HEAD. /// public IQueryableCommitLog Commits { @@ -291,7 +278,7 @@ public IQueryableCommitLog Commits } /// - /// Lookup and enumerate branches in the repository. + /// Lookup and enumerate branches in the repository. /// public BranchCollection Branches { @@ -299,7 +286,7 @@ public BranchCollection Branches } /// - /// Lookup and enumerate tags in the repository. + /// Lookup and enumerate tags in the repository. /// public TagCollection Tags { @@ -315,7 +302,7 @@ public StashCollection Stashes } /// - /// Provides high level information about this repository. + /// Provides high level information about this repository. /// public RepositoryInformation Info { @@ -323,7 +310,7 @@ public RepositoryInformation Info } /// - /// 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. + /// 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. /// public Diff Diff { @@ -331,7 +318,7 @@ public Diff Diff } /// - /// Lookup notes in the repository. + /// Lookup notes in the repository. /// public NoteCollection Notes { @@ -339,7 +326,7 @@ public NoteCollection Notes } /// - /// Submodules in the repository. + /// Submodules in the repository. /// public SubmoduleCollection Submodules { @@ -349,7 +336,7 @@ public SubmoduleCollection Submodules #region IDisposable Members /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { @@ -358,7 +345,7 @@ public void Dispose() } /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// protected virtual void Dispose(bool disposing) { @@ -368,60 +355,99 @@ protected virtual void Dispose(bool disposing) #endregion /// - /// Initialize a repository at the specified . + /// Initialize a repository at the specified . /// - /// The path to the working folder when initializing a standard ".git" repository. Otherwise, when initializing a bare repository, the path to the expected location of this later. - /// true to initialize a bare repository. False otherwise, to initialize a standard ".git" repository. + /// 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. /// Overrides to the way a repository is opened. - /// a new instance of the class. The client code is responsible for calling on this instance. - public static Repository Init(string path, bool isBare = false, RepositoryOptions options = null) + /// a new instance of the class. The client code is responsible for calling on this instance. + [Obsolete("This method will be removed in the next release. Please use Init(string, bool) instead.")] + public static Repository Init(string path, bool isBare, RepositoryOptions options) + { + string gitDirPath = Init(path, isBare); + + return new Repository(gitDirPath, options); + } + + /// + /// Initialize a repository at the specified . + /// + /// The path to the working folder when initializing a standard ".git" repository. Otherwise, when initializing a bare repository, the path to the expected location of this later. + /// true to initialize a bare repository. False otherwise, to initialize a standard ".git" repository. + /// The path to the created repository. + public static string Init(string path, bool isBare = false) { Ensure.ArgumentNotNullOrEmptyString(path, "path"); - using (RepositorySafeHandle repo = Proxy.git_repository_init(path, isBare)) + using (RepositorySafeHandle repo = Proxy.git_repository_init_ext(null, path, isBare)) { FilePath repoPath = Proxy.git_repository_path(repo); - return new Repository(repoPath.Native, options); + return repoPath.Native; } } /// - /// Try to lookup an object by its . If no matching object is found, null will be returned. + /// Initialize a repository by explictly setting the path to both the working directory and the git directory. /// - /// The id to lookup. - /// The or null if it was not found. + /// The path to the working directory. + /// The path to the git repository to be created. + /// The path to the created repository. + public static string Init(string workingDirectoryPath, string gitDirectoryPath) + { + Ensure.ArgumentNotNullOrEmptyString(workingDirectoryPath, "workingDirectoryPath"); + Ensure.ArgumentNotNullOrEmptyString(gitDirectoryPath, "gitDirectoryPath"); + + // When being passed a relative workdir path, libgit2 will evaluate it from the + // path to the repository. We pass a fully rooted path in order for the LibGit2Sharp caller + // to pass a path relatively to his current directory. + string wd = Path.GetFullPath(workingDirectoryPath); + + // TODO: Shouldn't we ensure that the working folder isn't under the gitDir? + + using (RepositorySafeHandle repo = Proxy.git_repository_init_ext(wd, gitDirectoryPath, false)) + { + FilePath repoPath = Proxy.git_repository_path(repo); + return repoPath.Native; + } + } + + /// + /// Try to lookup an object by its . If no matching object is found, null will be returned. + /// + /// The id to lookup. + /// The or null if it was not found. public GitObject Lookup(ObjectId id) { return LookupInternal(id, GitObjectType.Any, null); } /// - /// Try to lookup an object by its sha or a reference canonical name. If no matching object is found, null will be returned. + /// Try to lookup an object by its sha or a reference canonical name. If no matching object is found, null will be returned. /// - /// A revparse spec for the object to lookup. - /// The or null if it was not found. + /// A revparse spec for the object to lookup. + /// The or null if it was not found. public GitObject Lookup(string objectish) { return Lookup(objectish, GitObjectType.Any, LookUpOptions.None); } /// - /// Try to lookup an object by its and . If no matching object is found, null will be returned. + /// Try to lookup an object by its and . If no matching object is found, null will be returned. /// - /// The id to lookup. - /// The kind of GitObject being looked up - /// The or null if it was not found. + /// The id to lookup. + /// The kind of GitObject being looked up + /// The or null if it was not found. public GitObject Lookup(ObjectId id, ObjectType type) { return LookupInternal(id, type.ToGitObjectType(), null); } /// - /// Try to lookup an object by its sha or a reference canonical name and . If no matching object is found, null will be returned. + /// Try to lookup an object by its sha or a reference canonical name and . If no matching object is found, null will be returned. /// - /// A revparse spec for the object to lookup. - /// The kind of being looked up - /// The or null if it was not found. + /// A revparse spec for the object to lookup. + /// The kind of being looked up + /// The or null if it was not found. public GitObject Lookup(string objectish, ObjectType type) { return Lookup(objectish, type.ToGitObjectType(), LookUpOptions.None); @@ -502,21 +528,19 @@ internal GitObject Lookup(string objectish, GitObjectType type, LookUpOptions lo return obj; } - /// - /// Lookup a commit by its SHA or name, or throw if a commit is not found. - /// - /// A revparse spec for the commit. - /// The commit. internal Commit LookupCommit(string committish) { - return (Commit)Lookup(committish, GitObjectType.Any, LookUpOptions.ThrowWhenNoGitObjectHasBeenFound | LookUpOptions.DereferenceResultToCommit | LookUpOptions.ThrowWhenCanNotBeDereferencedToACommit); + return (Commit)Lookup(committish, GitObjectType.Any, + LookUpOptions.ThrowWhenNoGitObjectHasBeenFound | + LookUpOptions.DereferenceResultToCommit | + LookUpOptions.ThrowWhenCanNotBeDereferencedToACommit); } /// - /// Probe for a git repository. - /// The lookup start from and walk upward parent directories if nothing has been found. + /// Probe for a git repository. + /// The lookup start from and walk upward parent directories if nothing has been found. /// - /// The base path where the lookup starts. + /// The base path where the lookup starts. /// The path to the git repository. public static string Discover(string startingPath) { @@ -542,29 +566,57 @@ public static string Discover(string startingPath) /// Handler for checkout progress information /// Overrides to the way a repository is opened. /// Credentials to use for user/pass authentication - /// + /// a new instance of the class. The client code is responsible for calling on this instance. + [Obsolete("This method will be removed in the next release. Please use Clone(string, string, bool, bool, TransferProgressHandler, CheckoutProgressHandler, Credentials) instead.")] public static Repository Clone(string sourceUrl, string workdirPath, + bool bare, + bool checkout, + TransferProgressHandler onTransferProgress, + CheckoutProgressHandler onCheckoutProgress, + RepositoryOptions options, + Credentials credentials) + { + string gitDirPath = Clone(sourceUrl, workdirPath, bare, + checkout, onTransferProgress, onCheckoutProgress, credentials); + + return new Repository(gitDirPath, options); + } + + /// + /// Clone with specified options. + /// + /// URI for the remote repository + /// Local path to clone into + /// True will result in a bare clone, false a full clone. + /// If true, the origin's HEAD will be checked out. This only applies + /// to non-bare repositories. + /// Handler for network transfer and indexing progress information + /// Handler for checkout progress information + /// Credentials to use for user/pass authentication + /// The path to the created repository. + public static string Clone(string sourceUrl, string workdirPath, bool bare = false, bool checkout = true, TransferProgressHandler onTransferProgress = null, CheckoutProgressHandler onCheckoutProgress = null, - RepositoryOptions options = null, Credentials credentials = null) { + CheckoutCallbacks checkoutCallbacks = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress, null); + var cloneOpts = new GitCloneOptions + { + Bare = bare ? 1 : 0, + TransferProgressCallback = TransferCallbacks.GenerateCallback(onTransferProgress), + CheckoutOpts = { - Bare = bare ? 1 : 0, - TransferProgressCallback = TransferCallbacks.GenerateCallback(onTransferProgress), - CheckoutOpts = - { - version = 1, - progress_cb = - CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress), - checkout_strategy = checkout - ? CheckoutStrategy.GIT_CHECKOUT_SAFE_CREATE - : CheckoutStrategy.GIT_CHECKOUT_NONE - }, - }; + version = 1, + progress_cb = + checkoutCallbacks.CheckoutProgressCallback, + checkout_strategy = checkout + ? CheckoutStrategy.GIT_CHECKOUT_SAFE_CREATE + : CheckoutStrategy.GIT_CHECKOUT_NONE + }, + }; if (credentials != null) { @@ -573,75 +625,117 @@ public static Repository Clone(string sourceUrl, string workdirPath, NativeMethods.git_cred_userpass_plaintext_new(out cred, credentials.Username, credentials.Password); } - using(Proxy.git_clone(sourceUrl, workdirPath, cloneOpts)) {} + FilePath repoPath; + using (RepositorySafeHandle repo = Proxy.git_clone(sourceUrl, workdirPath, cloneOpts)) + { + repoPath = Proxy.git_repository_path(repo); + } // To be safe, make sure the credential callback is kept until // alive until at least this point. GC.KeepAlive(cloneOpts.CredAcquireCallback); - return new Repository(workdirPath, options); + return repoPath.Native; } /// - /// Checkout the specified , reference or SHA. + /// Checkout the specified , reference or SHA. + /// + /// If the committishOrBranchSpec parameter resolves to a branch name, then the checked out HEAD will + /// will point to the branch. Otherwise, the HEAD will be detached, pointing at the commit sha. + /// /// - /// A revparse spec for the commit or branch to checkout. - /// controlling checkout behavior. - /// that checkout progress is reported through. - /// The that was checked out. + /// A revparse spec for the commit or branch to checkout. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// The that was checked out. + [Obsolete("This method will be removed in the next release. Please use Checkout(string, CheckoutModifiers, CheckoutProgressHandler, CheckoutNotificationOptions) instead.")] public Branch Checkout(string committishOrBranchSpec, CheckoutOptions checkoutOptions, CheckoutProgressHandler onCheckoutProgress) { - Ensure.ArgumentNotNullOrEmptyString(committishOrBranchSpec, "committishOrBranchSpec"); + return Checkout(committishOrBranchSpec, (CheckoutModifiers)checkoutOptions, onCheckoutProgress, null); + } - Branch branch = TryResolveBranch(committishOrBranchSpec); + /// + /// Checkout the specified , reference or SHA. + /// + /// If the committishOrBranchSpec parameter resolves to a branch name, then the checked out HEAD will + /// will point to the branch. Otherwise, the HEAD will be detached, pointing at the commit sha. + /// + /// + /// A revparse spec for the commit or branch to checkout. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// to manage checkout notifications. + /// The that was checked out. + public Branch Checkout(string committishOrBranchSpec, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotifications) + { + Ensure.ArgumentNotNullOrEmptyString(committishOrBranchSpec, "committishOrBranchSpec"); - if (branch != null) + var handles = Proxy.git_revparse_ext(Handle, committishOrBranchSpec); + if (handles == null) { - return Checkout(branch, checkoutOptions, onCheckoutProgress); + Ensure.GitObjectIsNotNull(null, committishOrBranchSpec); } - var previousHeadName = Info.IsHeadDetached ? Head.Tip.Sha : Head.Name; - - Commit commit = LookupCommit(committishOrBranchSpec); - CheckoutTree(commit.Tree, checkoutOptions, onCheckoutProgress); + var objH = handles.Item1; + var refH = handles.Item2; + GitObject obj; + try + { + if (!refH.IsInvalid) + { + var reference = Reference.BuildFromPtr(refH, this); + if (reference.IsLocalBranch()) + { + Branch branch = Branches[reference.CanonicalName]; + return Checkout(branch, checkoutModifiers, onCheckoutProgress, checkoutNotifications); + } + } - // Update HEAD. - Refs.UpdateTarget("HEAD", commit.Id.Sha); - if (committishOrBranchSpec != "HEAD") + obj = GitObject.BuildFrom(this, Proxy.git_object_id(objH), Proxy.git_object_type(objH), + PathFromRevparseSpec(committishOrBranchSpec)); + } + finally { - LogCheckout(previousHeadName, commit.Id, committishOrBranchSpec); + objH.Dispose(); + refH.Dispose(); } + Commit commit = obj.DereferenceToCommit(true); + Checkout(commit.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotifications, commit.Id.Sha, committishOrBranchSpec, + committishOrBranchSpec != "HEAD"); + return Head; } - private Branch TryResolveBranch(string committishOrBranchSpec) + /// + /// Checkout the commit pointed at by the tip of the specified . + /// + /// If this commit is the current tip of the branch as it exists in the repository, the HEAD + /// will point to this branch. Otherwise, the HEAD will be detached, pointing at the commit sha. + /// + /// + /// The to check out. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// The that was checked out. + [Obsolete("This method will be removed in the next release. Please use Checkout(Branch, CheckoutModifiers, CheckoutProgressHandler, CheckoutNotificationOptions) instead.")] + public Branch Checkout(Branch branch, CheckoutOptions checkoutOptions, CheckoutProgressHandler onCheckoutProgress) { - if (committishOrBranchSpec == "HEAD") - { - return Head; - } - - try - { - return Branches[committishOrBranchSpec]; - } - catch (InvalidSpecificationException) - { - return null; - } + return Checkout(branch, (CheckoutModifiers)checkoutOptions, onCheckoutProgress, null); } /// - /// Checkout the tip commit of the specified object. If this commit is the - /// current tip of the branch, will checkout the named branch. Otherwise, will checkout the tip commit - /// as a detached HEAD. + /// Checkout the tip commit of the specified object. If this commit is the + /// current tip of the branch, will checkout the named branch. Otherwise, will checkout the tip commit + /// as a detached HEAD. /// - /// The to check out. - /// controlling checkout behavior. - /// that checkout progress is reported through. - /// The that was checked out. - public Branch Checkout(Branch branch, CheckoutOptions checkoutOptions, CheckoutProgressHandler onCheckoutProgress) + /// The to check out. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// to manage checkout notifications. + /// The that was checked out. + public Branch Checkout(Branch branch, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions) { Ensure.ArgumentNotNull(branch, "branch"); @@ -654,33 +748,55 @@ public Branch Checkout(Branch branch, CheckoutOptions checkoutOptions, CheckoutP } var branchIsCurrentRepositoryHead = branch.IsCurrentRepositoryHead; - var previousHeadName = Info.IsHeadDetached ? Head.Tip.Sha : Head.Name; - CheckoutTree(branch.Tip.Tree, checkoutOptions, onCheckoutProgress); - - // Update HEAD. if (!branch.IsRemote && !(branch is DetachedHead) && string.Equals(Refs[branch.CanonicalName].TargetIdentifier, branch.Tip.Id.Sha, StringComparison.OrdinalIgnoreCase)) { - Refs.UpdateTarget("HEAD", branch.CanonicalName); + Checkout(branch.Tip.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions, branch.CanonicalName, branch.Name, !branchIsCurrentRepositoryHead); } else { - Refs.UpdateTarget("HEAD", branch.Tip.Id.Sha); + Checkout(branch.Tip.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions, branch.Tip.Id.Sha, branch.Name, !branchIsCurrentRepositoryHead); } - if (!branchIsCurrentRepositoryHead) - { - LogCheckout(previousHeadName, branch); - } + return Head; + } + + /// + /// Checkout the specified . + /// + /// Will detach the HEAD and make it point to this commit sha. + /// + /// + /// The to check out. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// The that was checked out. + [Obsolete("This method will be removed in the next release. Please use Checkout(Commit, CheckoutModifiers, CheckoutProgressHandler, CheckoutNotificationOptions) instead.")] + public Branch Checkout(Commit commit, CheckoutOptions checkoutOptions, CheckoutProgressHandler onCheckoutProgress) + { + Checkout(commit.Tree, (CheckoutModifiers)checkoutOptions, onCheckoutProgress, null, commit.Id.Sha, commit.Id.Sha, true); return Head; } - private void LogCheckout(string previousHeadName, Branch newHead) + /// + /// Checkout the specified . + /// + /// Will detach the HEAD and make it point to this commit sha. + /// + /// + /// The to check out. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// to manage checkout notifications. + /// The that was checked out. + public Branch Checkout(Commit commit, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions) { - LogCheckout(previousHeadName, newHead.Tip.Id, newHead.Name); + Checkout(commit.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions, commit.Id.Sha, commit.Id.Sha, true); + + return Head; } private void LogCheckout(string previousHeadName, ObjectId newHeadTip, string newHeadSpec) @@ -693,35 +809,87 @@ private void LogCheckout(string previousHeadName, ObjectId newHeadTip, string ne } /// - /// Internal implementation of Checkout that expects the ID of the checkout target - /// to already be in the form of a canonical branch name or a commit ID. + /// Internal implementation of Checkout that expects the ID of the checkout target + /// to already be in the form of a canonical branch name or a commit ID. + /// + /// The to checkout. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// to manage checkout notifications. + /// Target for the new HEAD. + /// The spec which will be written as target in the reflog. + /// Will a reflog entry be created. + private void Checkout( + Tree tree, + CheckoutModifiers checkoutModifiers, + CheckoutProgressHandler onCheckoutProgress, + CheckoutNotificationOptions checkoutNotificationOptions, + string headTarget, string refLogHeadSpec, bool writeReflogEntry) + { + var previousHeadName = Info.IsHeadDetached ? Head.Tip.Sha : Head.Name; + + CheckoutTree(tree, null, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions); + + Refs.UpdateTarget("HEAD", headTarget); + + if (writeReflogEntry) + { + LogCheckout(previousHeadName, Head.Tip.Id, refLogHeadSpec); + } + } + + /// + /// Checkout the specified tree. /// /// The to checkout. - /// controlling checkout behavior. - /// that checkout progress is reported through. - private void CheckoutTree(Tree tree, CheckoutOptions checkoutOptions, CheckoutProgressHandler onCheckoutProgress) + /// The paths to checkout. + /// controlling checkout behavior. + /// that checkout progress is reported through. + /// to manage checkout notifications. + private void CheckoutTree( + Tree tree, + IList paths, + CheckoutModifiers checkoutModifiers, + CheckoutProgressHandler onCheckoutProgress, + CheckoutNotificationOptions checkoutNotificationOptions) { + CheckoutNotifyHandler onCheckoutNotify = checkoutNotificationOptions != null ? checkoutNotificationOptions.CheckoutNotifyHandler : null; + CheckoutNotifyFlags checkoutNotifyFlags = checkoutNotificationOptions != null ? checkoutNotificationOptions.NotifyFlags : default(CheckoutNotifyFlags); + CheckoutCallbacks checkoutCallbacks = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress, onCheckoutNotify); + + GitStrArrayIn strArray = (paths != null && paths.Count > 0) ? GitStrArrayIn.BuildFrom(ToFilePaths(paths)) : null; + GitCheckoutOpts options = new GitCheckoutOpts { version = 1, checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_SAFE, - progress_cb = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress) + progress_cb = checkoutCallbacks.CheckoutProgressCallback, + notify_cb = checkoutCallbacks.CheckoutNotifyCallback, + notify_flags = checkoutNotifyFlags, + paths = strArray }; - if (checkoutOptions.HasFlag(CheckoutOptions.Force)) + try { - options.checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_FORCE; - } + if (checkoutModifiers.HasFlag(CheckoutModifiers.Force)) + { + options.checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_FORCE; + } - Proxy.git_checkout_tree(this.Handle, tree.Id, ref options); + Proxy.git_checkout_tree(Handle, tree.Id, ref options); + } + finally + { + options.Dispose(); + } } /// - /// Sets the current to the specified commit and optionally resets the and - /// the content of the working tree to match. + /// Sets the current to the specified commit and optionally resets the and + /// the content of the working tree to match. /// - /// Flavor of reset operation to perform. - /// The target commit object. + /// Flavor of reset operation to perform. + /// The target commit object. public void Reset(ResetOptions resetOptions, Commit commit) { Ensure.ArgumentNotNull(commit, "commit"); @@ -732,13 +900,31 @@ public void Reset(ResetOptions resetOptions, Commit commit) } /// - /// Replaces entries in the with entries from the specified commit. + /// Updates specifed paths in the index and working directory with the versions from the specified branch, reference, or SHA. + /// + /// This method does not switch branches or update the current repository HEAD. + /// + /// + /// A revparse spec for the commit or branch to checkout paths from. + /// The paths to checkout. + /// Options controlling checkout behavior. + /// Callback method to report checkout progress updates through. + /// to manage checkout notifications. + public void CheckoutPaths(string committishOrBranchSpec, IList paths, CheckoutModifiers checkoutOptions, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions) + { + Ensure.ArgumentNotNullOrEmptyString(committishOrBranchSpec, "committishOrBranchSpec"); + Commit commit = LookupCommit(committishOrBranchSpec); + CheckoutTree(commit.Tree, paths, checkoutOptions, onCheckoutProgress, checkoutNotificationOptions); + } + + /// + /// Replaces entries in the with entries from the specified commit. /// - /// The target commit object. - /// The list of paths (either files or directories) that should be considered. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The target commit object. + /// The list of paths (either files or directories) that should be considered. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// public void Reset(Commit commit, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null) { @@ -754,15 +940,15 @@ public void Reset(Commit commit, IEnumerable paths = null, ExplicitPaths } /// - /// Stores the content of the as a new into the repository. - /// The tip of the will be used as the parent of this new Commit. - /// Once the commit is created, the will move forward to point at it. + /// Stores the content of the as a new into the repository. + /// The tip of the will be used as the parent of this new Commit. + /// Once the commit is created, the will move forward to point at it. /// - /// The description of why a change was made to the repository. - /// The of who made the change. - /// The of who added the change to the repository. - /// True to amend the current pointed at by , false otherwise. - /// The generated . + /// The description of why a change was made to the repository. + /// The of who made the change. + /// The of who added the change to the repository. + /// True to amend the current pointed at by , false otherwise. + /// The generated . public Commit Commit(string message, Signature author, Signature committer, bool amendPreviousCommit = false) { bool isHeadOrphaned = Info.IsHeadOrphaned; @@ -852,7 +1038,14 @@ public virtual void RemoveUntrackedFiles() | CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS, }; - Proxy.git_checkout_index(Handle, new NullGitObjectSafeHandle(), ref options); + try + { + Proxy.git_checkout_index(Handle, new NullGitObjectSafeHandle(), ref options); + } + finally + { + options.Dispose(); + } } private void CleanupDisposableDependencies() @@ -870,11 +1063,11 @@ internal T RegisterForCleanup(T disposable) where T : IDisposable } /// - /// Gets the current LibGit2Sharp version. - /// - /// The format of the version number is as follows: - /// Major.Minor.Patch-LibGit2Sharp_abbrev_hash-libgit2_abbrev_hash (x86|amd64) - /// + /// Gets the current LibGit2Sharp version. + /// + /// The format of the version number is as follows: + /// Major.Minor.Patch-LibGit2Sharp_abbrev_hash-libgit2_abbrev_hash (x86|amd64) + /// /// public static string Version { @@ -910,7 +1103,7 @@ private static string ReadContentFromResource(Assembly assembly, string partialR } /// - /// Gets the references to the tips that are currently being merged. + /// Gets the references to the tips that are currently being merged. /// public virtual IEnumerable MergeHeads { @@ -932,6 +1125,33 @@ internal bool PathStartsWith(string path, string value) return pathCase.Value.StartsWith(path, value); } + internal FilePath[] ToFilePaths(IEnumerable paths) + { + if (paths == null) + { + return null; + } + + var filePaths = new List(); + + foreach (string path in paths) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentException("At least one provided path is either null or empty.", "paths"); + } + + filePaths.Add(this.BuildRelativePathFrom(path)); + } + + if (filePaths.Count == 0) + { + throw new ArgumentException("No path has been provided.", "paths"); + } + + return filePaths.ToArray(); + } + private string DebuggerDisplay { get diff --git a/LibGit2Sharp/RepositoryExtensions.cs b/LibGit2Sharp/RepositoryExtensions.cs index 1cc638b8a..a1c8461a5 100644 --- a/LibGit2Sharp/RepositoryExtensions.cs +++ b/LibGit2Sharp/RepositoryExtensions.cs @@ -8,17 +8,17 @@ namespace LibGit2Sharp { /// - /// Provides helper overloads to a . + /// Provides helper overloads to a . /// public static class RepositoryExtensions { /// - /// Try to lookup an object by its sha or a reference name. + /// Try to lookup an object by its sha or a reference name. /// - /// - /// The being looked up. - /// The revparse spec for the object to lookup. - /// + /// The kind of to lookup. + /// The being looked up. + /// The revparse spec for the object to lookup. + /// The retrieved , or null if none was found. public static T Lookup(this IRepository repository, string objectish) where T : GitObject { EnsureNoGitLink(); @@ -32,12 +32,12 @@ public static T Lookup(this IRepository repository, string objectish) where T } /// - /// Try to lookup an object by its . + /// Try to lookup an object by its . /// - /// - /// The being looked up. - /// The id. - /// + /// The kind of to lookup. + /// The being looked up. + /// The id. + /// The retrieved , or null if none was found. public static T Lookup(this IRepository repository, ObjectId id) where T : GitObject { EnsureNoGitLink(); @@ -61,90 +61,90 @@ private static void EnsureNoGitLink() where T : GitObject } /// - /// Creates a lightweight tag with the specified name. This tag will point at the commit pointed at by the . + /// Creates a lightweight tag with the specified name. This tag will point at the commit pointed at by the . /// - /// The being worked with. - /// The name of the tag to create. + /// The being worked with. + /// The name of the tag to create. public static Tag ApplyTag(this IRepository repository, string tagName) { return ApplyTag(repository, tagName, repository.Head.CanonicalName); } /// - /// Creates a lightweight tag with the specified name. This tag will point at the . + /// Creates a lightweight tag with the specified name. This tag will point at the . /// - /// The being worked with. - /// The name of the tag to create. - /// The revparse spec for the target object. + /// The being worked with. + /// The name of the tag to create. + /// The revparse spec for the target object. public static Tag ApplyTag(this IRepository repository, string tagName, string objectish) { return repository.Tags.Add(tagName, objectish); } /// - /// Creates an annotated tag with the specified name. This tag will point at the commit pointed at by the . + /// Creates an annotated tag with the specified name. This tag will point at the commit pointed at by the . /// - /// The being worked with. - /// The name of the tag to create. - /// The identity of the creator of this tag. - /// The annotation message. + /// The being worked with. + /// The name of the tag to create. + /// The identity of the creator of this tag. + /// The annotation message. public static Tag ApplyTag(this IRepository repository, string tagName, Signature tagger, string message) { return ApplyTag(repository, tagName, repository.Head.CanonicalName, tagger, message); } /// - /// Creates an annotated tag with the specified name. This tag will point at the . + /// Creates an annotated tag with the specified name. This tag will point at the . /// - /// The being worked with. - /// The name of the tag to create. - /// The revparse spec for the target object. - /// The identity of the creator of this tag. - /// The annotation message. + /// The being worked with. + /// The name of the tag to create. + /// The revparse spec for the target object. + /// The identity of the creator of this tag. + /// The annotation message. public static Tag ApplyTag(this IRepository repository, string tagName, string objectish, Signature tagger, string message) { return repository.Tags.Add(tagName, objectish, tagger, message); } /// - /// Creates a branch with the specified name. This branch will point at the commit pointed at by the . + /// Creates a branch with the specified name. This branch will point at the commit pointed at by the . /// - /// The being worked with. - /// The name of the branch to create. + /// The being worked with. + /// The name of the branch to create. public static Branch CreateBranch(this IRepository repository, string branchName) { return CreateBranch(repository, branchName, repository.Head.Tip); } /// - /// Creates a branch with the specified name. This branch will point at . + /// Creates a branch with the specified name. This branch will point at . /// - /// The being worked with. - /// The name of the branch to create. - /// The commit which should be pointed at by the Branch. + /// The being worked with. + /// The name of the branch to create. + /// The commit which should be pointed at by the Branch. public static Branch CreateBranch(this IRepository repository, string branchName, Commit target) { return repository.Branches.Add(branchName, target); } /// - /// Creates a branch with the specified name. This branch will point at the commit pointed at by the . + /// Creates a branch with the specified name. This branch will point at the commit pointed at by the . /// - /// The being worked with. - /// The name of the branch to create. - /// The revparse spec for the target commit. + /// The being worked with. + /// The name of the branch to create. + /// The revparse spec for the target commit. public static Branch CreateBranch(this IRepository repository, string branchName, string committish) { return repository.Branches.Add(branchName, committish); } /// - /// Sets the current /> to the specified commit and optionally resets the and - /// the content of the working tree to match. + /// Sets the current to the specified commit and optionally resets the and + /// the content of the working tree to match. /// - /// The being worked with. - /// Flavor of reset operation to perform. - /// A revparse spec for the target commit object. + /// The being worked with. + /// Flavor of reset operation to perform. + /// A revparse spec for the target commit object. public static void Reset(this IRepository repository, ResetOptions resetOptions, string committish = "HEAD") { Ensure.ArgumentNotNullOrEmptyString(committish, "committish"); @@ -155,14 +155,14 @@ public static void Reset(this IRepository repository, ResetOptions resetOptions, } /// - /// Replaces entries in the with entries from the specified commit. + /// Replaces entries in the with entries from the specified commit. /// - /// The being worked with. - /// A revparse spec for the target commit object. - /// The list of paths (either files or directories) that should be considered. - /// - /// If set, the passed will be treated as explicit paths. - /// Use these options to determine how unmatched explicit paths should be handled. + /// The being worked with. + /// A revparse spec for the target commit object. + /// The list of paths (either files or directories) that should be considered. + /// + /// If set, the passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. /// public static void Reset(this IRepository repository, string committish = "HEAD", IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null) { @@ -186,15 +186,15 @@ private static Commit LookUpCommit(IRepository repository, string committish) } /// - /// Stores the content of the as a new into the repository. - /// The tip of the will be used as the parent of this new Commit. - /// Once the commit is created, the will move forward to point at it. - /// Both the Author and Committer will be guessed from the Git configuration. An exception will be raised if no configuration is reachable. + /// Stores the content of the as a new into the repository. + /// The tip of the will be used as the parent of this new Commit. + /// Once the commit is created, the will move forward to point at it. + /// Both the Author and Committer will be guessed from the Git configuration. An exception will be raised if no configuration is reachable. /// - /// The being worked with. - /// The description of why a change was made to the repository. - /// True to amend the current pointed at by , false otherwise. - /// The generated . + /// The being worked with. + /// The description of why a change was made to the repository. + /// True to amend the current pointed at by , false otherwise. + /// The generated . public static Commit Commit(this IRepository repository, string message, bool amendPreviousCommit = false) { Signature author = repository.Config.BuildSignatureFromGlobalConfiguration(DateTimeOffset.Now, true); @@ -203,16 +203,16 @@ public static Commit Commit(this IRepository repository, string message, bool am } /// - /// Stores the content of the as a new into the repository. - /// The tip of the will be used as the parent of this new Commit. - /// Once the commit is created, the will move forward to point at it. - /// The Committer will be guessed from the Git configuration. An exception will be raised if no configuration is reachable. + /// Stores the content of the as a new into the repository. + /// The tip of the will be used as the parent of this new Commit. + /// Once the commit is created, the will move forward to point at it. + /// The Committer will be guessed from the Git configuration. An exception will be raised if no configuration is reachable. /// - /// The being worked with. - /// The of who made the change. - /// The description of why a change was made to the repository. - /// True to amend the current pointed at by , false otherwise. - /// The generated . + /// The being worked with. + /// The of who made the change. + /// The description of why a change was made to the repository. + /// True to amend the current pointed at by , false otherwise. + /// The generated . public static Commit Commit(this IRepository repository, string message, Signature author, bool amendPreviousCommit = false) { Signature committer = repository.Config.BuildSignatureFromGlobalConfiguration(DateTimeOffset.Now, true); @@ -221,16 +221,16 @@ public static Commit Commit(this IRepository repository, string message, Signatu } /// - /// Fetch from the specified remote. + /// Fetch from the specified remote. /// - /// The being worked with. + /// The being worked with. /// The name of the to fetch from. /// Optional parameter indicating what tags to download. /// Progress callback. Corresponds to libgit2 progress callback. /// Completion callback. Corresponds to libgit2 completion callback. /// UpdateTips callback. Corresponds to libgit2 update_tips callback. /// Callback method that transfer progress will be reported through. - /// Reports the client's state regarding the received and processed (bytes, objects) from the server. + /// Reports the client's state regarding the received and processed (bytes, objects) from the server. /// Credentials to use for username/password authentication. public static void Fetch(this IRepository repository, string remoteName, TagFetchMode tagFetchMode = TagFetchMode.Auto, @@ -249,26 +249,43 @@ public static void Fetch(this IRepository repository, string remoteName, } /// - /// Checkout the specified , reference or SHA. + /// Checkout the specified , reference or SHA. /// - /// The being worked with. - /// A revparse spec for the commit or branch to checkout. - /// The that was checked out. + /// The being worked with. + /// A revparse spec for the commit or branch to checkout. + /// The that was checked out. public static Branch Checkout(this IRepository repository, string commitOrBranchSpec) { - return repository.Checkout(commitOrBranchSpec, CheckoutOptions.None, null); + return repository.Checkout(commitOrBranchSpec, CheckoutModifiers.None, null, null); } - /// - /// Checkout the specified . + /// Checkout the commit pointed at by the tip of the specified . + /// + /// If this commit is the current tip of the branch as it exists in the repository, the HEAD + /// will point to this branch. Otherwise, the HEAD will be detached, pointing at the commit sha. + /// /// - /// The being worked with. - /// The to check out. - /// The that was checked out. + /// The being worked with. + /// The to check out. + /// The that was checked out. public static Branch Checkout(this IRepository repository, Branch branch) { - return repository.Checkout(branch, CheckoutOptions.None, null); + return repository.Checkout(branch, CheckoutModifiers.None, null, null); + } + + /// + /// Checkout the specified . + /// + /// Will detach the HEAD and make it point to this commit sha. + /// + /// + /// The being worked with. + /// The to check out. + /// The that was checked out. + public static Branch Checkout(this IRepository repository, Commit commit) + { + return repository.Checkout(commit, CheckoutModifiers.None, null, null); } internal static string BuildRelativePathFrom(this Repository repo, string path) @@ -290,6 +307,5 @@ internal static string BuildRelativePathFrom(this Repository repo, string path) return normalizedPath.Substring(repo.Info.WorkingDirectory.Length); } - } } diff --git a/LibGit2Sharp/RepositoryInformation.cs b/LibGit2Sharp/RepositoryInformation.cs index 2944e5191..5eddc34ad 100644 --- a/LibGit2Sharp/RepositoryInformation.cs +++ b/LibGit2Sharp/RepositoryInformation.cs @@ -1,17 +1,16 @@ -using System; -using LibGit2Sharp.Core; +using LibGit2Sharp.Core; namespace LibGit2Sharp { /// - /// Provides high level information about a repository. + /// Provides high level information about a repository. /// public class RepositoryInformation { private readonly Repository repo; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected RepositoryInformation() { } @@ -30,30 +29,30 @@ internal RepositoryInformation(Repository repo, bool isBare) } /// - /// Gets the normalized path to the git repository. + /// Gets the normalized path to the git repository. /// public virtual string Path { get; private set; } /// - /// Gets the normalized path to the working directory. - /// - /// Is the repository is bare, null is returned. - /// + /// Gets the normalized path to the working directory. + /// + /// Is the repository is bare, null is returned. + /// /// public virtual string WorkingDirectory { get; private set; } /// - /// Indicates whether the repository has a working directory. + /// Indicates whether the repository has a working directory. /// public virtual bool IsBare { get; private set; } /// - /// Indicates whether the repository is shallow (the result of `git clone --depth ...`) + /// Indicates whether the repository is shallow (the result of `git clone --depth ...`) /// public virtual bool IsShallow { get; private set; } /// - /// Indicates whether the Head points to an arbitrary commit instead of the tip of a local branch. + /// Indicates whether the Head points to an arbitrary commit instead of the tip of a local branch. /// public virtual bool IsHeadDetached { @@ -61,7 +60,7 @@ public virtual bool IsHeadDetached } /// - /// Indicates whether the Head points to a reference which doesn't exist. + /// Indicates whether the Head points to a reference which doesn't exist. /// public virtual bool IsHeadOrphaned { @@ -69,7 +68,7 @@ public virtual bool IsHeadOrphaned } /// - /// The pending interactive operation. + /// The pending interactive operation. /// public virtual CurrentOperation CurrentOperation { @@ -77,7 +76,7 @@ public virtual CurrentOperation CurrentOperation } /// - /// The message for a pending interactive operation. + /// The message for a pending interactive operation. /// public virtual string Message { diff --git a/LibGit2Sharp/RepositoryNotFoundException.cs b/LibGit2Sharp/RepositoryNotFoundException.cs index edc6fcdf2..114da2ea0 100644 --- a/LibGit2Sharp/RepositoryNotFoundException.cs +++ b/LibGit2Sharp/RepositoryNotFoundException.cs @@ -4,43 +4,43 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when a is being built with - /// a path that doesn't point at a valid Git repository or workdir. + /// The exception that is thrown when a is being built with + /// a path that doesn't point at a valid Git repository or workdir. /// [Serializable] public class RepositoryNotFoundException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public RepositoryNotFoundException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public RepositoryNotFoundException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public RepositoryNotFoundException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected RepositoryNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/RepositoryOptions.cs b/LibGit2Sharp/RepositoryOptions.cs index 846477e94..bb139186b 100644 --- a/LibGit2Sharp/RepositoryOptions.cs +++ b/LibGit2Sharp/RepositoryOptions.cs @@ -1,55 +1,55 @@ namespace LibGit2Sharp { /// - /// Provides optional additional information to the Repository to be opened. + /// Provides optional additional information to the Repository to be opened. /// public class RepositoryOptions { /// - /// Overrides the probed location of the working directory of a standard repository, - /// or, combined with , would - /// allow to work against a bare repository as it was a standard one. - /// - /// The path has to lead to an existing directory. - /// + /// Overrides the probed location of the working directory of a standard repository, + /// or, combined with , would + /// allow to work against a bare repository as it was a standard one. + /// + /// The path has to lead to an existing directory. + /// /// public string WorkingDirectoryPath { get; set; } /// - /// Overrides the probed location of the Index file of a standard repository, - /// or, combined with , would - /// allow to work against a bare repository as it was a standard one. - /// - /// The path has either to lead to an existing valid Index file, - /// or to a non existent Index file which will be eventually created. - /// + /// Overrides the probed location of the Index file of a standard repository, + /// or, combined with , would + /// allow to work against a bare repository as it was a standard one. + /// + /// The path has either to lead to an existing valid Index file, + /// or to a non existent Index file which will be eventually created. + /// /// public string IndexPath { get; set; } /// - /// Overrides the probed location of the Global configuration file of a repository. - /// - /// The path has either to lead to an existing valid configuration file, - /// or to a non existent configuration file which will be eventually created. - /// + /// Overrides the probed location of the Global configuration file of a repository. + /// + /// The path has either to lead to an existing valid configuration file, + /// or to a non existent configuration file which will be eventually created. + /// /// public string GlobalConfigurationLocation { get; set; } /// - /// Overrides the probed location of the XDG configuration file of a repository. - /// - /// The path has either to lead to an existing valid configuration file, - /// or to a non existent configuration file which will be eventually created. - /// + /// Overrides the probed location of the XDG configuration file of a repository. + /// + /// The path has either to lead to an existing valid configuration file, + /// or to a non existent configuration file which will be eventually created. + /// /// public string XdgConfigurationLocation { get; set; } /// - /// Overrides the probed location of the System configuration file of a repository. - /// - /// The path has to lead to an existing valid configuration file, - /// or to a non existent configuration file which will be eventually created. - /// + /// Overrides the probed location of the System configuration file of a repository. + /// + /// The path has to lead to an existing valid configuration file, + /// or to a non existent configuration file which will be eventually created. + /// /// public string SystemConfigurationLocation { get; set; } } diff --git a/LibGit2Sharp/RepositoryStatus.cs b/LibGit2Sharp/RepositoryStatus.cs index 2a8839fbb..443978653 100644 --- a/LibGit2Sharp/RepositoryStatus.cs +++ b/LibGit2Sharp/RepositoryStatus.cs @@ -10,8 +10,8 @@ namespace LibGit2Sharp { /// - /// Holds the result of the determination of the state of the working directory. - /// Only files that differ from the current index and/or commit will be considered. + /// Holds the result of the determination of the state of the working directory. + /// Only files that differ from the current index and/or commit will be considered. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class RepositoryStatus : IEnumerable @@ -43,7 +43,7 @@ private static IDictionary> Build() } /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected RepositoryStatus() { } @@ -73,7 +73,7 @@ private StatusEntry StateChanged(IntPtr filePathPtr, uint state) } /// - /// Gets the for the specified relative path. + /// Gets the for the specified relative path. /// public virtual FileStatus this[string path] { @@ -95,25 +95,25 @@ public virtual FileStatus this[string path] } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { return statusEntries.GetEnumerator(); } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// - /// List of files added to the index, which are not in the current commit + /// List of files added to the index, which are not in the current commit /// public virtual IEnumerable Added { @@ -121,7 +121,7 @@ public virtual IEnumerable Added } /// - /// List of files added to the index, which are already in the current commit with different content + /// List of files added to the index, which are already in the current commit with different content /// public virtual IEnumerable Staged { @@ -129,7 +129,7 @@ public virtual IEnumerable Staged } /// - /// List of files removed from the index but are existent in the current commit + /// List of files removed from the index but are existent in the current commit /// public virtual IEnumerable Removed { @@ -137,7 +137,7 @@ public virtual IEnumerable Removed } /// - /// List of files existent in the index but are missing in the working directory + /// List of files existent in the index but are missing in the working directory /// public virtual IEnumerable Missing { @@ -145,7 +145,7 @@ public virtual IEnumerable Missing } /// - /// List of files with unstaged modifications. A file may be modified and staged at the same time if it has been modified after adding. + /// List of files with unstaged modifications. A file may be modified and staged at the same time if it has been modified after adding. /// public virtual IEnumerable Modified { @@ -153,7 +153,7 @@ public virtual IEnumerable Modified } /// - /// List of files existing in the working directory but are neither tracked in the index nor in the current commit. + /// List of files existing in the working directory but are neither tracked in the index nor in the current commit. /// public virtual IEnumerable Untracked { @@ -161,7 +161,7 @@ public virtual IEnumerable Untracked } /// - /// List of files existing in the working directory that are ignored. + /// List of files existing in the working directory that are ignored. /// public virtual IEnumerable Ignored { @@ -169,7 +169,7 @@ public virtual IEnumerable Ignored } /// - /// True if the index or the working directory has been altered since the last commit. False otherwise. + /// True if the index or the working directory has been altered since the last commit. False otherwise. /// public virtual bool IsDirty { diff --git a/LibGit2Sharp/ResetOptions.cs b/LibGit2Sharp/ResetOptions.cs index 66f009ed3..8ff26eff0 100644 --- a/LibGit2Sharp/ResetOptions.cs +++ b/LibGit2Sharp/ResetOptions.cs @@ -1,25 +1,25 @@ namespace LibGit2Sharp { /// - /// Specifies the kind of operation that should perform. + /// Specifies the kind of operation that should perform. /// public enum ResetOptions { /// - /// Moves the branch pointed to by HEAD to the specified commit object. + /// Moves the branch pointed to by HEAD to the specified commit object. /// Soft = 1, /// - /// Moves the branch pointed to by HEAD to the specified commit object and resets the index - /// to the tree recorded by the commit. + /// Moves the branch pointed to by HEAD to the specified commit object and resets the index + /// to the tree recorded by the commit. /// Mixed, /// - /// Moves the branch pointed to by HEAD to the specified commit object, resets the index - /// to the tree recorded by the commit and updates the working directory to match the content - /// of the index. + /// Moves the branch pointed to by HEAD to the specified commit object, resets the index + /// to the tree recorded by the commit and updates the working directory to match the content + /// of the index. /// Hard, } diff --git a/LibGit2Sharp/Signature.cs b/LibGit2Sharp/Signature.cs index c7d9bf762..ba2d2dd99 100644 --- a/LibGit2Sharp/Signature.cs +++ b/LibGit2Sharp/Signature.cs @@ -6,7 +6,7 @@ namespace LibGit2Sharp { /// - /// A signature + /// A signature /// public class Signature : IEquatable { @@ -28,11 +28,11 @@ internal Signature(IntPtr signaturePtr) } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The name. - /// The email. - /// The when. + /// The name. + /// The email. + /// The when. public Signature(string name, string email, DateTimeOffset when) { this.name = name; @@ -46,7 +46,7 @@ internal SignatureSafeHandle BuildHandle() } /// - /// Gets the name. + /// Gets the name. /// public string Name { @@ -54,7 +54,7 @@ public string Name } /// - /// Gets the email. + /// Gets the email. /// public string Email { @@ -62,7 +62,7 @@ public string Email } /// - /// Gets the date when this signature happened. + /// Gets the date when this signature happened. /// public DateTimeOffset When { @@ -70,27 +70,27 @@ public DateTimeOffset When } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Signature); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(Signature other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -99,10 +99,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(Signature left, Signature right) { @@ -110,10 +110,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(Signature left, Signature right) { diff --git a/LibGit2Sharp/StageLevel.cs b/LibGit2Sharp/StageLevel.cs index c6a9b1b1f..b46d218a5 100644 --- a/LibGit2Sharp/StageLevel.cs +++ b/LibGit2Sharp/StageLevel.cs @@ -1,27 +1,27 @@ namespace LibGit2Sharp { /// - /// Disambiguates the different versions of an index entry during a merge. + /// Disambiguates the different versions of an index entry during a merge. /// public enum StageLevel { /// - /// The standard fully merged state for an index entry. + /// The standard fully merged state for an index entry. /// Staged = 0, /// - /// Version of the entry as it was in the common base merge commit. + /// Version of the entry as it was in the common base merge commit. /// Ancestor = 1, /// - /// Version of the entry as it is in the commit of the Head. + /// Version of the entry as it is in the commit of the Head. /// Ours = 2, /// - /// Version of the entry as it is in the commit being merged. + /// Version of the entry as it is in the commit being merged. /// Theirs = 3, } diff --git a/LibGit2Sharp/Stash.cs b/LibGit2Sharp/Stash.cs index fa49cdd59..2c2856925 100644 --- a/LibGit2Sharp/Stash.cs +++ b/LibGit2Sharp/Stash.cs @@ -1,13 +1,16 @@ -namespace LibGit2Sharp +using System; +using System.Linq; + +namespace LibGit2Sharp { /// - /// A Stash - /// A stash is a snapshot of the dirty state of the working directory (i.e. the modified tracked files and staged changes) + /// A Stash + /// A stash is a snapshot of the dirty state of the working directory (i.e. the modified tracked files and staged changes) /// public class Stash : ReferenceWrapper { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Stash() { } @@ -17,23 +20,65 @@ internal Stash(Repository repo, ObjectId targetId, int index) { } /// - /// Gets the that this stash points to. + /// Gets the that this stash points to. /// + [Obsolete("This property will be removed in the next release. Please use Stash.WorkTree instead.")] public virtual Commit Target + { + get { return WorkTree; } + } + + /// + /// Gets the that contains to the captured content of the worktree when the + /// stash was created. + /// + public virtual Commit WorkTree { get { return TargetObject; } } /// - /// Gets the message associated to this . + /// Gets the base (i.e. the HEAD when the stash was + /// created). + /// + public virtual Commit Base + { + get { return TargetObject.Parents.First(); } + } + + /// + /// Gets the that contains the captured content of the index when the stash was + /// created. + /// + public virtual Commit Index + { + get { return GetParentAtOrDefault(1); } + } + + /// + /// Gets the that contains the list of either the untracked files, the ignored files, or both, + /// depending on the options passed when the stash was created. + /// + public virtual Commit Untracked + { + get { return GetParentAtOrDefault(2); } + } + + private Commit GetParentAtOrDefault(int parentIndex) + { + return TargetObject.Parents.ElementAtOrDefault(parentIndex); + } + + /// + /// Gets the message associated to this . /// public virtual string Message { - get { return Target.Message; } + get { return WorkTree.Message; } } /// - /// Returns "stash@{i}", where i is the index of this . + /// Returns "stash@{i}", where i is the index of this . /// protected override string Shorten() { diff --git a/LibGit2Sharp/StashCollection.cs b/LibGit2Sharp/StashCollection.cs index 0dc503403..b163084a2 100644 --- a/LibGit2Sharp/StashCollection.cs +++ b/LibGit2Sharp/StashCollection.cs @@ -9,7 +9,7 @@ namespace LibGit2Sharp { /// - /// The collection of es in a + /// The collection of es in a /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class StashCollection : IEnumerable @@ -17,15 +17,15 @@ public class StashCollection : IEnumerable internal readonly Repository repo; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected StashCollection() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The repo. + /// The repo. internal StashCollection(Repository repo) { this.repo = repo; @@ -34,12 +34,12 @@ internal StashCollection(Repository repo) #region Implementation of IEnumerable /// - /// Returns an enumerator that iterates through the collection. - /// - /// The enumerator returns the stashes by descending order (last stash is returned first). - /// + /// Returns an enumerator that iterates through the collection. + /// + /// The enumerator returns the stashes by descending order (last stash is returned first). + /// /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public IEnumerator GetEnumerator() { return Proxy.git_stash_foreach(repo.Handle, @@ -47,9 +47,9 @@ public IEnumerator GetEnumerator() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); @@ -58,7 +58,7 @@ IEnumerator IEnumerable.GetEnumerator() #endregion /// - /// Gets the corresponding to the specified index (0 being the most recent one). + /// Gets the corresponding to the specified index (0 being the most recent one). /// public virtual Stash this[int index] { @@ -76,13 +76,26 @@ public virtual Stash this[int index] } /// - /// Creates a stash with the specified message. + /// Creates a stash with the specified message. /// /// The of the user who stashes - /// The message of the stash. - /// A combination of flags + /// The message of the stash. + /// A combination of flags /// the newly created + [Obsolete("This method will be removed in the next release. Please use Add(Signature, string, StashModifiers) instead.")] public virtual Stash Add(Signature stasher, string message = null, StashOptions options = StashOptions.Default) + { + return Add(stasher, message, (StashModifiers) options); + } + + /// + /// Creates a stash with the specified message. + /// + /// The of the user who stashes + /// The message of the stash. + /// A combination of flags + /// the newly created + public virtual Stash Add(Signature stasher, string message = null, StashModifiers options = StashModifiers.Default) { Ensure.ArgumentNotNull(stasher, "stasher"); @@ -100,9 +113,9 @@ public virtual Stash Add(Signature stasher, string message = null, StashOptions } /// - /// Remove a single stashed state from the stash list. + /// Remove a single stashed state from the stash list. /// - /// The index of the stash to remove (0 being the most recent one). + /// The index of the stash to remove (0 being the most recent one). public virtual void Remove(int index) { if (index < 0) diff --git a/LibGit2Sharp/StashModifiers.cs b/LibGit2Sharp/StashModifiers.cs new file mode 100644 index 000000000..b0e6d41ff --- /dev/null +++ b/LibGit2Sharp/StashModifiers.cs @@ -0,0 +1,34 @@ +using System; + +namespace LibGit2Sharp +{ + /// + /// Options controlling Stash behavior. + /// + [Flags] + public enum StashModifiers + { + /// + /// Default + /// + Default = 0, + + /// + /// All changes already added to the index + /// are left intact in the working directory + /// + KeepIndex = (1 << 0), + + /// + /// All untracked files are also stashed and then + /// cleaned up from the working directory + /// + IncludeUntracked = (1 << 1), + + /// + /// All ignored files are also stashed and then + /// cleaned up from the working directory + /// + IncludeIgnored = (1 << 2), + } +} diff --git a/LibGit2Sharp/StashOptions.cs b/LibGit2Sharp/StashOptions.cs index 9933b27f2..eb6005134 100644 --- a/LibGit2Sharp/StashOptions.cs +++ b/LibGit2Sharp/StashOptions.cs @@ -6,6 +6,7 @@ namespace LibGit2Sharp /// Options controlling Stash behavior. /// [Flags] + [Obsolete("This type will be removed in the next release.")] public enum StashOptions { /// diff --git a/LibGit2Sharp/StatusEntry.cs b/LibGit2Sharp/StatusEntry.cs index 9fad0fb87..a11d57be2 100644 --- a/LibGit2Sharp/StatusEntry.cs +++ b/LibGit2Sharp/StatusEntry.cs @@ -5,7 +5,7 @@ namespace LibGit2Sharp { /// - /// Holds the calculated status of a particular file at a particular instant. + /// Holds the calculated status of a particular file at a particular instant. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class StatusEntry : IEquatable @@ -17,7 +17,7 @@ public class StatusEntry : IEquatable new LambdaEqualityHelper(x => x.FilePath, x => x.State); /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected StatusEntry() { } @@ -29,7 +29,7 @@ internal StatusEntry(string filePath, FileStatus state) } /// - /// Gets the of the file. + /// Gets the of the file. /// public virtual FileStatus State { @@ -37,7 +37,7 @@ public virtual FileStatus State } /// - /// Gets the relative filepath to the working directory of the file. + /// Gets the relative filepath to the working directory of the file. /// public virtual string FilePath { @@ -45,27 +45,27 @@ public virtual string FilePath } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as StatusEntry); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(StatusEntry other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -74,10 +74,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(StatusEntry left, StatusEntry right) { @@ -85,10 +85,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(StatusEntry left, StatusEntry right) { diff --git a/LibGit2Sharp/Submodule.cs b/LibGit2Sharp/Submodule.cs index f528d3dae..3d0b35629 100644 --- a/LibGit2Sharp/Submodule.cs +++ b/LibGit2Sharp/Submodule.cs @@ -6,7 +6,7 @@ namespace LibGit2Sharp { /// - /// A Submodule. + /// A Submodule. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class Submodule : IEquatable @@ -26,7 +26,7 @@ public class Submodule : IEquatable private readonly ILazy updateRule; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Submodule() { } @@ -50,57 +50,57 @@ internal Submodule(Repository repo, string name, string path, string url) } /// - /// The name of the submodule. + /// The name of the submodule. /// public virtual string Name { get { return name; } } /// - /// The path of the submodule. + /// The path of the submodule. /// public virtual string Path { get { return path; } } /// - /// The URL of the submodule. + /// The URL of the submodule. /// public virtual string Url { get { return url; } } /// - /// The commit ID for this submodule in the current HEAD tree. + /// The commit ID for this submodule in the current HEAD tree. /// public virtual ObjectId HeadCommitId { get { return headCommitId.Value; } } /// - /// The commit ID for this submodule in the index. + /// The commit ID for this submodule in the index. /// public virtual ObjectId IndexCommitId { get { return indexCommitId.Value; } } /// - /// The commit ID for this submodule in the current working directory. + /// The commit ID for this submodule in the current working directory. /// public virtual ObjectId WorkDirCommitId { get { return workdirCommitId.Value; } } /// - /// The fetchRecurseSubmodules rule for the submodule. + /// The fetchRecurseSubmodules rule for the submodule. /// - /// Note that at this time, LibGit2Sharp does not honor this setting and the - /// fetch functionality current ignores submodules. + /// Note that at this time, LibGit2Sharp does not honor this setting and the + /// fetch functionality current ignores submodules. /// public virtual bool FetchRecurseSubmodulesRule { get { return fetchRecurseSubmodulesRule.Value; } } /// - /// The ignore rule of the submodule. + /// The ignore rule of the submodule. /// public virtual SubmoduleIgnore IgnoreRule { get { return ignoreRule.Value; } } /// - /// The update rule of the submodule. + /// The update rule of the submodule. /// public virtual SubmoduleUpdate UpdateRule { get { return updateRule.Value; } } /// - /// Retrieves the state of this submodule in the working directory compared to the staging area and the latest commmit. + /// Retrieves the state of this submodule in the working directory compared to the staging area and the latest commmit. /// - /// + /// The of this submodule. public virtual SubmoduleStatus RetrieveStatus() { using (var handle = Proxy.git_submodule_lookup(repo.Handle, Name)) @@ -110,27 +110,27 @@ public virtual SubmoduleStatus RetrieveStatus() } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as Submodule); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(Submodule other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -139,9 +139,9 @@ public override int GetHashCode() } /// - /// Returns the , a representation of the current . + /// Returns the , a representation of the current . /// - /// The that represents the current . + /// The that represents the current . public override string ToString() { return Name; diff --git a/LibGit2Sharp/SubmoduleCollection.cs b/LibGit2Sharp/SubmoduleCollection.cs index 5973fe480..18649c764 100644 --- a/LibGit2Sharp/SubmoduleCollection.cs +++ b/LibGit2Sharp/SubmoduleCollection.cs @@ -10,7 +10,7 @@ namespace LibGit2Sharp { /// - /// The collection of submodules in a + /// The collection of submodules in a /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class SubmoduleCollection : IEnumerable @@ -18,22 +18,22 @@ public class SubmoduleCollection : IEnumerable internal readonly Repository repo; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected SubmoduleCollection() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The repo. + /// The repo. internal SubmoduleCollection(Repository repo) { this.repo = repo; } /// - /// Gets the with the specified name. + /// Gets the with the specified name. /// public virtual Submodule this[string name] { @@ -49,9 +49,9 @@ public virtual Submodule this[string name] } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public IEnumerator GetEnumerator() { return Proxy.git_submodule_foreach(repo.Handle, (h, n) => Utf8Marshaler.FromNative(n)) @@ -60,9 +60,9 @@ public IEnumerator GetEnumerator() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); diff --git a/LibGit2Sharp/SubmoduleExtensions.cs b/LibGit2Sharp/SubmoduleExtensions.cs index 1c77d1b06..377067b24 100644 --- a/LibGit2Sharp/SubmoduleExtensions.cs +++ b/LibGit2Sharp/SubmoduleExtensions.cs @@ -1,7 +1,7 @@ namespace LibGit2Sharp { /// - /// Extensions related to submodules + /// Extensions related to submodules /// public static class SubmoduleExtensions { @@ -9,7 +9,7 @@ public static class SubmoduleExtensions private const SubmoduleStatus WorkDirDirtyMask = SubmoduleStatus.WorkDirFilesIndexDirty | SubmoduleStatus.WorkDirFilesModified | SubmoduleStatus.WorkDirFilesUntracked; /// - /// The submodule is unmodified. + /// The submodule is unmodified. /// public static bool IsUnmodified(this SubmoduleStatus @this) { @@ -17,7 +17,7 @@ public static bool IsUnmodified(this SubmoduleStatus @this) } /// - /// The submodule working directory is dirty. + /// The submodule working directory is dirty. /// public static bool IsWorkingDirectoryDirty(this SubmoduleStatus @this) { diff --git a/LibGit2Sharp/SubmoduleIgnore.cs b/LibGit2Sharp/SubmoduleIgnore.cs index 53123893f..cae886da4 100644 --- a/LibGit2Sharp/SubmoduleIgnore.cs +++ b/LibGit2Sharp/SubmoduleIgnore.cs @@ -1,29 +1,29 @@ namespace LibGit2Sharp { /// - /// Values that could be specified for how closely to examine the - /// working directory when getting submodule status. + /// Values that could be specified for how closely to examine the + /// working directory when getting submodule status. /// public enum SubmoduleIgnore { /// - /// Reset to the last saved ignore rule. + /// Reset to the last saved ignore rule. /// Default = -1, /// - /// Any change or untracked == dirty + /// Any change or untracked == dirty /// None = 0, /// - /// Dirty if tracked files change + /// Dirty if tracked files change /// Untracked = 1, /// - /// Only dirty if HEAD moved + /// Only dirty if HEAD moved /// Dirty = 2, /// - /// Never dirty + /// Never dirty /// All = 3, } diff --git a/LibGit2Sharp/SubmoduleStatus.cs b/LibGit2Sharp/SubmoduleStatus.cs index af4e81a8e..19bee10bb 100644 --- a/LibGit2Sharp/SubmoduleStatus.cs +++ b/LibGit2Sharp/SubmoduleStatus.cs @@ -3,86 +3,86 @@ namespace LibGit2Sharp { /// - /// Calculated status of a submodule in the working directory considering the current and the . + /// Calculated status of a submodule in the working directory considering the current and the . /// [Flags] public enum SubmoduleStatus { /// - /// No submodule changes detected. + /// No submodule changes detected. /// Unmodified = 0, /// - /// Superproject head contains submodule. + /// Superproject head contains submodule. /// /// Can be returned even if ignore is set to "ALL". InHead = (1 << 0), /// - /// Superproject index contains submodule. + /// Superproject index contains submodule. /// /// Can be returned even if ignore is set to "ALL". InIndex = (1 << 1), /// - /// Superproject gitmodules has submodule. + /// Superproject gitmodules has submodule. /// /// Can be returned even if ignore is set to "ALL". InConfig = (1 << 2), /// - /// Superproject working directory has submodule. + /// Superproject working directory has submodule. /// /// Can be returned even if ignore is set to "ALL". InWorkDir = (1 << 3), /// - /// Submodule is in index, but not in head. + /// Submodule is in index, but not in head. /// /// Can be returned unless ignore is set to "ALL". IndexAdded = (1 << 4), /// - /// Submodule is in head, but not in index. + /// Submodule is in head, but not in index. /// /// Can be returned unless ignore is set to "ALL". IndexDeleted = (1 << 5), /// - /// Submodule in index and head don't match. + /// Submodule in index and head don't match. /// /// Can be returned unless ignore is set to "ALL". IndexModified = (1 << 6), /// - /// Submodule in working directory is not initialized. + /// Submodule in working directory is not initialized. /// /// Can be returned unless ignore is set to "ALL". WorkDirUninitialized = (1 << 7), /// - /// Submodule is in working directory, but not index. + /// Submodule is in working directory, but not index. /// /// Can be returned unless ignore is set to "ALL". WorkDirAdded = (1 << 8), /// - /// Submodule is in index, but not working directory. + /// Submodule is in index, but not working directory. /// /// Can be returned unless ignore is set to "ALL". WorkDirDeleted = (1 << 9), /// - /// Submodule in index and working directory head don't match. + /// Submodule in index and working directory head don't match. /// /// Can be returned unless ignore is set to "ALL". WorkDirModified = (1 << 10), /// - /// Submodule working directory index is dirty. + /// Submodule working directory index is dirty. /// /// Can only be returned if ignore is "NONE" or "UNTRACKED". WorkDirFilesIndexDirty = (1 << 11), /// - /// Submodule working directory has modified files. + /// Submodule working directory has modified files. /// /// Can only be returned if ignore is "NONE" or "UNTRACKED". WorkDirFilesModified = (1 << 12), /// - /// Working directory contains untracked files. + /// Working directory contains untracked files. /// /// Can only be returned if ignore is "NONE". WorkDirFilesUntracked = (1 << 13), diff --git a/LibGit2Sharp/SubmoduleUpdate.cs b/LibGit2Sharp/SubmoduleUpdate.cs index d03e3b058..02f290bc8 100644 --- a/LibGit2Sharp/SubmoduleUpdate.cs +++ b/LibGit2Sharp/SubmoduleUpdate.cs @@ -1,28 +1,28 @@ namespace LibGit2Sharp { /// - /// Submodule update rule options. + /// Submodule update rule options. /// public enum SubmoduleUpdate { /// - /// Reset to the last saved update rule. + /// Reset to the last saved update rule. /// Default = -1, /// - /// Checkout the commit recorded in the superproject. + /// Checkout the commit recorded in the superproject. /// Checkout = 0, /// - /// Rebase the current branch of the submodule onto the commit recorded in the superproject. + /// Rebase the current branch of the submodule onto the commit recorded in the superproject. /// Rebase = 1, /// - /// Merge the commit recorded in the superproject into the current branch of the submodule. + /// Merge the commit recorded in the superproject into the current branch of the submodule. /// Merge = 2, /// - /// Do not update the submodule. + /// Do not update the submodule. /// None = 3, } diff --git a/LibGit2Sharp/SymbolicReference.cs b/LibGit2Sharp/SymbolicReference.cs index d98a92ed1..fda8f0dd9 100644 --- a/LibGit2Sharp/SymbolicReference.cs +++ b/LibGit2Sharp/SymbolicReference.cs @@ -4,7 +4,7 @@ namespace LibGit2Sharp { /// - /// A SymbolicReference is a reference that points to another reference + /// A SymbolicReference is a reference that points to another reference /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class SymbolicReference : Reference @@ -12,7 +12,7 @@ public class SymbolicReference : Reference private readonly Reference target; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected SymbolicReference() { } @@ -24,7 +24,7 @@ internal SymbolicReference(string canonicalName, string targetIdentifier, Refere } /// - /// Gets the target of this + /// Gets the target of this /// public virtual Reference Target { @@ -32,9 +32,9 @@ public virtual Reference Target } /// - /// Recursively peels the target of the reference until a direct reference is encountered. + /// Recursively peels the target of the reference until a direct reference is encountered. /// - /// The this points to. + /// The this points to. public override DirectReference ResolveToDirectReference() { return (Target == null) ? null : Target.ResolveToDirectReference(); diff --git a/LibGit2Sharp/Tag.cs b/LibGit2Sharp/Tag.cs index 44b96650b..0cc8cb09e 100644 --- a/LibGit2Sharp/Tag.cs +++ b/LibGit2Sharp/Tag.cs @@ -1,12 +1,12 @@ namespace LibGit2Sharp { /// - /// A Tag + /// A Tag /// public class Tag : ReferenceWrapper { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Tag() { } @@ -17,8 +17,8 @@ internal Tag(Repository repo, Reference reference, string canonicalName) } /// - /// Gets the optional information associated to this tag. - /// When the is a lightweight tag, null is returned. + /// Gets the optional information associated to this tag. + /// When the is a lightweight tag, null is returned. /// public virtual TagAnnotation Annotation { @@ -26,7 +26,7 @@ public virtual TagAnnotation Annotation } /// - /// Gets the that this tag points to. + /// Gets the that this tag points to. /// public virtual GitObject Target { @@ -41,7 +41,7 @@ public virtual GitObject Target } /// - /// Indicates whether the tag holds any metadata. + /// Indicates whether the tag holds any metadata. /// public virtual bool IsAnnotated { @@ -49,8 +49,8 @@ public virtual bool IsAnnotated } /// - /// Removes redundent leading namespaces (regarding the kind of - /// reference being wrapped) from the canonical name. + /// Removes redundent leading namespaces (regarding the kind of + /// reference being wrapped) from the canonical name. /// /// The friendly shortened name protected override string Shorten() diff --git a/LibGit2Sharp/TagAnnotation.cs b/LibGit2Sharp/TagAnnotation.cs index 7e3044643..cd4bd9e30 100644 --- a/LibGit2Sharp/TagAnnotation.cs +++ b/LibGit2Sharp/TagAnnotation.cs @@ -3,7 +3,7 @@ namespace LibGit2Sharp { /// - /// A TagAnnotation + /// A TagAnnotation /// public class TagAnnotation : GitObject { @@ -14,7 +14,7 @@ public class TagAnnotation : GitObject private readonly ILazy lazyTagger; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected TagAnnotation() { } @@ -32,22 +32,22 @@ internal TagAnnotation(Repository repo, ObjectId id) } /// - /// Gets the name of this tag. + /// Gets the name of this tag. /// public virtual string Name { get { return lazyName.Value; } } /// - /// Gets the message of this tag. + /// Gets the message of this tag. /// public virtual string Message { get { return lazyMessage.Value; } } /// - /// Gets the that this tag annotation points to. + /// Gets the that this tag annotation points to. /// public virtual GitObject Target { get { return lazyTarget.Value; } } /// - /// Gets the tagger. + /// Gets the tagger. /// public virtual Signature Tagger { get { return lazyTagger.Value; } } } diff --git a/LibGit2Sharp/TagCollection.cs b/LibGit2Sharp/TagCollection.cs index 0b5387475..e1fd5b50d 100644 --- a/LibGit2Sharp/TagCollection.cs +++ b/LibGit2Sharp/TagCollection.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -9,7 +8,7 @@ namespace LibGit2Sharp { /// - /// The collection of s in a + /// The collection of s in a /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class TagCollection : IEnumerable @@ -17,22 +16,22 @@ public class TagCollection : IEnumerable internal readonly Repository repo; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected TagCollection() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The repo. + /// The repo. internal TagCollection(Repository repo) { this.repo = repo; } /// - /// Gets the with the specified name. + /// Gets the with the specified name. /// public virtual Tag this[string name] { @@ -48,9 +47,9 @@ public virtual Tag this[string name] #region IEnumerable Members /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { return Proxy @@ -60,9 +59,9 @@ public virtual IEnumerator GetEnumerator() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); @@ -71,14 +70,14 @@ IEnumerator IEnumerable.GetEnumerator() #endregion /// - /// Creates an annotated tag with the specified name. + /// Creates an annotated tag with the specified name. /// - /// The name. - /// The target . - /// The tagger. - /// The message. - /// True to allow silent overwriting a potentially existing tag, false otherwise. - /// + /// The name. + /// The target . + /// The tagger. + /// The message. + /// True to allow silent overwriting a potentially existing tag, false otherwise. + /// The added . public virtual Tag Add(string name, GitObject target, Signature tagger, string message, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); @@ -94,12 +93,12 @@ public virtual Tag Add(string name, GitObject target, Signature tagger, string m } /// - /// Creates a lightweight tag with the specified name. + /// Creates a lightweight tag with the specified name. /// - /// The name. - /// The target . - /// True to allow silent overwriting a potentially existing tag, false otherwise. - /// + /// The name. + /// The target . + /// True to allow silent overwriting a potentially existing tag, false otherwise. + /// The added . public virtual Tag Add(string name, GitObject target, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); @@ -111,9 +110,9 @@ public virtual Tag Add(string name, GitObject target, bool allowOverwrite = fals } /// - /// Deletes the tag with the specified name. + /// Deletes the tag with the specified name. /// - /// The tag to delete. + /// The tag to delete. public virtual void Remove(Tag tag) { Ensure.ArgumentNotNull(tag, "tag"); diff --git a/LibGit2Sharp/TagCollectionExtensions.cs b/LibGit2Sharp/TagCollectionExtensions.cs index 413f37e1f..f976e65ef 100644 --- a/LibGit2Sharp/TagCollectionExtensions.cs +++ b/LibGit2Sharp/TagCollectionExtensions.cs @@ -3,19 +3,19 @@ namespace LibGit2Sharp { /// - /// Provides helper overloads to a . + /// Provides helper overloads to a . /// public static class TagCollectionExtensions { /// - /// Creates an annotated tag with the specified name. + /// Creates an annotated tag with the specified name. /// - /// The name. - /// Revparse spec for the target object. - /// The tagger. - /// The message. - /// True to allow silent overwriting a potentially existing tag, false otherwise. - /// The being worked with. + /// The name. + /// Revparse spec for the target object. + /// The tagger. + /// The message. + /// True to allow silent overwriting a potentially existing tag, false otherwise. + /// The being worked with. public static Tag Add(this TagCollection tags, string name, string objectish, Signature tagger, string message, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(objectish, "target"); @@ -26,12 +26,12 @@ public static Tag Add(this TagCollection tags, string name, string objectish, Si } /// - /// Creates a lightweight tag with the specified name. + /// Creates a lightweight tag with the specified name. /// - /// The name. - /// Revparse spec for the target object. - /// True to allow silent overwriting a potentially existing tag, false otherwise. - /// The being worked with. + /// The name. + /// Revparse spec for the target object. + /// True to allow silent overwriting a potentially existing tag, false otherwise. + /// The being worked with. public static Tag Add(this TagCollection tags, string name, string objectish, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(objectish, "objectish"); @@ -42,10 +42,10 @@ public static Tag Add(this TagCollection tags, string name, string objectish, bo } /// - /// Deletes the tag with the specified name. + /// Deletes the tag with the specified name. /// - /// The short or canonical name of the tag to delete. - /// The being worked with. + /// The short or canonical name of the tag to delete. + /// The being worked with. public static void Remove(this TagCollection tags, string name) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); diff --git a/LibGit2Sharp/TagFetchMode.cs b/LibGit2Sharp/TagFetchMode.cs index 6e06eb37e..7455735ae 100644 --- a/LibGit2Sharp/TagFetchMode.cs +++ b/LibGit2Sharp/TagFetchMode.cs @@ -1,25 +1,25 @@ namespace LibGit2Sharp { /// - /// Describe the expected tag retrieval behavior - /// when a fetch operation is being performed. + /// Describe the expected tag retrieval behavior + /// when a fetch operation is being performed. /// public enum TagFetchMode { /// - /// Default behavior. Will automatically retrieve tags that - /// point to objects retrieved during this fetch. + /// Default behavior. Will automatically retrieve tags that + /// point to objects retrieved during this fetch. /// Auto = 0, // GIT_REMOTE_DOWNLOAD_TAGS_AUTO /// - /// No tag will be retrieved. + /// No tag will be retrieved. /// None, // GIT_REMOTE_DOWNLOAD_TAGS_NONE /// - /// All tags will be downloaded, but _only_ tags, along with - /// all the objects these tags are pointing to. + /// All tags will be downloaded, but _only_ tags, along with + /// all the objects these tags are pointing to. /// All, // GIT_REMOTE_DOWNLOAD_TAGS_ALL } diff --git a/LibGit2Sharp/TransferCallbacks.cs b/LibGit2Sharp/TransferCallbacks.cs index 311870629..46497ba6b 100644 --- a/LibGit2Sharp/TransferCallbacks.cs +++ b/LibGit2Sharp/TransferCallbacks.cs @@ -5,20 +5,20 @@ namespace LibGit2Sharp { /// - /// Class to handle the mapping between libgit2 git_transfer_progress_callback function and - /// a corresponding . Generates a delegate that - /// wraps the delegate with a delegate that matches - /// the git_transfer_progress_callback signature. + /// Class to handle the mapping between libgit2 git_transfer_progress_callback function and + /// a corresponding . Generates a delegate that + /// wraps the delegate with a delegate that matches + /// the git_transfer_progress_callback signature. /// internal class TransferCallbacks { /// - /// Managed delegate to be called in response to a git_transfer_progress_callback callback from libgit2. + /// Managed delegate to be called in response to a git_transfer_progress_callback callback from libgit2. /// private readonly TransferProgressHandler onTransferProgress; /// - /// Constructor to set up the native callback given managed delegate. + /// Constructor to set up the native callback given managed delegate. /// /// The delegate that the git_transfer_progress_callback will call. private TransferCallbacks(TransferProgressHandler onTransferProgress) @@ -27,9 +27,9 @@ private TransferCallbacks(TransferProgressHandler onTransferProgress) } /// - /// Generates a delegate that matches the native git_transfer_progress_callback function's signature and wraps the delegate. + /// Generates a delegate that matches the native git_transfer_progress_callback function's signature and wraps the delegate. /// - /// The delegate to call in responde to a the native git_transfer_progress_callback callback. + /// The delegate to call in responde to a the native git_transfer_progress_callback callback. /// A delegate method with a signature that matches git_transfer_progress_callback. internal static NativeMethods.git_transfer_progress_callback GenerateCallback(TransferProgressHandler onTransferProgress) { @@ -42,11 +42,11 @@ internal static NativeMethods.git_transfer_progress_callback GenerateCallback(Tr } /// - /// The delegate with the signature that matches the native git_transfer_progress_callback function's signature. + /// The delegate with the signature that matches the native git_transfer_progress_callback function's signature. /// - /// structure containing progress information. + /// structure containing progress information. /// Payload data. - /// the result of the wrapped + /// the result of the wrapped private int OnGitTransferProgress(ref GitTransferProgress progress, IntPtr payload) { return onTransferProgress(new TransferProgress(progress)); diff --git a/LibGit2Sharp/TransferProgress.cs b/LibGit2Sharp/TransferProgress.cs index 25603e97c..4ef072a8a 100644 --- a/LibGit2Sharp/TransferProgress.cs +++ b/LibGit2Sharp/TransferProgress.cs @@ -3,20 +3,20 @@ namespace LibGit2Sharp { /// - /// Expose progress values from a fetch operation. + /// Expose progress values from a fetch operation. /// public class TransferProgress { private GitTransferProgress gitTransferProgress; /// - /// Empty constructor. + /// Empty constructor. /// protected TransferProgress() { } /// - /// Constructor. + /// Constructor. /// internal TransferProgress(GitTransferProgress gitTransferProgress) { @@ -24,7 +24,7 @@ internal TransferProgress(GitTransferProgress gitTransferProgress) } /// - /// Total number of objects. + /// Total number of objects. /// public virtual int TotalObjects { @@ -35,7 +35,7 @@ public virtual int TotalObjects } /// - /// Number of objects indexed. + /// Number of objects indexed. /// public virtual int IndexedObjects { @@ -46,7 +46,7 @@ public virtual int IndexedObjects } /// - /// Number of objects received. + /// Number of objects received. /// public virtual int ReceivedObjects { @@ -57,7 +57,7 @@ public virtual int ReceivedObjects } /// - /// Number of bytes received. + /// Number of bytes received. /// public virtual long ReceivedBytes { diff --git a/LibGit2Sharp/Tree.cs b/LibGit2Sharp/Tree.cs index 4ce8e0128..c70eb9ee1 100644 --- a/LibGit2Sharp/Tree.cs +++ b/LibGit2Sharp/Tree.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -10,7 +9,7 @@ namespace LibGit2Sharp { /// - /// A container which references a list of other s and s. + /// A container which references a list of other s and s. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class Tree : GitObject, IEnumerable @@ -20,7 +19,7 @@ public class Tree : GitObject, IEnumerable private readonly ILazy lazyCount; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected Tree() { } @@ -34,15 +33,15 @@ internal Tree(Repository repo, ObjectId id, FilePath path) } /// - /// Gets the number of immediately under this . + /// Gets the number of immediately under this . /// public virtual int Count { get { return lazyCount.Value; } } /// - /// Gets the pointed at by the in this instance. + /// Gets the pointed at by the in this instance. /// - /// The relative path to the from this instance. - /// null if nothing has been found, the otherwise. + /// The relative path to the from this instance. + /// null if nothing has been found, the otherwise. public virtual TreeEntry this[string relativePath] { get { return RetrieveFromPath(relativePath); } @@ -69,36 +68,6 @@ private TreeEntry RetrieveFromPath(FilePath relativePath) } } - /// - /// Gets the s immediately under this . - /// - [Obsolete("This property will be removed in the next release.")] - public virtual IEnumerable Trees - { - get - { - return this - .Where(e => e.TargetType == TreeEntryTargetType.Tree) - .Select(e => e.Target) - .Cast(); - } - } - - /// - /// Gets the s immediately under this . - /// - [Obsolete("This property will be removed in the next release.")] - public virtual IEnumerable Blobs - { - get - { - return this - .Where(e => e.TargetType == TreeEntryTargetType.Blob) - .Select(e => e.Target) - .Cast(); - } - } - internal string Path { get { return path.Native; } @@ -107,9 +76,9 @@ internal string Path #region IEnumerable Members /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { using (var obj = new ObjectSafeWrapper(Id, repo.Handle)) @@ -123,9 +92,9 @@ public virtual IEnumerator GetEnumerator() } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); diff --git a/LibGit2Sharp/TreeChanges.cs b/LibGit2Sharp/TreeChanges.cs index c9b498529..7b9718c36 100644 --- a/LibGit2Sharp/TreeChanges.cs +++ b/LibGit2Sharp/TreeChanges.cs @@ -11,8 +11,8 @@ namespace LibGit2Sharp { /// - /// Holds the result of a diff between two trees. - /// Changes at the granularity of the file can be obtained through the different sub-collections , and . + /// Holds the result of a diff between two trees. + /// Changes at the granularity of the file can be obtained through the different sub-collections , and . /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class TreeChanges : IEnumerable @@ -43,7 +43,7 @@ private static IDictionary> Bu } /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected TreeChanges() { } @@ -120,18 +120,18 @@ private void AddFileChange(GitDiffDelta delta) #region IEnumerable Members /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { return changes.Values.GetEnumerator(); } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an enumerator that iterates through the collection. /// - /// An object that can be used to iterate through the collection. + /// An object that can be used to iterate through the collection. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); @@ -140,7 +140,7 @@ IEnumerator IEnumerable.GetEnumerator() #endregion /// - /// Gets the corresponding to the specified . + /// Gets the corresponding to the specified . /// public virtual TreeEntryChanges this[string path] { @@ -162,7 +162,7 @@ private TreeEntryChanges this[FilePath path] } /// - /// List of that have been been added. + /// List of that have been been added. /// public virtual IEnumerable Added { @@ -170,7 +170,7 @@ public virtual IEnumerable Added } /// - /// List of that have been deleted. + /// List of that have been deleted. /// public virtual IEnumerable Deleted { @@ -178,7 +178,7 @@ public virtual IEnumerable Deleted } /// - /// List of that have been modified. + /// List of that have been modified. /// public virtual IEnumerable Modified { @@ -186,7 +186,7 @@ public virtual IEnumerable Modified } /// - /// List of which type have been changed. + /// List of which type have been changed. /// public virtual IEnumerable TypeChanged { @@ -194,7 +194,7 @@ public virtual IEnumerable TypeChanged } /// - /// The total number of lines added in this diff. + /// The total number of lines added in this diff. /// public virtual int LinesAdded { @@ -202,7 +202,7 @@ public virtual int LinesAdded } /// - /// The total number of lines added in this diff. + /// The total number of lines added in this diff. /// public virtual int LinesDeleted { @@ -210,7 +210,7 @@ public virtual int LinesDeleted } /// - /// The full patch file of this diff. + /// The full patch file of this diff. /// public virtual string Patch { diff --git a/LibGit2Sharp/TreeDefinition.cs b/LibGit2Sharp/TreeDefinition.cs index 780f23233..bd29a20ee 100644 --- a/LibGit2Sharp/TreeDefinition.cs +++ b/LibGit2Sharp/TreeDefinition.cs @@ -9,7 +9,7 @@ namespace LibGit2Sharp { /// - /// Holds the meta data of a . + /// Holds the meta data of a . /// public class TreeDefinition { @@ -17,10 +17,10 @@ public class TreeDefinition private readonly Dictionary unwrappedTrees = new Dictionary(); /// - /// Builds a from an existing . + /// Builds a from an existing . /// - /// The to be processed. - /// A new holding the meta data of the . + /// The to be processed. + /// A new holding the meta data of the . public static TreeDefinition From(Tree tree) { Ensure.ArgumentNotNull(tree, "tree"); @@ -35,6 +35,18 @@ public static TreeDefinition From(Tree tree) return td; } + /// + /// Builds a from a 's . + /// + /// The whose tree is to be processed + /// A new holding the meta data of the 's . + public static TreeDefinition From(Commit commit) + { + Ensure.ArgumentNotNull(commit, "commit"); + + return From(commit.Tree); + } + private void AddEntry(string targetTreeEntryName, TreeEntryDefinition treeEntryDefinition) { if (entries.ContainsKey(targetTreeEntryName)) @@ -47,7 +59,7 @@ private void AddEntry(string targetTreeEntryName, TreeEntryDefinition treeEntryD } /// - /// Removes a located the specified path. + /// Removes a located the specified path. /// /// The path within this . /// The current . @@ -87,7 +99,7 @@ public virtual TreeDefinition Remove(string treeEntryPath) } /// - /// Adds or replaces a at the specified location. + /// Adds or replaces a at the specified location. /// /// The path within this . /// The to be stored at the described location. @@ -126,7 +138,7 @@ public virtual TreeDefinition Add(string targetTreeEntryPath, TreeEntryDefinitio } /// - /// Adds or replaces a , dynamically built from the provided , at the specified location. + /// Adds or replaces a , dynamically built from the provided , at the specified location. /// /// The path within this . /// The to be stored at the described location. @@ -143,11 +155,11 @@ public virtual TreeDefinition Add(string targetTreeEntryPath, Blob blob, Mode mo } /// - /// Adds or replaces a , dynamically built from the content of the file, at the specified location. + /// Adds or replaces a , dynamically built from the content of the file, at the specified location. /// /// The path within this . /// The path to the file from which a will be built and stored at the described location. A relative path is allowed to be passed if the target - /// is a standard, non-bare, repository. The path will then be considered as a path relative to the root of the working directory. + /// is a standard, non-bare, repository. The path will then be considered as a path relative to the root of the working directory. /// The file related attributes. /// The current . public virtual TreeDefinition Add(string targetTreeEntryPath, string filePath, Mode mode) @@ -160,7 +172,7 @@ public virtual TreeDefinition Add(string targetTreeEntryPath, string filePath, M } /// - /// Adds or replaces a , dynamically built from the provided , at the specified location. + /// Adds or replaces a , dynamically built from the provided , at the specified location. /// /// The path within this . /// The to be stored at the described location. @@ -175,7 +187,7 @@ public virtual TreeDefinition Add(string targetTreeEntryPath, Tree tree) } /// - /// Adds or replaces a gitlink equivalent to . + /// Adds or replaces a gitlink equivalent to . /// /// The to be linked. /// The current . @@ -187,9 +199,9 @@ public virtual TreeDefinition Add(Submodule submodule) } /// - /// Adds or replaces a gitlink , - /// referencing the commit identified by , - /// at the specified location. + /// Adds or replaces a gitlink , + /// referencing the commit identified by , + /// at the specified location. /// /// The path within this . /// The of the commit to be linked at the described location. @@ -306,7 +318,7 @@ private void WrapTree(string entryName, TreeEntryDefinition treeEntryDefinition) } /// - /// Retrieves the located the specified path. + /// Retrieves the located the specified path. /// /// The path within this . /// The found if any; null otherwise. diff --git a/LibGit2Sharp/TreeEntry.cs b/LibGit2Sharp/TreeEntry.cs index 28baaa80c..ffdf22d3d 100644 --- a/LibGit2Sharp/TreeEntry.cs +++ b/LibGit2Sharp/TreeEntry.cs @@ -7,7 +7,7 @@ namespace LibGit2Sharp { /// - /// Representation of an entry in a . + /// Representation of an entry in a . /// public class TreeEntry : IEquatable { @@ -21,7 +21,7 @@ public class TreeEntry : IEquatable new LambdaEqualityHelper(x => x.Name, x => x.parentTreeId); /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected TreeEntry() { } @@ -43,23 +43,23 @@ internal TreeEntry(SafeHandle obj, ObjectId parentTreeId, Repository repo, FileP } /// - /// Gets the file mode. + /// Gets the file mode. /// public virtual Mode Mode { get; private set; } /// - /// Gets the filename. + /// Gets the filename. /// public virtual string Name { get; private set; } /// - /// Gets the path. - /// The path is expressed in a relative form from the latest known . Path segments are separated with a forward or backslash, depending on the OS the libray is being run on."/> + /// Gets the path. + /// The path is expressed in a relative form from the latest known . Path segments are separated with a forward or backslash, depending on the OS the libray is being run on."/> /// public virtual string Path { get { return path.Value; } } /// - /// Gets the being pointed at. + /// Gets the being pointed at. /// public virtual GitObject Target { get { return target.Value; } } @@ -69,7 +69,7 @@ internal ObjectId TargetId } /// - /// Gets the of the being pointed at. + /// Gets the of the being pointed at. /// public virtual TreeEntryTargetType TargetType { get; private set; } @@ -93,27 +93,27 @@ private GitObject RetrieveTreeEntryTarget() } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as TreeEntry); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(TreeEntry other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -122,10 +122,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(TreeEntry left, TreeEntry right) { @@ -133,10 +133,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(TreeEntry left, TreeEntry right) { diff --git a/LibGit2Sharp/TreeEntryChanges.cs b/LibGit2Sharp/TreeEntryChanges.cs index 24bc2c634..4ce5547d4 100644 --- a/LibGit2Sharp/TreeEntryChanges.cs +++ b/LibGit2Sharp/TreeEntryChanges.cs @@ -5,13 +5,13 @@ namespace LibGit2Sharp { /// - /// Holds the changes between two versions of a tree entry. + /// Holds the changes between two versions of a tree entry. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class TreeEntryChanges : Changes { /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected TreeEntryChanges() { } @@ -29,37 +29,37 @@ internal TreeEntryChanges(FilePath path, Mode mode, ObjectId oid, ChangeKind sta } /// - /// The new path. + /// The new path. /// public virtual string Path { get; private set; } /// - /// The new . + /// The new . /// public virtual Mode Mode { get; private set; } /// - /// The new content hash. + /// The new content hash. /// public virtual ObjectId Oid { get; private set; } /// - /// The kind of change that has been done (added, deleted, modified ...). + /// The kind of change that has been done (added, deleted, modified ...). /// public virtual ChangeKind Status { get; private set; } /// - /// The old path. + /// The old path. /// public virtual string OldPath { get; private set; } /// - /// The old . + /// The old . /// public virtual Mode OldMode { get; private set; } /// - /// The old content hash. + /// The old content hash. /// public virtual ObjectId OldOid { get; private set; } diff --git a/LibGit2Sharp/TreeEntryDefinition.cs b/LibGit2Sharp/TreeEntryDefinition.cs index 13e2fd2ea..e97066824 100644 --- a/LibGit2Sharp/TreeEntryDefinition.cs +++ b/LibGit2Sharp/TreeEntryDefinition.cs @@ -5,7 +5,7 @@ namespace LibGit2Sharp { /// - /// Holds the meta data of a . + /// Holds the meta data of a . /// public class TreeEntryDefinition : IEquatable { @@ -17,24 +17,24 @@ public class TreeEntryDefinition : IEquatable internal static readonly Enum[] BlobModes = new Enum[] { Mode.NonExecutableFile, Mode.ExecutableFile, Mode.NonExecutableGroupWritableFile, Mode.SymbolicLink }; /// - /// Needed for mocking purposes. + /// Needed for mocking purposes. /// protected TreeEntryDefinition() { } /// - /// Gets file mode. + /// Gets file mode. /// public virtual Mode Mode { get; private set; } /// - /// Gets the of the target being pointed at. + /// Gets the of the target being pointed at. /// public virtual TreeEntryTargetType TargetType { get; private set; } /// - /// Gets the of the target being pointed at. + /// Gets the of the target being pointed at. /// public virtual ObjectId TargetId { get; private set; } @@ -99,27 +99,27 @@ internal static TreeEntryDefinition From(Tree tree) } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return Equals(obj as TreeEntryDefinition); } /// - /// Determines whether the specified is equal to the current . + /// Determines whether the specified is equal to the current . /// - /// The to compare with the current . - /// True if the specified is equal to the current ; otherwise, false. + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(TreeEntryDefinition other) { return equalityHelper.Equals(this, other); } /// - /// Returns the hash code for this instance. + /// Returns the hash code for this instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() @@ -128,10 +128,10 @@ public override int GetHashCode() } /// - /// Tests if two are equal. + /// Tests if two are equal. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are equal; false otherwise. public static bool operator ==(TreeEntryDefinition left, TreeEntryDefinition right) { @@ -139,10 +139,10 @@ public override int GetHashCode() } /// - /// Tests if two are different. + /// Tests if two are different. /// - /// First to compare. - /// Second to compare. + /// First to compare. + /// Second to compare. /// True if the two objects are different; false otherwise. public static bool operator !=(TreeEntryDefinition left, TreeEntryDefinition right) { diff --git a/LibGit2Sharp/TreeEntryTargetType.cs b/LibGit2Sharp/TreeEntryTargetType.cs index b6a5a2d84..0dfca339f 100644 --- a/LibGit2Sharp/TreeEntryTargetType.cs +++ b/LibGit2Sharp/TreeEntryTargetType.cs @@ -4,28 +4,22 @@ namespace LibGit2Sharp { /// - /// Underlying type of the target a + /// Underlying type of the target a /// public enum TreeEntryTargetType { /// - /// A file revision object. + /// A file revision object. /// - Blob = 1, + Blob, /// - /// A tree object. + /// A tree object. /// Tree, /// - /// An annotated tag object. - /// - [Obsolete("This entry will be removed in the next release as it is not a valid TreeEntryTargetType.")] - Tag, - - /// - /// A pointer to a commit object in another repository. + /// A pointer to a commit object in another repository. /// GitLink, } diff --git a/LibGit2Sharp/UniqueIdentifier.targets b/LibGit2Sharp/UniqueIdentifier.targets index 8b97c65d3..f6eb926e3 100644 --- a/LibGit2Sharp/UniqueIdentifier.targets +++ b/LibGit2Sharp/UniqueIdentifier.targets @@ -6,7 +6,14 @@ - Core\UniqueIdentifier.cs + + . + $(MSBuildThisFileDirectory) + $(LibGit2SharpPath)\Core\UniqueIdentifier.cs $(CoreCompileDependsOn);GenerateUniqueIdentifierCs $(CoreCleanDependsOn);CleanUniqueIdentifierCs diff --git a/LibGit2Sharp/UnmatchedPathException.cs b/LibGit2Sharp/UnmatchedPathException.cs index 38f33c036..50d8cd70b 100644 --- a/LibGit2Sharp/UnmatchedPathException.cs +++ b/LibGit2Sharp/UnmatchedPathException.cs @@ -5,42 +5,42 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when an explicit path or a list of explicit paths could not be matched. + /// The exception that is thrown when an explicit path or a list of explicit paths could not be matched. /// [Serializable] public class UnmatchedPathException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public UnmatchedPathException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public UnmatchedPathException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public UnmatchedPathException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected UnmatchedPathException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/UnmergedIndexEntriesException.cs b/LibGit2Sharp/UnmergedIndexEntriesException.cs index 5cd7ff217..0963c6b87 100644 --- a/LibGit2Sharp/UnmergedIndexEntriesException.cs +++ b/LibGit2Sharp/UnmergedIndexEntriesException.cs @@ -5,43 +5,43 @@ namespace LibGit2Sharp { /// - /// The exception that is thrown when an operation that requires a fully merged index - /// is performed against an index with unmerged entries + /// The exception that is thrown when an operation that requires a fully merged index + /// is performed against an index with unmerged entries /// [Serializable] public class UnmergedIndexEntriesException : LibGit2SharpException { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public UnmergedIndexEntriesException() { } /// - /// Initializes a new instance of the class with a specified error message. + /// Initializes a new instance of the class with a specified error message. /// - /// A message that describes the error. + /// A message that describes the error. public UnmergedIndexEntriesException(string message) : base(message) { } /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. public UnmergedIndexEntriesException(string message, Exception innerException) : base(message, innerException) { } /// - /// Initializes a new instance of the class with a serialized data. + /// Initializes a new instance of the class with a serialized data. /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. protected UnmergedIndexEntriesException(SerializationInfo info, StreamingContext context) : base(info, context) { diff --git a/LibGit2Sharp/UserCanceledException.cs b/LibGit2Sharp/UserCanceledException.cs new file mode 100644 index 000000000..a5c226679 --- /dev/null +++ b/LibGit2Sharp/UserCanceledException.cs @@ -0,0 +1,54 @@ +using System; +using System.Runtime.Serialization; +using LibGit2Sharp.Core; + +namespace LibGit2Sharp +{ + /// + /// The exception that is thrown when an operation is canceled. + /// + [Serializable] + public class UserCancelledException : LibGit2SharpException + { + /// + /// Initializes a new instance of the class. + /// + public UserCancelledException() + { + } + + /// + /// Initializes a new instance of the class with a specified error message. + /// + /// A message that describes the error. + public UserCancelledException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + public UserCancelledException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class with a serialized data. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + protected UserCancelledException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + internal UserCancelledException(string message, GitErrorCode code, GitErrorCategory category) + : base(message, code, category) + { + } + } +} diff --git a/LibGit2Sharp/libgit2_hash.txt b/LibGit2Sharp/libgit2_hash.txt index e7f26f1d5..d618000b7 100644 --- a/LibGit2Sharp/libgit2_hash.txt +++ b/LibGit2Sharp/libgit2_hash.txt @@ -1 +1 @@ -9d9fff3c3dbc207a8a2ee2114eab19086afecb6e +794003650e041668405a5ee12a7f763dca951758 diff --git a/UpdateLibgit2ToSha.ps1 b/UpdateLibgit2ToSha.ps1 index bf35ca98c..ff5974943 100644 --- a/UpdateLibgit2ToSha.ps1 +++ b/UpdateLibgit2ToSha.ps1 @@ -5,6 +5,8 @@ Desired libgit2 version. This is run through `git rev-parse`, so branch names are okay too. .PARAMETER vs Version of Visual Studio project files to generate. Cmake supports "10" (default) and "11". +.PARAMETER libgit2Name + The base name (i.e without the file extension) of the libgit2 DLL to generate. Default is to use git2-$suffix, where $suffix is the first 7 characters of the SHA1 of the corresponding libgi2 commit as the suffix. .PARAMETER test If set, run the libgit2 tests on the desired version. .PARAMETER debug @@ -14,6 +16,7 @@ Param( [string]$sha = 'HEAD', [string]$vs = '10', + [string]$libgit2Name = '', [switch]$test, [switch]$debug ) @@ -91,6 +94,22 @@ function Find-Git { Push-Location $libgit2Directory +function Ensure-Property($expected, $propertyValue, $propertyName, $path) { + if ($propertyValue -eq $expected) { + return + } + + throw "Error: Invalid '$propertyName' property in generated '$path' (Expected: $expected - Actual: $propertyValue)" +} + +function Assert-Consistent-Naming($expected, $path) { + $dll = get-item $path + + Ensure-Property $expected $dll.Name "Name" $dll.Fullname + Ensure-Property $expected $dll.VersionInfo.InternalName "VersionInfo.InternalName" $dll.Fullname + Ensure-Property $expected $dll.VersionInfo.OriginalFilename "VersionInfo.OriginalFilename" $dll.Fullname +} + & { trap { Pop-Location @@ -111,7 +130,12 @@ Push-Location $libgit2Directory popd break } - $shortsha = $sha.Substring(0,7) + + if(![string]::IsNullOrEmpty($libgit2Name)) { + $binaryFilename = $libgit2Name + } else { + $binaryFilename = "git2-" + $sha.Substring(0,7) + } Write-Output "Checking out $sha..." Run-Command -Quiet -Fatal { & $git checkout $sha } @@ -120,10 +144,11 @@ Push-Location $libgit2Directory Run-Command -Quiet { & remove-item build -recurse -force } Run-Command -Quiet { & mkdir build } cd build - Run-Command -Quiet -Fatal { & $cmake -G "Visual Studio $vs" -D THREADSAFE=ON -D "BUILD_CLAR=$build_clar" -D "SONAME_APPEND=$shortsha" .. } + Run-Command -Quiet -Fatal { & $cmake -G "Visual Studio $vs" -D THREADSAFE=ON -D "BUILD_CLAR=$build_clar" -D "LIBGIT2_FILENAME=$binaryFilename" -DSTDCALL=ON .. } Run-Command -Quiet -Fatal { & $cmake --build . --config $configuration } if ($test.IsPresent) { Run-Command -Quiet -Fatal { & $ctest -V . } } cd $configuration + Assert-Consistent-Naming "$binaryFilename.dll" "*.dll" Run-Command -Quiet { & rm *.exp } Run-Command -Quiet { & rm $x86Directory\* } Run-Command -Quiet -Fatal { & copy -fo * $x86Directory } @@ -132,10 +157,11 @@ Push-Location $libgit2Directory cd .. Run-Command -Quiet { & mkdir build64 } cd build64 - Run-Command -Quiet -Fatal { & $cmake -G "Visual Studio $vs Win64" -D THREADSAFE=ON -D "BUILD_CLAR=$build_clar" -D "SONAME_APPEND=$shortsha" ../.. } + Run-Command -Quiet -Fatal { & $cmake -G "Visual Studio $vs Win64" -D THREADSAFE=ON -D "BUILD_CLAR=$build_clar" -D "LIBGIT2_FILENAME=$binaryFilename" -DSTDCALL=ON ../.. } Run-Command -Quiet -Fatal { & $cmake --build . --config $configuration } if ($test.IsPresent) { Run-Command -Quiet -Fatal { & $ctest -V . } } cd $configuration + Assert-Consistent-Naming "$binaryFilename.dll" "*.dll" Run-Command -Quiet { & rm *.exp } Run-Command -Quiet { & rm $x64Directory\* } Run-Command -Quiet -Fatal { & copy -fo * $x64Directory } @@ -147,7 +173,7 @@ namespace LibGit2Sharp.Core { internal static class NativeDllName { - public const string Name = "git2-$shortsha"; + public const string Name = "$binaryFilename"; } } "@ diff --git a/build.libgit2sharp.sh b/build.libgit2sharp.sh old mode 100644 new mode 100755 index c1b151ed8..7d4994cff --- a/build.libgit2sharp.sh +++ b/build.libgit2sharp.sh @@ -8,7 +8,7 @@ SHORTSHA=${LIBGIT2SHA:0:7} rm -rf cmake-build mkdir cmake-build && cd cmake-build -cmake -DBUILD_SHARED_LIBS:BOOL=ON -DTHREADSAFE:BOOL=ON -DBUILD_CLAR:BOOL=OFF -DCMAKE_INSTALL_PREFIX=./libgit2-bin -DSONAME_APPEND=$SHORTSHA ../libgit2 +cmake -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DTHREADSAFE:BOOL=ON -DBUILD_CLAR:BOOL=OFF -DCMAKE_INSTALL_PREFIX=./libgit2-bin -DLIBGIT2_FILENAME=git2-$SHORTSHA ../libgit2 cmake --build . --target install LD_LIBRARY_PATH=$PWD/libgit2-bin/lib:$LD_LIBRARY_PATH diff --git a/libgit2 b/libgit2 index 9d9fff3c3..794003650 160000 --- a/libgit2 +++ b/libgit2 @@ -1 +1 @@ -Subproject commit 9d9fff3c3dbc207a8a2ee2114eab19086afecb6e +Subproject commit 794003650e041668405a5ee12a7f763dca951758