From 7a9d52bcd949d0f1ae9e93d695210cf323636cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 23 Mar 2016 22:26:55 +0100 Subject: [PATCH 1/3] Move Stage and Unstage to Commands and keep the index in memory These commands work on a repository, and we can leave the Index be the data structure. Thus it is no longer written to disk after every change. --- LibGit2Sharp.Tests/AttributesFixture.cs | 2 +- LibGit2Sharp.Tests/BlobFixture.cs | 6 +- LibGit2Sharp.Tests/BranchFixture.cs | 2 +- LibGit2Sharp.Tests/CheckoutFixture.cs | 40 ++-- LibGit2Sharp.Tests/CherryPickFixture.cs | 2 +- LibGit2Sharp.Tests/CommitFixture.cs | 24 +-- LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs | 10 +- LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs | 64 +++--- LibGit2Sharp.Tests/FileHistoryFixture.cs | 2 +- LibGit2Sharp.Tests/FilterFixture.cs | 6 +- .../FilterSubstitutionCipherFixture.cs | 4 +- LibGit2Sharp.Tests/IgnoreFixture.cs | 2 +- LibGit2Sharp.Tests/IndexFixture.cs | 31 +-- LibGit2Sharp.Tests/MergeFixture.cs | 8 +- LibGit2Sharp.Tests/ObjectDatabaseFixture.cs | 2 +- LibGit2Sharp.Tests/OdbBackendFixture.cs | 4 +- LibGit2Sharp.Tests/PushFixture.cs | 4 +- LibGit2Sharp.Tests/RebaseFixture.cs | 36 ++-- LibGit2Sharp.Tests/ReflogFixture.cs | 6 +- LibGit2Sharp.Tests/RemoveFixture.cs | 10 +- LibGit2Sharp.Tests/RepositoryFixture.cs | 2 +- .../RepositoryOptionsFixture.cs | 6 +- LibGit2Sharp.Tests/ResetHeadFixture.cs | 4 +- LibGit2Sharp.Tests/StageFixture.cs | 46 ++-- LibGit2Sharp.Tests/StashFixture.cs | 18 +- LibGit2Sharp.Tests/StatusFixture.cs | 18 +- LibGit2Sharp.Tests/SubmoduleFixture.cs | 4 +- LibGit2Sharp.Tests/UnstageFixture.cs | 46 ++-- LibGit2Sharp/Commands/Stage.cs | 204 ++++++++++++++++++ LibGit2Sharp/IRepository.cs | 4 + LibGit2Sharp/Index.cs | 49 ++--- LibGit2Sharp/LibGit2Sharp.csproj | 5 +- LibGit2Sharp/Repository.cs | 106 ++------- LibGit2Sharp/RepositoryExtensions.cs | 4 + 34 files changed, 446 insertions(+), 335 deletions(-) create mode 100644 LibGit2Sharp/Commands/Stage.cs diff --git a/LibGit2Sharp.Tests/AttributesFixture.cs b/LibGit2Sharp.Tests/AttributesFixture.cs index 8a0a15dce..3ac8326d3 100644 --- a/LibGit2Sharp.Tests/AttributesFixture.cs +++ b/LibGit2Sharp.Tests/AttributesFixture.cs @@ -29,7 +29,7 @@ private static void AssertNormalization(IRepository repo, string filename, bool Touch(repo.Info.WorkingDirectory, filename, sb.ToString()); - repo.Stage(filename); + Commands.Stage(repo, filename); IndexEntry entry = repo.Index[filename]; Assert.NotNull(entry); diff --git a/LibGit2Sharp.Tests/BlobFixture.cs b/LibGit2Sharp.Tests/BlobFixture.cs index 4c984bd34..371e50c51 100644 --- a/LibGit2Sharp.Tests/BlobFixture.cs +++ b/LibGit2Sharp.Tests/BlobFixture.cs @@ -63,7 +63,7 @@ public void CanGetBlobAsTextWithVariousEncodings(string encodingName, int expect var bomPath = Touch(repo.Info.WorkingDirectory, bomFile, content, encoding); Assert.Equal(expectedContentBytes, File.ReadAllBytes(bomPath).Length); - repo.Stage(bomFile); + Commands.Stage(repo, bomFile); var commit = repo.Commit("bom", Constants.Signature, Constants.Signature); var blob = (Blob)commit.Tree[bomFile].Target; @@ -190,7 +190,7 @@ public void CanStageAFileGeneratedFromABlobContentStream() File.AppendAllText(Path.Combine(repo.Info.WorkingDirectory, "small.txt"), sb.ToString()); } - repo.Stage("small.txt"); + Commands.Stage(repo, "small.txt"); IndexEntry entry = repo.Index["small.txt"]; Assert.Equal("baae1fb3760a73481ced1fa03dc15614142c19ef", entry.Id.Sha); @@ -202,7 +202,7 @@ public void CanStageAFileGeneratedFromABlobContentStream() CopyStream(stream, file); } - repo.Stage("small.fromblob.txt"); + Commands.Stage(repo, "small.fromblob.txt"); IndexEntry newentry = repo.Index["small.fromblob.txt"]; Assert.Equal("baae1fb3760a73481ced1fa03dc15614142c19ef", newentry.Id.Sha); diff --git a/LibGit2Sharp.Tests/BranchFixture.cs b/LibGit2Sharp.Tests/BranchFixture.cs index 99eea1b29..1fd943c00 100644 --- a/LibGit2Sharp.Tests/BranchFixture.cs +++ b/LibGit2Sharp.Tests/BranchFixture.cs @@ -1137,7 +1137,7 @@ public void TrackedBranchExistsFromDefaultConfigInEmptyClone() Assert.Equal("origin", repo.Head.RemoteName); Touch(repo.Info.WorkingDirectory, "a.txt", "a"); - repo.Stage("a.txt"); + Commands.Stage(repo, "a.txt"); repo.Commit("A file", Constants.Signature, Constants.Signature); Assert.NotNull(repo.Head.Tip); diff --git a/LibGit2Sharp.Tests/CheckoutFixture.cs b/LibGit2Sharp.Tests/CheckoutFixture.cs index 80cb9727d..2d0789984 100644 --- a/LibGit2Sharp.Tests/CheckoutFixture.cs +++ b/LibGit2Sharp.Tests/CheckoutFixture.cs @@ -184,7 +184,7 @@ public void CheckoutRemovesExtraFilesInWorkingDirectory() string newFileFullPath = Touch( repo.Info.WorkingDirectory, "b.txt", "hello from master branch!\n"); - repo.Stage(newFileFullPath); + Commands.Stage(repo, newFileFullPath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); // Checkout other_branch @@ -212,7 +212,7 @@ public void CheckoutUpdatesModifiedFilesInWorkingDirectory() string fullPath = Touch( repo.Info.WorkingDirectory, originalFilePath, "Update : hello from master branch!\n"); - repo.Stage(fullPath); + Commands.Stage(repo, fullPath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); // Checkout other_branch @@ -254,7 +254,7 @@ public void CanForcefullyCheckoutWithConflictingStagedChanges() // Add change to master. Touch(repo.Info.WorkingDirectory, originalFilePath, originalFileContent); - repo.Stage(originalFilePath); + Commands.Stage(repo, originalFilePath); repo.Commit("change in master", Constants.Signature, Constants.Signature); // Checkout otherBranch. @@ -262,7 +262,7 @@ public void CanForcefullyCheckoutWithConflictingStagedChanges() // Add change to otherBranch. Touch(repo.Info.WorkingDirectory, originalFilePath, alternateFileContent); - repo.Stage(originalFilePath); + Commands.Stage(repo, originalFilePath); // Assert that normal checkout throws exception // for the conflict. @@ -287,7 +287,7 @@ public void CheckingOutWithMergeConflictsThrows() using (var repo = new Repository(repoPath)) { Touch(repo.Info.WorkingDirectory, originalFilePath, "Hello\n"); - repo.Stage(originalFilePath); + Commands.Stage(repo, originalFilePath); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); // Create 2nd branch @@ -295,7 +295,7 @@ public void CheckingOutWithMergeConflictsThrows() // Update file in main Touch(repo.Info.WorkingDirectory, originalFilePath, "Hello from master!\n"); - repo.Stage(originalFilePath); + Commands.Stage(repo, originalFilePath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); // Checkout branch2 @@ -307,7 +307,7 @@ public void CheckingOutWithMergeConflictsThrows() Assert.Throws(() => repo.Checkout("master")); // And when there are staged commits - repo.Stage(originalFilePath); + Commands.Stage(repo, originalFilePath); Assert.Throws(() => repo.Checkout("master")); } } @@ -322,7 +322,7 @@ public void CanCancelCheckoutThroughNotifyCallback() const string relativePath = "a.txt"; Touch(repo.Info.WorkingDirectory, relativePath, "Hello\n"); - repo.Stage(relativePath); + Commands.Stage(repo, relativePath); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); // Create 2nd branch @@ -330,7 +330,7 @@ public void CanCancelCheckoutThroughNotifyCallback() // Update file in main Touch(repo.Info.WorkingDirectory, relativePath, "Hello from master!\n"); - repo.Stage(relativePath); + Commands.Stage(repo, relativePath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); // Checkout branch2 @@ -453,13 +453,13 @@ public void CheckingOutCallsCheckoutNotify(CheckoutNotifyFlags notifyFlags, stri const string relativePathUpdated = "updated.txt"; Touch(repo.Info.WorkingDirectory, relativePathUpdated, "updated file text A"); - repo.Stage(relativePathUpdated); + Commands.Stage(repo, relativePathUpdated); repo.Commit("Commit initial update file", Constants.Signature, Constants.Signature); // Create conflicting change const string relativePathConflict = "conflict.txt"; Touch(repo.Info.WorkingDirectory, relativePathConflict, "conflict file text A"); - repo.Stage(relativePathConflict); + Commands.Stage(repo, relativePathConflict); repo.Commit("Initial commit of conflict.txt and update.txt", Constants.Signature, Constants.Signature); // Create another branch @@ -467,9 +467,9 @@ public void CheckingOutCallsCheckoutNotify(CheckoutNotifyFlags notifyFlags, stri // Make an edit to conflict.txt and update.txt Touch(repo.Info.WorkingDirectory, relativePathUpdated, "updated file text BB"); - repo.Stage(relativePathUpdated); + Commands.Stage(repo, relativePathUpdated); Touch(repo.Info.WorkingDirectory, relativePathConflict, "conflict file text BB"); - repo.Stage(relativePathConflict); + Commands.Stage(repo, relativePathConflict); repo.Commit("2nd commit of conflict.txt and update.txt on master branch", Constants.Signature, Constants.Signature); @@ -478,14 +478,14 @@ public void CheckingOutCallsCheckoutNotify(CheckoutNotifyFlags notifyFlags, stri // Make alternate edits to conflict.txt and update.txt Touch(repo.Info.WorkingDirectory, relativePathUpdated, "updated file text CCC"); - repo.Stage(relativePathUpdated); + Commands.Stage(repo, relativePathUpdated); Touch(repo.Info.WorkingDirectory, relativePathConflict, "conflict file text CCC"); - repo.Stage(relativePathConflict); + Commands.Stage(repo, 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.Stage(relativePathConflict); + Commands.Stage(repo, relativePathConflict); // Create ignored change string relativePathIgnore = Path.Combine("bin", "ignored.txt"); @@ -596,7 +596,7 @@ public void CheckoutRetainsStagedChanges() // Generate a staged change. string fullPathFileA = Touch(repo.Info.WorkingDirectory, originalFilePath, alternateFileContent); - repo.Stage(fullPathFileA); + Commands.Stage(repo, fullPathFileA); // Verify that there is a staged entry. Assert.Equal(1, repo.RetrieveStatus().Staged.Count()); @@ -680,7 +680,7 @@ public void CheckoutBranchSnapshot() // Add commit to master string fullPath = Touch(repo.Info.WorkingDirectory, originalFilePath, "Update : hello from master branch!\n"); - repo.Stage(fullPath); + Commands.Stage(repo, fullPath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); Assert.False(repo.Info.IsHeadDetached); @@ -1038,10 +1038,10 @@ private void PopulateBasicRepository(IRepository repo) { // Generate a .gitignore file. string gitIgnoreFilePath = Touch(repo.Info.WorkingDirectory, ".gitignore", "bin"); - repo.Stage(gitIgnoreFilePath); + Commands.Stage(repo, gitIgnoreFilePath); string fullPathFileA = Touch(repo.Info.WorkingDirectory, originalFilePath, originalFileContent); - repo.Stage(fullPathFileA); + Commands.Stage(repo, fullPathFileA); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp.Tests/CherryPickFixture.cs b/LibGit2Sharp.Tests/CherryPickFixture.cs index d9828e266..ab7c90c45 100644 --- a/LibGit2Sharp.Tests/CherryPickFixture.cs +++ b/LibGit2Sharp.Tests/CherryPickFixture.cs @@ -130,7 +130,7 @@ private Commit AddFileCommitToRepo(IRepository repository, string filename, stri { Touch(repository.Info.WorkingDirectory, filename, content); - repository.Stage(filename); + Commands.Stage(repository, filename); return repository.Commit("New commit", Constants.Signature, Constants.Signature); } diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index 30a996fd7..5078672d0 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -552,10 +552,10 @@ public void CanCommitWithSignatureFromConfig() const string relativeFilepath = "new.txt"; string filePath = Touch(repo.Info.WorkingDirectory, relativeFilepath, "null"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); File.AppendAllText(filePath, "token\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); Assert.Null(repo.Head[relativeFilepath]); @@ -614,7 +614,7 @@ public void CommitCleansUpMergeMetadata() const string relativeFilepath = "new.txt"; Touch(repo.Info.WorkingDirectory, relativeFilepath, "this is a new file"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); string mergeHeadPath = Touch(repo.Info.Path, "MERGE_HEAD", "abcdefabcdefabcdefabcdefabcdefabcdefabcd"); string mergeMsgPath = Touch(repo.Info.Path, "MERGE_MSG", "This is a dummy merge.\n"); @@ -651,9 +651,9 @@ public void CanCommitALittleBit() const string relativeFilepath = "new.txt"; string filePath = Touch(repo.Info.WorkingDirectory, relativeFilepath, "null"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); File.AppendAllText(filePath, "token\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); Assert.Null(repo.Head[relativeFilepath]); @@ -692,7 +692,7 @@ public void CanCommitALittleBit() Assert.Equal(commit.Id, repo.Refs.Log(targetCanonicalName).First().To); File.WriteAllText(filePath, "nulltoken commits!\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); var author2 = new Signature(author.Name, author.Email, author.When.AddSeconds(5)); Commit commit2 = repo.Commit("Are you trying to fork me?", author2, author2); @@ -713,7 +713,7 @@ public void CanCommitALittleBit() File.WriteAllText(filePath, "davidfowl commits!\n"); var author3 = new Signature("David Fowler", "david.fowler@microsoft.com", author.When.AddSeconds(2)); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); Commit commit3 = repo.Commit("I'm going to branch you backwards in time!", author3, author3); @@ -739,7 +739,7 @@ private static void AddCommitToRepo(string path) { const string relativeFilepath = "test.txt"; Touch(repo.Info.WorkingDirectory, relativeFilepath, "test\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); var author = new Signature("nulltoken", "emeric.fermas@gmail.com", DateTimeOffset.Parse("Wed, Dec 14 2011 08:29:03 +0100")); repo.Commit("Initial commit", author, author); @@ -825,7 +825,7 @@ private static void CreateAndStageANewFile(IRepository repo) { string relativeFilepath = string.Format("new-file-{0}.txt", Path.GetRandomFileName()); Touch(repo.Info.WorkingDirectory, relativeFilepath, "brand new content\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); } private static void AssertCommitHasBeenAmended(IRepository repo, Commit amendedCommit, Commit originalCommit) @@ -914,7 +914,7 @@ public void CanCommitOnOrphanedBranch() const string relativeFilepath = "test.txt"; Touch(repo.Info.WorkingDirectory, relativeFilepath, "test\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); Assert.Equal(1, repo.Head.Commits.Count()); @@ -1030,12 +1030,12 @@ public void CanNotAmendACommitInAWayThatWouldLeadTheNewCommitToBecomeEmpty() using (var repo = new Repository(repoPath)) { Touch(repo.Info.WorkingDirectory, "test.txt", "test\n"); - repo.Stage("test.txt"); + Commands.Stage(repo, "test.txt"); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); Touch(repo.Info.WorkingDirectory, "new.txt", "content\n"); - repo.Stage("new.txt"); + Commands.Stage(repo, "new.txt"); repo.Commit("One commit", Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs index da48dbc68..b8ff89e3f 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs @@ -12,12 +12,12 @@ private static void SetUpSimpleDiffContext(IRepository repo) { var fullpath = Touch(repo.Info.WorkingDirectory, "file.txt", "hello\n"); - repo.Stage(fullpath); + Commands.Stage(repo, fullpath); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); File.AppendAllText(fullpath, "world\n"); - repo.Stage(fullpath); + Commands.Stage(repo,fullpath); File.AppendAllText(fullpath, "!!!\n"); } @@ -159,7 +159,7 @@ public void ShowcaseTheDifferenceBetweenTheTwoKindOfComparison() var fullpath = Path.Combine(repo.Info.WorkingDirectory, "file.txt"); File.Move(fullpath, fullpath + ".bak"); - repo.Stage(fullpath); + Commands.Stage(repo, fullpath); File.Move(fullpath + ".bak", fullpath); FileStatus state = repo.RetrieveStatus("file.txt"); @@ -378,11 +378,11 @@ public void CanCopeWithEndOfFileNewlineChanges() { var fullpath = Touch(repo.Info.WorkingDirectory, "file.txt", "a"); - repo.Stage("file.txt"); + Commands.Stage(repo, "file.txt"); repo.Commit("Add file without line ending", Constants.Signature, Constants.Signature); File.AppendAllText(fullpath, "\n"); - repo.Stage("file.txt"); + Commands.Stage(repo, "file.txt"); var changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index); Assert.Equal(1, changes.Modified.Count()); diff --git a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs index ebd426787..4d07f23e0 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs @@ -99,7 +99,7 @@ public void CanDetectABinaryChange() CreateBinaryFile(filepath); - repo.Stage(filename); + Commands.Stage(repo, filename); var commit = repo.Commit("Add binary file", Constants.Signature, Constants.Signature); File.AppendAllText(filepath, "abcdef"); @@ -107,7 +107,7 @@ public void CanDetectABinaryChange() var patch = repo.Diff.Compare(commit.Tree, DiffTargets.WorkingDirectory, new[] { filename }); Assert.True(patch[filename].IsBinaryComparison); - repo.Stage(filename); + Commands.Stage(repo, filename); var commit2 = repo.Commit("Update binary file", Constants.Signature, Constants.Signature); var patch2 = repo.Diff.Compare(commit.Tree, commit2.Tree, new[] { filename }); @@ -125,7 +125,7 @@ public void CanDetectABinaryDeletion() CreateBinaryFile(filepath); - repo.Stage(filename); + Commands.Stage(repo, filename); var commit = repo.Commit("Add binary file", Constants.Signature, Constants.Signature); File.Delete(filepath); @@ -289,7 +289,7 @@ public void DetectsTheExactRenamingOfFilesByDefault() Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); @@ -324,13 +324,13 @@ public void RenameThresholdsAreObeyed() // 4 lines Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); // 8 lines, 50% are from original file Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\ne\nf\ng\nh\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); repo.Move(originalPath, renamedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -365,7 +365,7 @@ public void ExactModeDetectsExactRenames() Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); @@ -399,11 +399,11 @@ public void ExactModeDetectsExactCopies() var copiedFullPath = Path.Combine(repo.Info.WorkingDirectory, copiedPath); Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); File.Copy(originalFullPath, copiedFullPath); - repo.Stage(copiedPath); + Commands.Stage(repo, copiedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -430,13 +430,13 @@ public void ExactModeDoesntDetectRenamesWithEdits() Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); repo.Move(originalPath, renamedPath); File.AppendAllText(Path.Combine(repo.Info.WorkingDirectory, renamedPath), "e\nf\n"); - repo.Stage(renamedPath); + Commands.Stage(repo, renamedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -467,12 +467,12 @@ public void CanIncludeUnmodifiedEntriesWhenDetectingTheExactRenamingOfFilesWhenE Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); File.Copy(originalFullPath, copiedFullPath); - repo.Stage(copiedPath); + Commands.Stage(repo, copiedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -504,7 +504,7 @@ public void CanNotDetectTheExactRenamingFilesWhenNotEnabled() Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); @@ -538,12 +538,12 @@ public void CanDetectTheExactCopyingOfNonModifiedFilesWhenEnabled() Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); File.Copy(originalFullPath, copiedFullPath); - repo.Stage(copiedPath); + Commands.Stage(repo, copiedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -575,12 +575,12 @@ public void CanNotDetectTheExactCopyingOfNonModifiedFilesWhenNotEnabled() Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); File.Copy(originalFullPath, copiedFullPath); - repo.Stage(copiedPath); + Commands.Stage(repo, copiedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -605,15 +605,15 @@ public void CanDetectTheExactCopyingOfModifiedFilesWhenEnabled() Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); File.Copy(originalFullPath, copiedFullPath); Touch(repo.Info.WorkingDirectory, originalPath, "e\n"); - repo.Stage(originalPath); - repo.Stage(copiedPath); + Commands.Stage(repo, originalPath); + Commands.Stage(repo, copiedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -645,15 +645,15 @@ public void CanNotDetectTheExactCopyingOfModifiedFilesWhenNotEnabled() Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n"); - repo.Stage(originalPath); + Commands.Stage(repo, originalPath); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); File.Copy(originalFullPath, copiedFullPath); File.AppendAllText(originalFullPath, "e\n"); - repo.Stage(originalPath); - repo.Stage(copiedPath); + Commands.Stage(repo, originalPath); + Commands.Stage(repo, copiedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -674,11 +674,11 @@ public void CanIncludeUnmodifiedEntriesWhenEnabled() Touch(repo.Info.WorkingDirectory, "a.txt", "abc\ndef\n"); Touch(repo.Info.WorkingDirectory, "b.txt", "abc\ndef\n"); - repo.Stage(new[] {"a.txt", "b.txt"}); + Commands.Stage(repo, new[] {"a.txt", "b.txt"}); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); File.AppendAllText(Path.Combine(repo.Info.WorkingDirectory, "b.txt"), "ghi\njkl\n"); - repo.Stage("b.txt"); + Commands.Stage(repo, "b.txt"); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); var changes = repo.Diff.Compare(old.Tree, @new.Tree, @@ -708,9 +708,9 @@ public void CanDetectTheExactRenamingExactCopyingOfNonModifiedAndModifiedFilesWh Touch(repo.Info.WorkingDirectory, originalPath2, "1\n2\n3\n4\n"); Touch(repo.Info.WorkingDirectory, originalPath3, "5\n6\n7\n8\n"); - repo.Stage(originalPath); - repo.Stage(originalPath2); - repo.Stage(originalPath3); + Commands.Stage(repo, originalPath); + Commands.Stage(repo, originalPath2); + Commands.Stage(repo, originalPath3); Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); @@ -722,9 +722,9 @@ public void CanDetectTheExactRenamingExactCopyingOfNonModifiedAndModifiedFilesWh File.Copy(originalFullPath3, copiedFullPath2); File.AppendAllText(originalFullPath3, "9\n"); - repo.Stage(originalPath3); - repo.Stage(copiedPath1); - repo.Stage(copiedPath2); + Commands.Stage(repo, originalPath3); + Commands.Stage(repo, copiedPath1); + Commands.Stage(repo, copiedPath2); repo.Move(originalPath, renamedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp.Tests/FileHistoryFixture.cs b/LibGit2Sharp.Tests/FileHistoryFixture.cs index 3d09858b3..0c4921a9d 100644 --- a/LibGit2Sharp.Tests/FileHistoryFixture.cs +++ b/LibGit2Sharp.Tests/FileHistoryFixture.cs @@ -365,7 +365,7 @@ private Commit MakeAndCommitChange(Repository repo, string repoPath, string path string message = null) { Touch(repoPath, path, text); - repo.Stage(path); + Commands.Stage(repo, path); var commitSignature = GetNextSignature(); return repo.Commit(message ?? "Changed " + path, commitSignature, commitSignature); diff --git a/LibGit2Sharp.Tests/FilterFixture.cs b/LibGit2Sharp.Tests/FilterFixture.cs index e0a5282d9..a2ad2c01a 100644 --- a/LibGit2Sharp.Tests/FilterFixture.cs +++ b/LibGit2Sharp.Tests/FilterFixture.cs @@ -280,8 +280,8 @@ public void CanFilterLargeFiles() { CreateConfigurationWithDummyUser(repo, Constants.Identity); File.WriteAllText(attributesPath, "*.blob filter=test"); - repo.Stage(attributesFile.Name); - repo.Stage(contentFile.Name); + Commands.Stage(repo, attributesFile.Name); + Commands.Stage(repo, contentFile.Name); repo.Commit("test", Constants.Signature, Constants.Signature); contentFile.Delete(); repo.Checkout("HEAD", new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force }); @@ -413,7 +413,7 @@ private static FileInfo StageNewFile(IRepository repo, string contents = "null") { string newFilePath = Touch(repo.Info.WorkingDirectory, Guid.NewGuid() + ".txt", contents); var stageNewFile = new FileInfo(newFilePath); - repo.Stage(newFilePath); + Commands.Stage(repo, newFilePath); return stageNewFile; } diff --git a/LibGit2Sharp.Tests/FilterSubstitutionCipherFixture.cs b/LibGit2Sharp.Tests/FilterSubstitutionCipherFixture.cs index f022c9571..fb4dd36f8 100644 --- a/LibGit2Sharp.Tests/FilterSubstitutionCipherFixture.cs +++ b/LibGit2Sharp.Tests/FilterSubstitutionCipherFixture.cs @@ -197,14 +197,14 @@ private static string ReadTextFromFile(Repository repo, string fileName) private static void DeleteFile(Repository repo, string fileName) { File.Delete(Path.Combine(repo.Info.WorkingDirectory, fileName)); - repo.Stage(fileName); + Commands.Stage(repo, fileName); repo.Commit("remove file", Constants.Signature, Constants.Signature); } private static Blob CommitOnBranchAndReturnDatabaseBlob(Repository repo, string fileName, string input) { Touch(repo.Info.WorkingDirectory, fileName, input); - repo.Stage(fileName); + Commands.Stage(repo, fileName); var commit = repo.Commit("new file", Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp.Tests/IgnoreFixture.cs b/LibGit2Sharp.Tests/IgnoreFixture.cs index b9af91404..7957bf3e0 100644 --- a/LibGit2Sharp.Tests/IgnoreFixture.cs +++ b/LibGit2Sharp.Tests/IgnoreFixture.cs @@ -95,7 +95,7 @@ public void HonorDeeplyNestedGitIgnoreFile() var gitIgnoreFile = string.Format("deeply{0}nested{0}.gitignore", pd); Touch(repo.Info.WorkingDirectory, gitIgnoreFile, "SmtCounters.h"); - repo.Stage(gitIgnoreFile); + Commands.Stage(repo, gitIgnoreFile); repo.Commit("Add .gitignore", Constants.Signature, Constants.Signature); Assert.False(repo.RetrieveStatus().IsDirty); diff --git a/LibGit2Sharp.Tests/IndexFixture.cs b/LibGit2Sharp.Tests/IndexFixture.cs index 0b0f42553..6bf814732 100644 --- a/LibGit2Sharp.Tests/IndexFixture.cs +++ b/LibGit2Sharp.Tests/IndexFixture.cs @@ -103,7 +103,7 @@ public void CanRenameAFile() Touch(repo.Info.WorkingDirectory, oldName, "hello test file\n"); Assert.Equal(FileStatus.NewInWorkdir, repo.RetrieveStatus(oldName)); - repo.Stage(oldName); + Commands.Stage(repo, oldName); Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus(oldName)); // Generated through @@ -211,7 +211,7 @@ public void PathsOfIndexEntriesAreExpressedInNativeFormat() Touch(repo.Info.WorkingDirectory, relFilePath, "Anybody out there?"); // Stage the file - repo.Stage(relFilePath); + Commands.Stage(repo, relFilePath); // Get the index Index index = repo.Index; @@ -248,7 +248,7 @@ public void StagingAFileWhenTheIndexIsLockedThrowsALockedFileException() Touch(repo.Info.Path, "index.lock"); Touch(repo.Info.WorkingDirectory, "newfile", "my my, this is gonna crash\n"); - Assert.Throws(() => repo.Stage("newfile")); + Assert.Throws(() => Commands.Stage(repo, "newfile")); } } @@ -273,7 +273,7 @@ public void CanCopeWithExternalChangesToTheIndex() Assert.True(readStatus.IsDirty); Assert.Equal(0, repoRead.Index.Count); - repoWrite.Stage("*"); + Commands.Stage(repoWrite, "*"); repoWrite.Commit("message", Constants.Signature, Constants.Signature); writeStatus = repoWrite.RetrieveStatus(); @@ -304,9 +304,11 @@ public void CanResetFullyMergedIndexFromTree() var headIndexTree = repo.Lookup(headIndexTreeSha); Assert.NotNull(headIndexTree); - repo.Index.Replace(headIndexTree); + var index = repo.Index; + index.Replace(headIndexTree); + index.Write(); - Assert.True(repo.Index.IsFullyMerged); + Assert.True(index.IsFullyMerged); Assert.Equal(FileStatus.NewInWorkdir, repo.RetrieveStatus(testFile)); } @@ -335,9 +337,11 @@ public void CanResetIndexWithUnmergedEntriesFromTree() var headIndexTree = repo.Lookup(headIndexTreeSha); Assert.NotNull(headIndexTree); - repo.Index.Replace(headIndexTree); + var index = repo.Index; + index.Replace(headIndexTree); + index.Write(); - Assert.True(repo.Index.IsFullyMerged); + Assert.True(index.IsFullyMerged); Assert.Equal(FileStatus.ModifiedInWorkdir, repo.RetrieveStatus(testFile)); } @@ -359,10 +363,11 @@ public void CanClearTheIndex() using (var repo = new Repository(path)) { Assert.Equal(FileStatus.Unaltered, repo.RetrieveStatus(testFile)); - Assert.NotEqual(0, repo.Index.Count); - - repo.Index.Clear(); - Assert.Equal(0, repo.Index.Count); + var index = repo.Index; + Assert.NotEqual(0, index.Count); + index.Clear(); + Assert.Equal(0, index.Count); + index.Write(); Assert.Equal(FileStatus.DeletedFromIndex | FileStatus.NewInWorkdir, repo.RetrieveStatus(testFile)); } @@ -457,7 +462,7 @@ public void CanMimicGitAddAll() AddSomeCornerCases(repo); - repo.Stage("*"); + Commands.Stage(repo, "*"); var after = repo.RetrieveStatus(); Assert.False(after.Any(se => se.State == FileStatus.NewInWorkdir)); diff --git a/LibGit2Sharp.Tests/MergeFixture.cs b/LibGit2Sharp.Tests/MergeFixture.cs index f38f456de..99e1e4595 100644 --- a/LibGit2Sharp.Tests/MergeFixture.cs +++ b/LibGit2Sharp.Tests/MergeFixture.cs @@ -611,7 +611,7 @@ public void MergeWithWorkDirConflictsThrows(bool shouldStage, FastForwardStrateg if (shouldStage) { - repo.Stage("b.txt"); + Commands.Stage(repo, "b.txt"); } Assert.Throws(() => repo.Merge(committishToMerge, Constants.Signature, new MergeOptions() { FastForwardStrategy = strategy })); @@ -750,7 +750,7 @@ public void CanMergeIntoOrphanedBranch() // Remove entries from the working directory foreach(var entry in repo.RetrieveStatus()) { - repo.Unstage(entry.FilePath); + Commands.Unstage(repo, entry.FilePath); repo.Remove(entry.FilePath, true); } @@ -790,7 +790,7 @@ public void CanMergeTreeIntoTreeFromUnbornBranch() Touch(repo.Info.WorkingDirectory, "README", "Yeah!\n"); repo.Index.Clear(); - repo.Stage("README"); + Commands.Stage(repo, "README"); repo.Commit("A new world, free of the burden of the history", Constants.Signature, Constants.Signature); @@ -869,7 +869,7 @@ private Commit AddFileCommitToRepo(IRepository repository, string filename, stri { Touch(repository.Info.WorkingDirectory, filename, content); - repository.Stage(filename); + Commands.Stage(repository, filename); return repository.Commit("New commit", Constants.Signature, Constants.Signature); } diff --git a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs index bfbb6ae5a..fc06ef713 100644 --- a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs +++ b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs @@ -676,7 +676,7 @@ public void TestMergeIntoOtherUnbornBranchHasNoConflicts() Touch(repo.Info.WorkingDirectory, "README", "Yeah!\n"); repo.Index.Clear(); - repo.Stage("README"); + Commands.Stage(repo, "README"); repo.Commit("A new world, free of the burden of the history", Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp.Tests/OdbBackendFixture.cs b/LibGit2Sharp.Tests/OdbBackendFixture.cs index 2ca40a4cb..824738f13 100644 --- a/LibGit2Sharp.Tests/OdbBackendFixture.cs +++ b/LibGit2Sharp.Tests/OdbBackendFixture.cs @@ -16,7 +16,7 @@ private static Commit AddCommitToRepo(IRepository repo) { string relativeFilepath = "test.txt"; Touch(repo.Info.WorkingDirectory, relativeFilepath, content); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); var ie = repo.Index[relativeFilepath]; Assert.NotNull(ie); @@ -28,7 +28,7 @@ private static Commit AddCommitToRepo(IRepository repo) relativeFilepath = "big.txt"; var zeros = new string('0', 32*1024 + 3); Touch(repo.Info.WorkingDirectory, relativeFilepath, zeros); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); ie = repo.Index[relativeFilepath]; Assert.NotNull(ie); diff --git a/LibGit2Sharp.Tests/PushFixture.cs b/LibGit2Sharp.Tests/PushFixture.cs index 7dde5efd6..d8cf2befe 100644 --- a/LibGit2Sharp.Tests/PushFixture.cs +++ b/LibGit2Sharp.Tests/PushFixture.cs @@ -38,7 +38,7 @@ private void AssertPush(Action push) // Change local state (commit) const string relativeFilepath = "new_file.txt"; Touch(clonedRepo.Info.WorkingDirectory, relativeFilepath, "__content__"); - clonedRepo.Stage(relativeFilepath); + Commands.Stage(clonedRepo, relativeFilepath); clonedRepo.Commit("__commit_message__", Constants.Signature, Constants.Signature); // Assert local state has changed @@ -228,7 +228,7 @@ private Commit AddCommitToRepo(IRepository repository) Touch(repository.Info.WorkingDirectory, filename, random); - repository.Stage(filename); + Commands.Stage(repository, filename); return repository.Commit("New commit", Constants.Signature, Constants.Signature); } diff --git a/LibGit2Sharp.Tests/RebaseFixture.cs b/LibGit2Sharp.Tests/RebaseFixture.cs index d70851bdc..6edf468af 100644 --- a/LibGit2Sharp.Tests/RebaseFixture.cs +++ b/LibGit2Sharp.Tests/RebaseFixture.cs @@ -338,7 +338,7 @@ public void CanContinueRebase() Touch(repo.Info.WorkingDirectory, conflict.Theirs.Path, repo.Lookup(conflict.Theirs.Id).GetContentText(new FilteringOptions(conflict.Theirs.Path))); - repo.Stage(conflict.Theirs.Path); + Commands.Stage(repo, conflict.Theirs.Path); } Assert.True(repo.Index.IsFullyMerged); @@ -396,7 +396,7 @@ public void ContinuingRebaseWithUnstagedChangesThrows() Touch(repo.Info.WorkingDirectory, conflict.Theirs.Path, repo.Lookup(conflict.Theirs.Id).GetContentText(new FilteringOptions(conflict.Theirs.Path))); - repo.Stage(conflict.Theirs.Path); + Commands.Stage(repo, conflict.Theirs.Path); } Touch(repo.Info.WorkingDirectory, @@ -618,7 +618,7 @@ public void CanRebaseHandlePatchAlreadyApplied(string attributes, string lineEnd string newFileRelativePath = "new_file.txt"; Touch(repo.Info.WorkingDirectory, newFileRelativePath, "New Content"); - repo.Stage(newFileRelativePath); + Commands.Stage(repo, newFileRelativePath); Commit commit = repo.Commit("new commit 1", Constants.Signature, Constants.Signature, new CommitOptions()); repo.Checkout(topicBranch1Prime); @@ -627,7 +627,7 @@ public void CanRebaseHandlePatchAlreadyApplied(string attributes, string lineEnd string newFileRelativePath2 = "new_file_2.txt"; Touch(repo.Info.WorkingDirectory, newFileRelativePath2, "New Content for path 2"); - repo.Stage(newFileRelativePath2); + Commands.Stage(repo, newFileRelativePath2); repo.Commit("new commit 2", Constants.Signature, Constants.Signature, new CommitOptions()); Branch upstreamBranch = repo.Branches[topicBranch1Name]; @@ -714,69 +714,69 @@ private void ConstructRebaseTestRepository(Repository repo, string attributes = CreateAttributesFile(repo, attributes); - repo.Stage(".gitattributes"); + Commands.Stage(repo, ".gitattributes"); commit = repo.Commit("setup", Constants.Signature, Constants.Signature, new CommitOptions()); Touch(workdir, filePathA, fileContentA1); - repo.Stage(filePathA); + Commands.Stage(repo, filePathA); commit = repo.Commit("commit 1", Constants.Signature, Constants.Signature, new CommitOptions()); Touch(workdir, filePathB, fileContentB1); - repo.Stage(filePathB); + Commands.Stage(repo, filePathB); commit = repo.Commit("commit 2", Constants.Signature, Constants.Signature, new CommitOptions()); Touch(workdir, filePathC, fileContentC1); - repo.Stage(filePathC); + Commands.Stage(repo, filePathC); commit = repo.Commit("commit 3", Constants.Signature, Constants.Signature, new CommitOptions()); Branch masterBranch1 = repo.CreateBranch(masterBranch1Name, commit); Touch(workdir, filePathB, string.Join(lineEnding, fileContentB1, fileContentB2)); - repo.Stage(filePathB); + Commands.Stage(repo, filePathB); commit = repo.Commit("commit 4", Constants.Signature, Constants.Signature, new CommitOptions()); Touch(workdir, filePathB, string.Join(lineEnding, fileContentB1, fileContentB2, fileContentB3)); - repo.Stage(filePathB); + Commands.Stage(repo, filePathB); commit = repo.Commit("commit 5", Constants.Signature, Constants.Signature, new CommitOptions()); Touch(workdir, filePathB, string.Join(lineEnding, fileContentB1, fileContentB2, fileContentB3, fileContentB4)); - repo.Stage(filePathB); + Commands.Stage(repo, filePathB); commit = repo.Commit("commit 6", Constants.Signature, Constants.Signature, new CommitOptions()); repo.CreateBranch(topicBranch1Name, commit); Touch(workdir, filePathC, string.Join(lineEnding, fileContentC1, fileContentC2)); - repo.Stage(filePathC); + Commands.Stage(repo, filePathC); commit = repo.Commit("commit 7", Constants.Signature, Constants.Signature, new CommitOptions()); Touch(workdir, filePathC, string.Join(lineEnding, fileContentC1, fileContentC2, fileContentC3)); - repo.Stage(filePathC); + Commands.Stage(repo, filePathC); commit = repo.Commit("commit 8", Constants.Signature, Constants.Signature, new CommitOptions()); Touch(workdir, filePathC, string.Join(lineEnding, fileContentC1, fileContentC2, fileContentC3, fileContentC4)); - repo.Stage(filePathC); + Commands.Stage(repo, filePathC); commit = repo.Commit("commit 9", Constants.Signature, Constants.Signature, new CommitOptions()); repo.CreateBranch(topicBranch2Name, commit); repo.Checkout(masterBranch1.Tip); Touch(workdir, filePathD, fileContentD1); - repo.Stage(filePathD); + Commands.Stage(repo, filePathD); commit = repo.Commit("commit 10", Constants.Signature, Constants.Signature, new CommitOptions()); Touch(workdir, filePathD, string.Join(lineEnding, fileContentD1, fileContentD2)); - repo.Stage(filePathD); + Commands.Stage(repo, filePathD); commit = repo.Commit("commit 11", Constants.Signature, Constants.Signature, new CommitOptions()); Touch(workdir, filePathD, string.Join(lineEnding, fileContentD1, fileContentD2, fileContentD3)); - repo.Stage(filePathD); + Commands.Stage(repo, filePathD); commit = repo.Commit("commit 12", Constants.Signature, Constants.Signature, new CommitOptions()); repo.CreateBranch(masterBranch2Name, commit); // Create commit / branch that conflicts with T1 and T2 Touch(workdir, filePathB, string.Join(lineEnding, fileContentB1, fileContentB2 + fileContentB3 + fileContentB4)); - repo.Stage(filePathB); + Commands.Stage(repo, filePathB); commit = repo.Commit("commit 13", Constants.Signature, Constants.Signature, new CommitOptions()); repo.CreateBranch(conflictBranch1Name, commit); } diff --git a/LibGit2Sharp.Tests/ReflogFixture.cs b/LibGit2Sharp.Tests/ReflogFixture.cs index 72f9faa0f..22c455d8a 100644 --- a/LibGit2Sharp.Tests/ReflogFixture.cs +++ b/LibGit2Sharp.Tests/ReflogFixture.cs @@ -68,7 +68,7 @@ public void CommitShouldCreateReflogEntryOnHeadAndOnTargetedDirectReference() const string relativeFilepath = "new.txt"; Touch(repo.Info.WorkingDirectory, relativeFilepath, "content\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); var author = Constants.Signature; const string commitMessage = "Hope reflog behaves as it should"; @@ -116,7 +116,7 @@ public void CommitOnUnbornReferenceShouldCreateReflogEntryWithInitialTag() { const string relativeFilepath = "new.txt"; Touch(repo.Info.WorkingDirectory, relativeFilepath, "content\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); var author = Constants.Signature; const string commitMessage = "First commit should be logged as initial"; @@ -145,7 +145,7 @@ public void CommitOnDetachedHeadShouldInsertReflogEntry() const string relativeFilepath = "new.txt"; Touch(repo.Info.WorkingDirectory, relativeFilepath, "content\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); var author = Constants.Signature; const string commitMessage = "Commit on detached head"; diff --git a/LibGit2Sharp.Tests/RemoveFixture.cs b/LibGit2Sharp.Tests/RemoveFixture.cs index 94a376daf..3ab860994 100644 --- a/LibGit2Sharp.Tests/RemoveFixture.cs +++ b/LibGit2Sharp.Tests/RemoveFixture.cs @@ -104,11 +104,11 @@ public void CanRemoveAFolderThroughUsageOfPathspecsForNewlyAddedFiles() string path = SandboxStandardTestRepo(); using (var repo = new Repository(path)) { - repo.Stage(Touch(repo.Info.WorkingDirectory, "2/subdir1/2.txt", "whone")); - repo.Stage(Touch(repo.Info.WorkingDirectory, "2/subdir1/3.txt", "too")); - repo.Stage(Touch(repo.Info.WorkingDirectory, "2/subdir2/4.txt", "tree")); - repo.Stage(Touch(repo.Info.WorkingDirectory, "2/5.txt", "for")); - repo.Stage(Touch(repo.Info.WorkingDirectory, "2/6.txt", "fyve")); + Commands.Stage(repo, Touch(repo.Info.WorkingDirectory, "2/subdir1/2.txt", "whone")); + Commands.Stage(repo, Touch(repo.Info.WorkingDirectory, "2/subdir1/3.txt", "too")); + Commands.Stage(repo, Touch(repo.Info.WorkingDirectory, "2/subdir2/4.txt", "tree")); + Commands.Stage(repo, Touch(repo.Info.WorkingDirectory, "2/5.txt", "for")); + Commands.Stage(repo, Touch(repo.Info.WorkingDirectory, "2/6.txt", "fyve")); int count = repo.Index.Count; diff --git a/LibGit2Sharp.Tests/RepositoryFixture.cs b/LibGit2Sharp.Tests/RepositoryFixture.cs index 47fd359fa..04bec799f 100644 --- a/LibGit2Sharp.Tests/RepositoryFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryFixture.cs @@ -443,7 +443,7 @@ public void CanLookupWhithShortIdentifers() { const string filename = "new.txt"; Touch(repo.Info.WorkingDirectory, filename, "one "); - repo.Stage(filename); + Commands.Stage(repo, filename); Signature author = Constants.Signature; Commit commit = repo.Commit("Initial commit", author, author); diff --git a/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs b/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs index 496cf3029..8cf033506 100644 --- a/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs @@ -90,7 +90,7 @@ public void CanProvideADifferentIndexToAStandardRepo() { Assert.Equal(FileStatus.NewInWorkdir, repo.RetrieveStatus("new_untracked_file.txt")); - repo.Stage("new_untracked_file.txt"); + Commands.Stage(repo, "new_untracked_file.txt"); Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus("new_untracked_file.txt")); @@ -148,7 +148,7 @@ private string MeanwhileInAnotherDimensionAnEvilMastermindIsAtWork(string workin const string filename = "zomg.txt"; Touch(sneakyRepo.Info.WorkingDirectory, filename, "I'm being sneaked in!\n"); - sneakyRepo.Stage(filename); + Commands.Stage(sneakyRepo, filename); return sneakyRepo.Commit("Tadaaaa!", Constants.Signature, Constants.Signature).Sha; } } @@ -210,7 +210,7 @@ public void CanCommitOnBareRepository() { const string relativeFilepath = "test.txt"; Touch(repo.Info.WorkingDirectory, relativeFilepath, "test\n"); - repo.Stage(relativeFilepath); + Commands.Stage(repo, relativeFilepath); Assert.NotNull(repo.Commit("Initial commit", Constants.Signature, Constants.Signature)); Assert.Equal(1, repo.Head.Commits.Count()); diff --git a/LibGit2Sharp.Tests/ResetHeadFixture.cs b/LibGit2Sharp.Tests/ResetHeadFixture.cs index 2a2927328..683b029fd 100644 --- a/LibGit2Sharp.Tests/ResetHeadFixture.cs +++ b/LibGit2Sharp.Tests/ResetHeadFixture.cs @@ -163,12 +163,12 @@ private void AssertSoftReset(Func branchIdentifierRetriever, boo private static void FeedTheRepository(IRepository repo) { string fullPath = Touch(repo.Info.WorkingDirectory, "a.txt", "Hello\n"); - repo.Stage(fullPath); + Commands.Stage(repo, fullPath); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); repo.ApplyTag("mytag"); File.AppendAllText(fullPath, "World\n"); - repo.Stage(fullPath); + Commands.Stage(repo, fullPath); Signature shiftedSignature = Constants.Signature.TimeShift(TimeSpan.FromMinutes(1)); repo.Commit("Update file", shiftedSignature, shiftedSignature); diff --git a/LibGit2Sharp.Tests/StageFixture.cs b/LibGit2Sharp.Tests/StageFixture.cs index 9a6c6248a..b606a745e 100644 --- a/LibGit2Sharp.Tests/StageFixture.cs +++ b/LibGit2Sharp.Tests/StageFixture.cs @@ -25,7 +25,7 @@ public void CanStage(string relativePath, FileStatus currentStatus, bool doesCur Assert.Equal(doesCurrentlyExistInTheIndex, (repo.Index[relativePath] != null)); Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); - repo.Stage(relativePath); + Commands.Stage(repo, relativePath); Assert.Equal(count + expectedIndexCountVariation, repo.Index.Count); Assert.Equal(doesExistInTheIndexOnceStaged, (repo.Index[relativePath] != null)); @@ -48,7 +48,7 @@ public void CanStageTheUpdationOfAStagedFile() Touch(repo.Info.WorkingDirectory, filename, "brand new content"); Assert.Equal(FileStatus.NewInIndex | FileStatus.ModifiedInWorkdir, repo.RetrieveStatus(filename)); - repo.Stage(filename); + Commands.Stage(repo, filename); IndexEntry newBlob = repo.Index[filename]; Assert.Equal(count, repo.Index.Count); @@ -68,7 +68,7 @@ public void StagingAnUnknownFileThrowsIfExplicitPath(string relativePath, FileSt Assert.Null(repo.Index[relativePath]); Assert.Equal(status, repo.RetrieveStatus(relativePath)); - Assert.Throws(() => repo.Stage(relativePath, new StageOptions { ExplicitPathsOptions = new ExplicitPathsOptions() })); + Assert.Throws(() => Commands.Stage(repo, relativePath, new StageOptions { ExplicitPathsOptions = new ExplicitPathsOptions() })); } } @@ -83,8 +83,8 @@ public void CanStageAnUnknownFileWithLaxUnmatchedExplicitPathsValidation(string Assert.Null(repo.Index[relativePath]); Assert.Equal(status, repo.RetrieveStatus(relativePath)); - Assert.DoesNotThrow(() => repo.Stage(relativePath)); - Assert.DoesNotThrow(() => repo.Stage(relativePath, new StageOptions { ExplicitPathsOptions = new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false } })); + Assert.DoesNotThrow(() => Commands.Stage(repo, relativePath)); + Assert.DoesNotThrow(() => Commands.Stage(repo, relativePath, new StageOptions { ExplicitPathsOptions = new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false } })); Assert.Equal(status, repo.RetrieveStatus(relativePath)); } @@ -101,8 +101,8 @@ public void StagingAnUnknownFileWithLaxExplicitPathsValidationDoesntThrow(string Assert.Null(repo.Index[relativePath]); Assert.Equal(status, repo.RetrieveStatus(relativePath)); - repo.Stage(relativePath); - repo.Stage(relativePath, new StageOptions { ExplicitPathsOptions = new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false } }); + Commands.Stage(repo, relativePath); + Commands.Stage(repo, relativePath, new StageOptions { ExplicitPathsOptions = new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false } }); } } @@ -121,7 +121,7 @@ public void CanStageTheRemovalOfAStagedFile() File.Delete(Path.Combine(repo.Info.WorkingDirectory, filename)); Assert.Equal(FileStatus.NewInIndex | FileStatus.DeletedFromWorkdir, repo.RetrieveStatus(filename)); - repo.Stage(filename); + Commands.Stage(repo, filename); Assert.Null(repo.Index[filename]); Assert.Equal(count - 1, repo.Index.Count); @@ -145,7 +145,7 @@ public void CanStageANewFileInAPersistentManner(string filename) Assert.Equal(FileStatus.NewInWorkdir, repo.RetrieveStatus(filename)); Assert.Null(repo.Index[filename]); - repo.Stage(filename); + Commands.Stage(repo, filename); Assert.NotNull(repo.Index[filename]); Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus(filename)); } @@ -193,7 +193,7 @@ private static void AssertStage(bool? ignorecase, IRepository repo, string path) { try { - repo.Stage(path); + Commands.Stage(repo, path); Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus(path)); repo.Index.Replace(repo.Head.Tip); Assert.Equal(FileStatus.NewInWorkdir, repo.RetrieveStatus(path)); @@ -216,7 +216,7 @@ public void CanStageANewFileWithARelativePathContainingNativeDirectorySeparatorC Touch(repo.Info.WorkingDirectory, file, "With backward slash on Windows!"); - repo.Stage(file); + Commands.Stage(repo, file); Assert.Equal(count + 1, repo.Index.Count); @@ -235,7 +235,7 @@ public void StagingANewFileWithAFullPathWhichEscapesOutOfTheWorkingDirThrows() { string fullPath = Touch(scd.RootedDirectoryPath, "unit_test.txt", "some contents"); - Assert.Throws(() => repo.Stage(fullPath)); + Assert.Throws(() => Commands.Stage(repo, fullPath)); } } @@ -245,10 +245,10 @@ public void StagingFileWithBadParamsThrows() var path = SandboxStandardTestRepoGitDir(); using (var repo = new Repository(path)) { - Assert.Throws(() => repo.Stage(string.Empty)); - Assert.Throws(() => repo.Stage((string)null)); - Assert.Throws(() => repo.Stage(new string[] { })); - Assert.Throws(() => repo.Stage(new string[] { null })); + Assert.Throws(() => Commands.Stage(repo, string.Empty)); + Assert.Throws(() => Commands.Stage(repo, (string)null)); + Assert.Throws(() => Commands.Stage(repo, new string[] { })); + Assert.Throws(() => Commands.Stage(repo, new string[] { null })); } } @@ -284,7 +284,7 @@ public void CanStageWithPathspec(string relativePath, int expectedIndexCountVari { int count = repo.Index.Count; - repo.Stage(relativePath); + Commands.Stage(repo, relativePath); Assert.Equal(count + expectedIndexCountVariation, repo.Index.Count); } @@ -297,7 +297,7 @@ public void CanStageWithMultiplePathspecs() { int count = repo.Index.Count; - repo.Stage(new string[] { "*", "u*" }); + Commands.Stage(repo, new string[] { "*", "u*" }); Assert.Equal(count, repo.Index.Count); // 1 added file, 1 deleted file, so same count } @@ -314,7 +314,7 @@ public void CanIgnoreIgnoredPaths(string path) Touch(repo.Info.WorkingDirectory, path, "This file is ignored."); Assert.Equal(FileStatus.Ignored, repo.RetrieveStatus(path)); - repo.Stage("*"); + Commands.Stage(repo, "*"); Assert.Equal(FileStatus.Ignored, repo.RetrieveStatus(path)); } } @@ -330,7 +330,7 @@ public void CanStageIgnoredPaths(string path) Touch(repo.Info.WorkingDirectory, path, "This file is ignored."); Assert.Equal(FileStatus.Ignored, repo.RetrieveStatus(path)); - repo.Stage(path, new StageOptions { IncludeIgnored = true }); + Commands.Stage(repo, path, new StageOptions { IncludeIgnored = true }); Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus(path)); } } @@ -346,7 +346,7 @@ public void IgnoredFilesAreOnlyStagedIfTheyreInTheRepo(string filename, FileStat File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, ".gitignore"), String.Format("{0}\n", filename)); - repo.Stage(filename); + Commands.Stage(repo, filename); Assert.Equal(expected, repo.RetrieveStatus(filename)); } } @@ -368,7 +368,7 @@ public void CanStageConflictedIgnoredFiles(string filename, FileStatus expected) File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, ".gitignore"), String.Format("{0}\n", filename)); - repo.Stage(filename); + Commands.Stage(repo, filename); Assert.Equal(expected, repo.RetrieveStatus(filename)); } } @@ -385,7 +385,7 @@ public void CanSuccessfullyStageTheContentOfAModifiedFileOfTheSameSizeWithinTheS Touch(repo.Info.WorkingDirectory, "test.txt", Guid.NewGuid().ToString()); - repo.Stage("test.txt"); + Commands.Stage(repo, "test.txt"); Assert.DoesNotThrow(() => repo.Commit( "Commit", Constants.Signature, Constants.Signature)); diff --git a/LibGit2Sharp.Tests/StashFixture.cs b/LibGit2Sharp.Tests/StashFixture.cs index 369ac0994..6d6d5565d 100644 --- a/LibGit2Sharp.Tests/StashFixture.cs +++ b/LibGit2Sharp.Tests/StashFixture.cs @@ -139,7 +139,7 @@ public void CanStashWithoutOptions() const string staged = "staged_file_path.txt"; Touch(repo.Info.WorkingDirectory, staged, "I'm staged\n"); - repo.Stage(staged); + Commands.Stage(repo, staged); Stash stash = repo.Stashes.Add(stasher, "Stash with default options", StashModifiers.Default); @@ -165,7 +165,7 @@ public void CanStashAndKeepIndex() const string filename = "staged_file_path.txt"; Touch(repo.Info.WorkingDirectory, filename, "I'm staged\n"); - repo.Stage(filename); + Commands.Stage(repo, filename); Stash stash = repo.Stashes.Add(stasher, "This stash will keep index", StashModifiers.KeepIndex); @@ -186,7 +186,7 @@ public void CanStashIgnoredFiles() const string ignoredFilename = "ignored_file.txt"; Touch(repo.Info.WorkingDirectory, gitIgnore, ignoredFilename); - repo.Stage(gitIgnore); + Commands.Stage(repo, gitIgnore); repo.Commit("Modify gitignore", Constants.Signature, Constants.Signature); Touch(repo.Info.WorkingDirectory, ignoredFilename, "I'm ignored\n"); @@ -214,7 +214,7 @@ public void CanStashAndApplyWithOptions() const string filename = "staged_file_path.txt"; Touch(repo.Info.WorkingDirectory, filename, "I'm staged\n"); - repo.Stage(filename); + Commands.Stage(repo, filename); repo.Stashes.Add(stasher, "This stash with default options"); Assert.Equal(StashApplyStatus.Applied, repo.Stashes.Apply(0)); @@ -222,7 +222,7 @@ public void CanStashAndApplyWithOptions() Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus(filename)); Assert.Equal(1, repo.Stashes.Count()); - repo.Stage(filename); + Commands.Stage(repo, filename); repo.Stashes.Add(stasher, "This stash with default options"); Assert.Equal(StashApplyStatus.Applied, repo.Stashes.Apply( @@ -250,7 +250,7 @@ public void CanStashAndPop() const string filename = "staged_file_path.txt"; const string contents = "I'm staged"; Touch(repo.Info.WorkingDirectory, filename, contents); - repo.Stage(filename); + Commands.Stage(repo, filename); repo.Stashes.Add(stasher, "This stash with default options"); Assert.Equal(1, repo.Stashes.Count()); @@ -277,13 +277,13 @@ public void StashFailsWithUncommittedChangesIntheIndex() const string newContents = "I'm post-stash."; Touch(repo.Info.WorkingDirectory, filename, originalContents); - repo.Stage(filename); + Commands.Stage(repo, filename); Touch(repo.Info.WorkingDirectory, filename2, originalContents); repo.Stashes.Add(stasher, "This stash with default options"); Touch(repo.Info.WorkingDirectory, filename, newContents); - repo.Stage(filename); + Commands.Stage(repo, filename); Touch(repo.Info.WorkingDirectory, filename2, newContents); Assert.Equal(StashApplyStatus.UncommittedChanges, repo.Stashes.Pop(0, new StashApplyOptions @@ -310,7 +310,7 @@ public void StashCallsTheCallback() const string originalContents = "I'm pre-stash."; Touch(repo.Info.WorkingDirectory, filename, originalContents); - repo.Stage(filename); + Commands.Stage(repo, filename); Touch(repo.Info.WorkingDirectory, filename2, originalContents); repo.Stashes.Add(stasher, "This stash with default options"); diff --git a/LibGit2Sharp.Tests/StatusFixture.cs b/LibGit2Sharp.Tests/StatusFixture.cs index 3c9bc0023..018e88e4f 100644 --- a/LibGit2Sharp.Tests/StatusFixture.cs +++ b/LibGit2Sharp.Tests/StatusFixture.cs @@ -49,7 +49,7 @@ public void CanLimitStatusToIndexOnly(StatusShowOption show, FileStatus expected using (var repo = new Repository(clone)) { Touch(repo.Info.WorkingDirectory, "file.txt", "content"); - repo.Stage("file.txt"); + Commands.Stage(repo, "file.txt"); RepositoryStatus status = repo.RetrieveStatus(new StatusOptions() { Show = show }); Assert.Equal(expected, status["file.txt"].State); @@ -161,7 +161,7 @@ public void CanRetrieveTheStatusOfRenamedFilesInWorkDir() "This is a file with enough data to trigger similarity matching.\r\n" + "This is a file with enough data to trigger similarity matching.\r\n"); - repo.Stage("old_name.txt"); + Commands.Stage(repo, "old_name.txt"); File.Move(Path.Combine(repo.Info.WorkingDirectory, "old_name.txt"), Path.Combine(repo.Info.WorkingDirectory, "rename_target.txt")); @@ -188,8 +188,8 @@ public void CanRetrieveTheStatusOfRenamedFilesInIndex() Path.Combine(repo.Info.WorkingDirectory, "1.txt"), Path.Combine(repo.Info.WorkingDirectory, "rename_target.txt")); - repo.Stage("1.txt"); - repo.Stage("rename_target.txt"); + Commands.Stage(repo, "1.txt"); + Commands.Stage(repo, "rename_target.txt"); RepositoryStatus status = repo.RetrieveStatus(); @@ -210,7 +210,7 @@ public void CanDetectedVariousKindsOfRenaming() "This is a file with enough data to trigger similarity matching.\r\n" + "This is a file with enough data to trigger similarity matching.\r\n"); - repo.Stage("file.txt"); + Commands.Stage(repo, "file.txt"); repo.Commit("Initial commit", Constants.Signature, Constants.Signature); File.Move(Path.Combine(repo.Info.WorkingDirectory, "file.txt"), @@ -227,8 +227,8 @@ public void CanDetectedVariousKindsOfRenaming() // This passes as expected Assert.Equal(FileStatus.RenamedInWorkdir, status.Single().State); - repo.Stage("file.txt"); - repo.Stage("renamed.txt"); + Commands.Stage(repo, "file.txt"); + Commands.Stage(repo, "renamed.txt"); status = repo.RetrieveStatus(opts); @@ -281,7 +281,7 @@ public void RetrievingTheStatusOfARepositoryReturnNativeFilePaths() Touch(repo.Info.WorkingDirectory, relFilePath, "Anybody out there?"); // Add the file to the index - repo.Stage(relFilePath); + Commands.Stage(repo, relFilePath); // Get the repository status RepositoryStatus repoStatus = repo.RetrieveStatus(); @@ -427,7 +427,7 @@ FileStatus expectedCamelCasedFileStatus lowerCasedPath = Touch(repo.Info.WorkingDirectory, lowercasedFilename); - repo.Stage(lowercasedFilename); + Commands.Stage(repo, lowercasedFilename); repo.Commit("initial", Constants.Signature, Constants.Signature); } diff --git a/LibGit2Sharp.Tests/SubmoduleFixture.cs b/LibGit2Sharp.Tests/SubmoduleFixture.cs index 58c8a830a..803e43267 100644 --- a/LibGit2Sharp.Tests/SubmoduleFixture.cs +++ b/LibGit2Sharp.Tests/SubmoduleFixture.cs @@ -148,7 +148,7 @@ public void CanStageChangeInSubmoduleViaIndexStage(string submodulePath, bool ap var statusBefore = submodule.RetrieveStatus(); Assert.Equal(SubmoduleStatus.WorkDirModified, statusBefore & SubmoduleStatus.WorkDirModified); - repo.Stage(submodulePath); + Commands.Stage(repo, submodulePath); var statusAfter = submodule.RetrieveStatus(); Assert.Equal(SubmoduleStatus.IndexModified, statusAfter & SubmoduleStatus.IndexModified); @@ -173,7 +173,7 @@ public void CanStageChangeInSubmoduleViaIndexStageWithOtherPaths(string submodul Touch(repo.Info.WorkingDirectory, "new-file.txt"); - repo.Stage(new[] { "new-file.txt", submodulePath, "does-not-exist.txt" }); + Commands.Stage(repo, new[] { "new-file.txt", submodulePath, "does-not-exist.txt" }); var statusAfter = submodule.RetrieveStatus(); Assert.Equal(SubmoduleStatus.IndexModified, statusAfter & SubmoduleStatus.IndexModified); diff --git a/LibGit2Sharp.Tests/UnstageFixture.cs b/LibGit2Sharp.Tests/UnstageFixture.cs index ac73cf381..d58ffb122 100644 --- a/LibGit2Sharp.Tests/UnstageFixture.cs +++ b/LibGit2Sharp.Tests/UnstageFixture.cs @@ -25,12 +25,12 @@ public void StagingANewVersionOfAFileThenUnstagingItRevertsTheBlobToTheVersionOf string fullpath = Path.Combine(repo.Info.WorkingDirectory, filename); File.AppendAllText(fullpath, "Is there there anybody out there?"); - repo.Stage(filename); + Commands.Stage(repo, filename); Assert.Equal(count, repo.Index.Count); Assert.NotEqual((blobId), repo.Index[posixifiedFileName].Id); - repo.Unstage(posixifiedFileName); + Commands.Unstage(repo, posixifiedFileName); Assert.Equal(count, repo.Index.Count); Assert.Equal(blobId, repo.Index[posixifiedFileName].Id); @@ -50,10 +50,10 @@ public void CanStageAndUnstageAnIgnoredFile() Assert.Equal(FileStatus.Ignored, repo.RetrieveStatus(relativePath)); - repo.Stage(relativePath, new StageOptions { IncludeIgnored = true }); + Commands.Stage(repo, relativePath, new StageOptions { IncludeIgnored = true }); Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus(relativePath)); - repo.Unstage(relativePath); + Commands.Unstage(repo, relativePath); Assert.Equal(FileStatus.Ignored, repo.RetrieveStatus(relativePath)); } } @@ -76,7 +76,7 @@ public void CanUnstage( Assert.Equal(doesCurrentlyExistInTheIndex, (repo.Index[relativePath] != null)); Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); - repo.Unstage(relativePath); + Commands.Unstage(repo, relativePath); Assert.Equal(count + expectedIndexCountVariation, repo.Index.Count); Assert.Equal(doesExistInTheIndexOnceStaged, (repo.Index[relativePath] != null)); @@ -93,7 +93,7 @@ public void UnstagingUnknownPathsWithStrictUnmatchedExplicitPathsValidationThrow { Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); - Assert.Throws(() => repo.Unstage(relativePath, new ExplicitPathsOptions())); + Assert.Throws(() => Commands.Unstage(repo, relativePath, new ExplicitPathsOptions())); } } @@ -106,7 +106,7 @@ public void CanUnstageUnknownPathsWithLaxUnmatchedExplicitPathsValidation(string { Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); - Assert.DoesNotThrow(() => repo.Unstage(relativePath, new ExplicitPathsOptions() { ShouldFailOnUnmatchedPath = false })); + Assert.DoesNotThrow(() => Commands.Unstage(repo, relativePath, new ExplicitPathsOptions() { ShouldFailOnUnmatchedPath = false })); Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); } } @@ -126,7 +126,7 @@ public void CanUnstageTheRemovalOfAFile() Assert.Equal(FileStatus.DeletedFromIndex, repo.RetrieveStatus(filename)); - repo.Unstage(filename); + Commands.Unstage(repo, filename); Assert.Equal(count + 1, repo.Index.Count); Assert.Equal(FileStatus.DeletedFromWorkdir, repo.RetrieveStatus(filename)); @@ -143,14 +143,14 @@ public void CanUnstageUntrackedFileAgainstAnOrphanedHead() const string relativePath = "a.txt"; Touch(repo.Info.WorkingDirectory, relativePath, "hello test file\n"); - repo.Stage(relativePath); + Commands.Stage(repo, relativePath); - repo.Unstage(relativePath); + Commands.Unstage(repo, relativePath); RepositoryStatus status = repo.RetrieveStatus(); Assert.Equal(0, status.Staged.Count()); Assert.Equal(1, status.Untracked.Count()); - Assert.Throws(() => repo.Unstage("i-dont-exist", new ExplicitPathsOptions())); + Assert.Throws(() => Commands.Unstage(repo, "i-dont-exist", new ExplicitPathsOptions())); } } @@ -166,7 +166,7 @@ public void UnstagingUnknownPathsAgainstAnOrphanedHeadWithStrictUnmatchedExplici Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); - Assert.Throws(() => repo.Unstage(relativePath, new ExplicitPathsOptions())); + Assert.Throws(() => Commands.Unstage(repo, relativePath, new ExplicitPathsOptions())); } } @@ -182,8 +182,8 @@ public void CanUnstageUnknownPathsAgainstAnOrphanedHeadWithLaxUnmatchedExplicitP Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); - Assert.DoesNotThrow(() => repo.Unstage(relativePath)); - Assert.DoesNotThrow(() => repo.Unstage(relativePath, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false })); + Assert.DoesNotThrow(() => Commands.Unstage(repo, relativePath)); + Assert.DoesNotThrow(() => Commands.Unstage(repo, relativePath, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false })); Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); } } @@ -200,7 +200,7 @@ public void UnstagingANewFileWithAFullPathWhichEscapesOutOfTheWorkingDirThrows() const string filename = "unit_test.txt"; string fullPath = Touch(di.FullName, filename, "some contents"); - Assert.Throws(() => repo.Unstage(fullPath)); + Assert.Throws(() => Commands.Unstage(repo, fullPath)); } } @@ -218,7 +218,7 @@ public void UnstagingANewFileWithAFullPathWhichEscapesOutOfTheWorkingDirAgainstA const string filename = "unit_test.txt"; string fullPath = Touch(di.FullName, filename, "some contents"); - Assert.Throws(() => repo.Unstage(fullPath)); + Assert.Throws(() => Commands.Unstage(repo, fullPath)); } } @@ -228,10 +228,10 @@ public void UnstagingFileWithBadParamsThrows() var path = SandboxStandardTestRepoGitDir(); using (var repo = new Repository(path)) { - Assert.Throws(() => repo.Unstage(string.Empty)); - Assert.Throws(() => repo.Unstage((string)null)); - Assert.Throws(() => repo.Unstage(new string[] { })); - Assert.Throws(() => repo.Unstage(new string[] { null })); + Assert.Throws(() => Commands.Unstage(repo, string.Empty)); + Assert.Throws(() => Commands.Unstage(repo, (string)null)); + Assert.Throws(() => Commands.Unstage(repo, new string[] { })); + Assert.Throws(() => Commands.Unstage(repo, new string[] { null })); } } @@ -247,7 +247,7 @@ public void CanUnstageSourceOfARename() Assert.Equal(FileStatus.Nonexistent, oldStatus["branch_file.txt"].State); Assert.Equal(FileStatus.RenamedInIndex, oldStatus["renamed_branch_file.txt"].State); - repo.Unstage(new string[] { "branch_file.txt" }); + Commands.Unstage(repo, new string[] { "branch_file.txt" }); RepositoryStatus newStatus = repo.RetrieveStatus(); Assert.Equal(0, newStatus.RenamedInIndex.Count()); @@ -267,7 +267,7 @@ public void CanUnstageTargetOfARename() Assert.Equal(1, oldStatus.RenamedInIndex.Count()); Assert.Equal(FileStatus.RenamedInIndex, oldStatus["renamed_branch_file.txt"].State); - repo.Unstage(new string[] { "renamed_branch_file.txt" }); + Commands.Unstage(repo, new string[] { "renamed_branch_file.txt" }); RepositoryStatus newStatus = repo.RetrieveStatus(); Assert.Equal(0, newStatus.RenamedInIndex.Count()); @@ -282,7 +282,7 @@ public void CanUnstageBothSidesOfARename() using (var repo = new Repository(SandboxStandardTestRepo())) { repo.Move("branch_file.txt", "renamed_branch_file.txt"); - repo.Unstage(new string[] { "branch_file.txt", "renamed_branch_file.txt" }); + Commands.Unstage(repo, new string[] { "branch_file.txt", "renamed_branch_file.txt" }); RepositoryStatus status = repo.RetrieveStatus(); Assert.Equal(FileStatus.DeletedFromWorkdir, status["branch_file.txt"].State); diff --git a/LibGit2Sharp/Commands/Stage.cs b/LibGit2Sharp/Commands/Stage.cs new file mode 100644 index 000000000..8db58931c --- /dev/null +++ b/LibGit2Sharp/Commands/Stage.cs @@ -0,0 +1,204 @@ +using System; +using System.Linq; +using System.Globalization; +using System.Collections.Generic; +using LibGit2Sharp; +using LibGit2Sharp.Core; + +namespace LibGit2Sharp +{ + public static partial class Commands + { + /// + /// Promotes to the staging area the latest modifications of a file in the working directory (addition, updation or removal). + /// + /// If this path is ignored by configuration then it will not be staged unless is unset. + /// + /// The repository in which to act + /// The path of the file within the working directory. + public static void Stage(IRepository repository, string path) + { + Ensure.ArgumentNotNull(repository, "repository"); + Ensure.ArgumentNotNull(path, "path"); + + Stage(repository, new[] { path }, null); + } + + /// + /// Promotes to the staging area the latest modifications of a file in the working directory (addition, updation or removal). + /// + /// If this path is ignored by configuration then it will not be staged unless is unset. + /// + /// The repository in which to act + /// The path of the file within the working directory. + /// Determines how paths will be staged. + public static void Stage(IRepository repository, string path, StageOptions stageOptions) + { + Ensure.ArgumentNotNull(repository, "repository"); + Ensure.ArgumentNotNull(path, "path"); + + Stage(repository, new[] { path }, stageOptions); + } + + /// + /// Promotes to the staging area the latest modifications of a collection of files in the working directory (addition, updation or removal). + /// + /// Any paths (even those listed explicitly) that are ignored by configuration will not be staged unless is unset. + /// + /// The repository in which to act + /// The collection of paths of the files within the working directory. + public static void Stage(IRepository repository, IEnumerable paths) + { + Stage(repository, paths, null); + } + + /// + /// Promotes to the staging area the latest modifications of a collection of files in the working directory (addition, updation or removal). + /// + /// Any paths (even those listed explicitly) that are ignored by configuration will not be staged unless is unset. + /// + /// The repository in which to act + /// The collection of paths of the files within the working directory. + /// Determines how paths will be staged. + public static void Stage(IRepository repository, IEnumerable paths, StageOptions stageOptions) + { + Ensure.ArgumentNotNull(repository, "repository"); + Ensure.ArgumentNotNull(paths, "paths"); + + DiffModifiers diffModifiers = DiffModifiers.IncludeUntracked; + ExplicitPathsOptions explicitPathsOptions = stageOptions != null ? stageOptions.ExplicitPathsOptions : null; + + if (stageOptions != null && stageOptions.IncludeIgnored) + { + diffModifiers |= DiffModifiers.IncludeIgnored; + } + + var changes = repository.Diff.Compare(diffModifiers, paths, explicitPathsOptions, + new CompareOptions { Similarity = SimilarityOptions.None }); + + var unexpectedTypesOfChanges = changes + .Where( + tec => tec.Status != ChangeKind.Added && + tec.Status != ChangeKind.Modified && + tec.Status != ChangeKind.Conflicted && + tec.Status != ChangeKind.Unmodified && + tec.Status != ChangeKind.Deleted).ToList(); + + if (unexpectedTypesOfChanges.Count > 0) + { + throw new InvalidOperationException( + string.Format(CultureInfo.InvariantCulture, + "Entry '{0}' bears an unexpected ChangeKind '{1}'", + unexpectedTypesOfChanges[0].Path, unexpectedTypesOfChanges[0].Status)); + } + + /* Remove files from the index that don't exist on disk */ + foreach (TreeEntryChanges treeEntryChanges in changes) + { + switch (treeEntryChanges.Status) + { + case ChangeKind.Conflicted: + if (!treeEntryChanges.Exists) + { + repository.Index.Remove(treeEntryChanges.Path); + } + break; + + case ChangeKind.Deleted: + repository.Index.Remove(treeEntryChanges.Path); + break; + + default: + continue; + } + } + + foreach (TreeEntryChanges treeEntryChanges in changes) + { + switch (treeEntryChanges.Status) + { + case ChangeKind.Added: + case ChangeKind.Modified: + repository.Index.Add(treeEntryChanges.Path); + break; + + case ChangeKind.Conflicted: + if (treeEntryChanges.Exists) + { + repository.Index.Add(treeEntryChanges.Path); + } + break; + + default: + continue; + } + } + + repository.Index.Write(); + } + + /// + /// Removes from the staging area all the modifications of a file since the latest commit (addition, updation or removal). + /// + /// The repository in which to act + /// The path of the file within the working directory. + public static void Unstage(IRepository repository, string path) + { + Unstage(repository, path, null); + } + + /// + /// Removes from the staging area all the modifications of a file since the latest commit (addition, updation or removal). + /// + /// The repository in which to act + /// The path of the file within the working directory. + /// + /// The passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. + /// + public static void Unstage(IRepository repository, string path, ExplicitPathsOptions explicitPathsOptions) + { + Ensure.ArgumentNotNull(repository, "repository"); + Ensure.ArgumentNotNull(path, "path"); + + Unstage(repository, new[] { path }, explicitPathsOptions); + } + + /// + /// Removes from the staging area all the modifications of a collection of file since the latest commit (addition, updation or removal). + /// + /// The repository in which to act + /// The collection of paths of the files within the working directory. + public static void Unstage(IRepository repository, IEnumerable paths) + { + Unstage(repository, paths, null); + } + + /// + /// Removes from the staging area all the modifications of a collection of file since the latest commit (addition, updation or removal). + /// + /// The repository in which to act + /// The collection of paths of the files within the working directory. + /// + /// The passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. + /// + public static void Unstage(IRepository repository, IEnumerable paths, ExplicitPathsOptions explicitPathsOptions) + { + Ensure.ArgumentNotNull(repository, "repository"); + Ensure.ArgumentNotNull(paths, "paths"); + + if (repository.Info.IsHeadUnborn) + { + var changes = repository.Diff.Compare(null, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None }); + + repository.Index.Replace(changes); + } + else + { + repository.Index.Replace(repository.Head.Tip, paths, explicitPathsOptions); + } + } + } +} + diff --git a/LibGit2Sharp/IRepository.cs b/LibGit2Sharp/IRepository.cs index 1bd921a51..b430db07d 100644 --- a/LibGit2Sharp/IRepository.cs +++ b/LibGit2Sharp/IRepository.cs @@ -271,6 +271,7 @@ public interface IRepository : IDisposable /// /// The path of the file within the working directory. /// Determines how paths will be staged. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Stage()")] void Stage(string path, StageOptions stageOptions); /// @@ -280,6 +281,7 @@ public interface IRepository : IDisposable /// /// The collection of paths of the files within the working directory. /// Determines how paths will be staged. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Stage()")] void Stage(IEnumerable paths, StageOptions stageOptions); /// @@ -290,6 +292,7 @@ public interface IRepository : IDisposable /// The passed will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Unstage()")] void Unstage(string path, ExplicitPathsOptions explicitPathsOptions); /// @@ -300,6 +303,7 @@ public interface IRepository : IDisposable /// The passed will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Unstage()")] void Unstage(IEnumerable paths, ExplicitPathsOptions explicitPathsOptions); /// diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index 8128741ac..3ddc6d694 100644 --- a/LibGit2Sharp/Index.cs +++ b/LibGit2Sharp/Index.cs @@ -139,8 +139,6 @@ public virtual void Replace(Tree source) { Proxy.git_index_read_fromtree(this, obj.ObjectPtr); } - - UpdatePhysicalIndex(); } /// @@ -153,7 +151,6 @@ public virtual void Replace(Tree source) public virtual void Clear() { Proxy.git_index_clear(this); - UpdatePhysicalIndex(); } private void RemoveFromIndex(string relativePath) @@ -167,14 +164,8 @@ private void RemoveFromIndex(string relativePath) /// The path of the entry to be removed. public virtual void Remove(string indexEntryPath) { - if (indexEntryPath == null) - { - throw new ArgumentNullException("indexEntryPath"); - } - + Ensure.ArgumentNotNull(indexEntryPath, "indexEntryPath"); RemoveFromIndex(indexEntryPath); - - UpdatePhysicalIndex(); } /// @@ -187,14 +178,8 @@ public virtual void Remove(string indexEntryPath) /// The path, in the working directory, of the file to be added. public virtual void Add(string pathInTheWorkdir) { - if (pathInTheWorkdir == null) - { - throw new ArgumentNullException("pathInTheWorkdir"); - } - + Ensure.ArgumentNotNull(pathInTheWorkdir, "pathInTheWorkdir"); Proxy.git_index_add_bypath(handle, pathInTheWorkdir); - - UpdatePhysicalIndex(); } /// @@ -211,25 +196,9 @@ public virtual void Add(string pathInTheWorkdir) public virtual void Add(Blob blob, string indexEntryPath, Mode indexEntryMode) { Ensure.ArgumentConformsTo(indexEntryMode, m => m.HasAny(TreeEntryDefinition.BlobModes), "indexEntryMode"); - - if (blob == null) - { - throw new ArgumentNullException("blob"); - } - - if (indexEntryPath == null) - { - throw new ArgumentNullException("indexEntryPath"); - } - + Ensure.ArgumentNotNull(blob, "blob"); + Ensure.ArgumentNotNull(indexEntryPath, "indexEntryPath"); AddEntryToTheIndex(indexEntryPath, blob.Id, indexEntryMode); - - UpdatePhysicalIndex(); - } - - private void UpdatePhysicalIndex() - { - Proxy.git_index_write(handle); } internal void Replace(TreeChanges changes) @@ -259,8 +228,6 @@ internal void Replace(TreeChanges changes) treeEntryChanges.Status)); } } - - UpdatePhysicalIndex(); } /// @@ -328,5 +295,13 @@ public virtual void Replace(Commit commit, IEnumerable paths, ExplicitPa var changes = repo.Diff.Compare(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None }); Replace(changes); } + + /// + /// Write the contents of this to disk + /// + public virtual void Write() + { + Proxy.git_index_write(handle); + } } } diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 6606f5fa2..09a3d8753 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -1,4 +1,4 @@ - + @@ -352,6 +352,7 @@ + @@ -391,4 +392,4 @@ - \ No newline at end of file + diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index 0ad989f94..c1eb4f679 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -1683,11 +1683,10 @@ internal FilePath[] ToFilePaths(IEnumerable paths) /// /// The path of the file within the working directory. /// Determines how paths will be staged. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Stage()")] public void Stage(string path, StageOptions stageOptions) { - Ensure.ArgumentNotNull(path, "path"); - - Stage(new[] { path }, stageOptions); + Commands.Stage(this, path, stageOptions); } /// @@ -1697,80 +1696,10 @@ public void Stage(string path, StageOptions stageOptions) /// /// The collection of paths of the files within the working directory. /// Determines how paths will be staged. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Stage()")] public void Stage(IEnumerable paths, StageOptions stageOptions) { - Ensure.ArgumentNotNull(paths, "paths"); - - DiffModifiers diffModifiers = DiffModifiers.IncludeUntracked; - ExplicitPathsOptions explicitPathsOptions = stageOptions != null ? stageOptions.ExplicitPathsOptions : null; - - if (stageOptions != null && stageOptions.IncludeIgnored) - { - diffModifiers |= DiffModifiers.IncludeIgnored; - } - - var changes = Diff.Compare(diffModifiers, paths, explicitPathsOptions, - new CompareOptions { Similarity = SimilarityOptions.None }); - - var unexpectedTypesOfChanges = changes - .Where( - tec => tec.Status != ChangeKind.Added && - tec.Status != ChangeKind.Modified && - tec.Status != ChangeKind.Conflicted && - tec.Status != ChangeKind.Unmodified && - tec.Status != ChangeKind.Deleted).ToList(); - - if (unexpectedTypesOfChanges.Count > 0) - { - throw new InvalidOperationException( - string.Format(CultureInfo.InvariantCulture, - "Entry '{0}' bears an unexpected ChangeKind '{1}'", - unexpectedTypesOfChanges[0].Path, unexpectedTypesOfChanges[0].Status)); - } - - /* Remove files from the index that don't exist on disk */ - foreach (TreeEntryChanges treeEntryChanges in changes) - { - switch (treeEntryChanges.Status) - { - case ChangeKind.Conflicted: - if (!treeEntryChanges.Exists) - { - RemoveFromIndex(treeEntryChanges.Path); - } - break; - - case ChangeKind.Deleted: - RemoveFromIndex(treeEntryChanges.Path); - break; - - default: - continue; - } - } - - foreach (TreeEntryChanges treeEntryChanges in changes) - { - switch (treeEntryChanges.Status) - { - case ChangeKind.Added: - case ChangeKind.Modified: - AddToIndex(treeEntryChanges.Path); - break; - - case ChangeKind.Conflicted: - if (treeEntryChanges.Exists) - { - AddToIndex(treeEntryChanges.Path); - } - break; - - default: - continue; - } - } - - UpdatePhysicalIndex(); + Commands.Stage(this, paths, stageOptions); } /// @@ -1781,11 +1710,10 @@ public void Stage(IEnumerable paths, StageOptions stageOptions) /// The passed will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Unstage()")] public void Unstage(string path, ExplicitPathsOptions explicitPathsOptions) { - Ensure.ArgumentNotNull(path, "path"); - - Unstage(new[] { path }, explicitPathsOptions); + Commands.Unstage(this, path, explicitPathsOptions); } /// @@ -1796,20 +1724,10 @@ public void Unstage(string path, ExplicitPathsOptions explicitPathsOptions) /// The passed will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Unstage()")] public void Unstage(IEnumerable paths, ExplicitPathsOptions explicitPathsOptions) { - Ensure.ArgumentNotNull(paths, "paths"); - - if (Info.IsHeadUnborn) - { - var changes = Diff.Compare(null, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None }); - - Index.Replace(changes); - } - else - { - Index.Replace(Head.Tip, paths, explicitPathsOptions); - } + Commands.Unstage(this, paths, explicitPathsOptions); } /// @@ -1822,7 +1740,7 @@ public 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. /// /// The paths of the files within the working directory which have to be moved/renamed. @@ -2005,7 +1923,7 @@ internal void ReloadFromDisk() Proxy.git_index_read(Index.Handle); } - private void AddToIndex(string relativePath) + internal void AddToIndex(string relativePath) { if (!Submodules.TryStage(relativePath, true)) { @@ -2013,14 +1931,14 @@ private void AddToIndex(string relativePath) } } - private string RemoveFromIndex(string relativePath) + internal string RemoveFromIndex(string relativePath) { Proxy.git_index_remove_bypath(Index.Handle, relativePath); return relativePath; } - private void UpdatePhysicalIndex() + internal void UpdatePhysicalIndex() { Proxy.git_index_write(Index.Handle); } diff --git a/LibGit2Sharp/RepositoryExtensions.cs b/LibGit2Sharp/RepositoryExtensions.cs index 643dfb94a..9e4a69548 100644 --- a/LibGit2Sharp/RepositoryExtensions.cs +++ b/LibGit2Sharp/RepositoryExtensions.cs @@ -560,6 +560,7 @@ public static RevertResult Revert(this IRepository repository, Commit commit, Si /// /// The being worked with. /// The path of the file within the working directory. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Stage()")] public static void Stage(this IRepository repository, string path) { repository.Stage(path, null); @@ -570,6 +571,7 @@ public static void Stage(this IRepository repository, string path) /// /// The being worked with. /// The collection of paths of the files within the working directory. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Stage()")] public static void Stage(this IRepository repository, IEnumerable paths) { repository.Stage(paths, null); @@ -580,6 +582,7 @@ public static void Stage(this IRepository repository, IEnumerable paths) /// /// The being worked with. /// The path of the file within the working directory. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Unstage()")] public static void Unstage(this IRepository repository, string path) { repository.Unstage(path, null); @@ -590,6 +593,7 @@ public static void Unstage(this IRepository repository, string path) /// /// The being worked with. /// The collection of paths of the files within the working directory. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Unstage()")] public static void Unstage(this IRepository repository, IEnumerable paths) { repository.Unstage(paths, null); From 2d4d66dade6d006b89ead3b1f4800abdf811d51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 23 Mar 2016 23:21:25 +0100 Subject: [PATCH 2/3] Move Remove to Commands This deprecates them from the repository itself and makes it clear this isn't a fundamental operation but something which builds on them. --- LibGit2Sharp.Tests/CheckoutFixture.cs | 2 +- LibGit2Sharp.Tests/CommitFixture.cs | 2 +- LibGit2Sharp.Tests/ConflictFixture.cs | 2 +- LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs | 2 +- LibGit2Sharp.Tests/MergeFixture.cs | 2 +- LibGit2Sharp.Tests/RemoveFixture.cs | 26 +-- LibGit2Sharp/Commands/Remove.cs | 240 ++++++++++++++++++++ LibGit2Sharp/IRepository.cs | 2 + LibGit2Sharp/LibGit2Sharp.csproj | 1 + LibGit2Sharp/Repository.cs | 113 +-------- LibGit2Sharp/RepositoryExtensions.cs | 10 +- 11 files changed, 272 insertions(+), 130 deletions(-) create mode 100644 LibGit2Sharp/Commands/Remove.cs diff --git a/LibGit2Sharp.Tests/CheckoutFixture.cs b/LibGit2Sharp.Tests/CheckoutFixture.cs index 2d0789984..c84ea7e0b 100644 --- a/LibGit2Sharp.Tests/CheckoutFixture.cs +++ b/LibGit2Sharp.Tests/CheckoutFixture.cs @@ -156,7 +156,7 @@ public void CheckoutAddsMissingFilesInWorkingDirectory() // Remove the file in master branch // Verify it exists after checking out otherBranch. string fileFullPath = Path.Combine(repo.Info.WorkingDirectory, originalFilePath); - repo.Remove(fileFullPath); + Commands.Remove(repo, fileFullPath); repo.Commit("2nd commit", Constants.Signature, Constants.Signature); // Checkout other_branch diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index 5078672d0..a8fa563bb 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -1039,7 +1039,7 @@ public void CanNotAmendACommitInAWayThatWouldLeadTheNewCommitToBecomeEmpty() repo.Commit("One commit", Constants.Signature, Constants.Signature); - repo.Remove("new.txt"); + Commands.Remove(repo, "new.txt"); Assert.Throws(() => repo.Commit("Oops", Constants.Signature, Constants.Signature, new CommitOptions { AmendPreviousCommit = true })); diff --git a/LibGit2Sharp.Tests/ConflictFixture.cs b/LibGit2Sharp.Tests/ConflictFixture.cs index 65a98659e..10d498500 100644 --- a/LibGit2Sharp.Tests/ConflictFixture.cs +++ b/LibGit2Sharp.Tests/ConflictFixture.cs @@ -77,7 +77,7 @@ public void CanResolveConflictsByRemovingFromTheIndex( Assert.NotNull(repo.Index.Conflicts[filename]); Assert.Equal(0, repo.Index.Conflicts.ResolvedConflicts.Count()); - repo.Remove(filename, removeFromWorkdir); + Commands.Remove(repo, filename, removeFromWorkdir); Assert.Null(repo.Index.Conflicts[filename]); Assert.Equal(count - removedIndexEntries, repo.Index.Count); diff --git a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs index 4d07f23e0..494642e9b 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs @@ -133,7 +133,7 @@ public void CanDetectABinaryDeletion() var patch = repo.Diff.Compare(commit.Tree, DiffTargets.WorkingDirectory, new [] {filename}); Assert.True(patch[filename].IsBinaryComparison); - repo.Remove(filename); + Commands.Remove(repo, filename); var commit2 = repo.Commit("Delete binary file", Constants.Signature, Constants.Signature); var patch2 = repo.Diff.Compare(commit.Tree, commit2.Tree, new[] { filename }); diff --git a/LibGit2Sharp.Tests/MergeFixture.cs b/LibGit2Sharp.Tests/MergeFixture.cs index 99e1e4595..2598c81b3 100644 --- a/LibGit2Sharp.Tests/MergeFixture.cs +++ b/LibGit2Sharp.Tests/MergeFixture.cs @@ -751,7 +751,7 @@ public void CanMergeIntoOrphanedBranch() foreach(var entry in repo.RetrieveStatus()) { Commands.Unstage(repo, entry.FilePath); - repo.Remove(entry.FilePath, true); + Commands.Remove(repo, entry.FilePath, true); } // Assert that we have an empty working directory. diff --git a/LibGit2Sharp.Tests/RemoveFixture.cs b/LibGit2Sharp.Tests/RemoveFixture.cs index 3ab860994..a89977fce 100644 --- a/LibGit2Sharp.Tests/RemoveFixture.cs +++ b/LibGit2Sharp.Tests/RemoveFixture.cs @@ -59,12 +59,12 @@ public void CanRemoveAnUnalteredFileFromTheIndexWithoutRemovingItFromTheWorkingD if (throws) { - Assert.Throws(() => repo.Remove(filename, removeFromWorkdir)); + Assert.Throws(() => Commands.Remove(repo, filename, removeFromWorkdir)); Assert.Equal(count, repo.Index.Count); } else { - repo.Remove(filename, removeFromWorkdir); + Commands.Remove(repo, filename, removeFromWorkdir); Assert.Equal(count - 1, repo.Index.Count); Assert.Equal(existsAfterRemove, File.Exists(fullpath)); @@ -93,8 +93,8 @@ public void RemovingAModifiedFileWhoseChangesHaveBeenPromotedToTheIndexAndWithAd File.AppendAllText(fullpath, "additional content"); Assert.Equal(FileStatus.ModifiedInIndex | FileStatus.ModifiedInWorkdir, repo.RetrieveStatus(filename)); - Assert.Throws(() => repo.Remove(filename)); - Assert.Throws(() => repo.Remove(filename, false)); + Assert.Throws(() => Commands.Remove(repo, filename)); + Assert.Throws(() => Commands.Remove(repo, filename, false)); } } @@ -113,7 +113,7 @@ public void CanRemoveAFolderThroughUsageOfPathspecsForNewlyAddedFiles() int count = repo.Index.Count; Assert.True(Directory.Exists(Path.Combine(repo.Info.WorkingDirectory, "2"))); - repo.Remove("2", false); + Commands.Remove(repo, "2", false); Assert.Equal(count - 5, repo.Index.Count); } @@ -128,7 +128,7 @@ public void CanRemoveAFolderThroughUsageOfPathspecsForFilesAlreadyInTheIndexAndI int count = repo.Index.Count; Assert.True(Directory.Exists(Path.Combine(repo.Info.WorkingDirectory, "1"))); - repo.Remove("1"); + Commands.Remove(repo, "1"); Assert.False(Directory.Exists(Path.Combine(repo.Info.WorkingDirectory, "1"))); Assert.Equal(count - 1, repo.Index.Count); @@ -148,8 +148,8 @@ public void RemovingAnUnknownFileWithLaxExplicitPathsValidationDoesntThrow(strin Assert.Null(repo.Index[relativePath]); Assert.Equal(status, repo.RetrieveStatus(relativePath)); - repo.Remove(relativePath, i % 2 == 0); - repo.Remove(relativePath, i % 2 == 0, + Commands.Remove(repo, relativePath, i % 2 == 0); + Commands.Remove(repo, relativePath, i % 2 == 0, new ExplicitPathsOptions {ShouldFailOnUnmatchedPath = false}); } } @@ -169,7 +169,7 @@ public void RemovingAnUnknownFileThrowsIfExplicitPath(string relativePath, FileS Assert.Equal(status, repo.RetrieveStatus(relativePath)); Assert.Throws( - () => repo.Remove(relativePath, i%2 == 0, new ExplicitPathsOptions())); + () => Commands.Remove(repo, relativePath, i%2 == 0, new ExplicitPathsOptions())); } } } @@ -180,10 +180,10 @@ public void RemovingFileWithBadParamsThrows() var path = SandboxStandardTestRepoGitDir(); using (var repo = new Repository(path)) { - Assert.Throws(() => repo.Remove(string.Empty)); - Assert.Throws(() => repo.Remove((string)null)); - Assert.Throws(() => repo.Remove(new string[] { })); - Assert.Throws(() => repo.Remove(new string[] { null })); + Assert.Throws(() => Commands.Remove(repo, string.Empty)); + Assert.Throws(() => Commands.Remove(repo, (string)null)); + Assert.Throws(() => Commands.Remove(repo, new string[] { })); + Assert.Throws(() => Commands.Remove(repo, new string[] { null })); } } } diff --git a/LibGit2Sharp/Commands/Remove.cs b/LibGit2Sharp/Commands/Remove.cs new file mode 100644 index 000000000..87265a2dd --- /dev/null +++ b/LibGit2Sharp/Commands/Remove.cs @@ -0,0 +1,240 @@ +using System.Linq; +using System.IO; +using System.Collections.Generic; +using LibGit2Sharp; +using LibGit2Sharp.Core; + +namespace LibGit2Sharp +{ + public static partial class Commands + { + + /// + /// 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. + /// + /// + /// The being worked with. + /// The path of the file within the working directory. + public static void Remove(IRepository repository, string path) + { + Remove(repository, path, true, null); + } + + /// + /// 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. + /// + /// + /// The being worked with. + /// The path of the file within the working directory. + /// True to remove the file from the working directory, False otherwise. + public static void Remove(IRepository repository, string path, bool removeFromWorkingDirectory) + { + Remove(repository, path, removeFromWorkingDirectory, null); + } + + + /// + /// 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 repository in which to operate + /// The path of the file within the working directory. + /// True to remove the file from the working directory, False otherwise. + /// + /// The passed will be treated as an explicit path. + /// Use these options to determine how unmatched explicit paths should be handled. + /// + public static void Remove(IRepository repository, string path, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions) + { + Ensure.ArgumentNotNull(repository, "repository"); + Ensure.ArgumentNotNull(path, "path"); + + Remove(repository, new[] { path }, removeFromWorkingDirectory, explicitPathsOptions); + } + + /// + /// 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. + /// + /// + /// The being worked with. + /// The collection of paths of the files within the working directory. + public static void Remove(IRepository repository, IEnumerable paths) + { + Remove(repository, paths, true, null); + } + + /// + /// 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 repository in which to operate + /// The collection of paths of the files within the working directory. + /// True to remove the files from the working directory, False otherwise. + /// + /// The passed will be treated as explicit paths. + /// Use these options to determine how unmatched explicit paths should be handled. + /// + public static void Remove(IRepository repository, IEnumerable paths, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions) + { + Ensure.ArgumentNotNull(repository, "repository"); + Ensure.ArgumentNotNullOrEmptyEnumerable(paths, "paths"); + + var pathsToDelete = paths.Where(p => Directory.Exists(Path.Combine(repository.Info.WorkingDirectory, p))).ToList(); + var notConflictedPaths = new List(); + var index = repository.Index; + + foreach (var path in paths) + { + Ensure.ArgumentNotNullOrEmptyString(path, "path"); + + var conflict = index.Conflicts[path]; + + if (conflict != null) + { + index.Remove(path); + pathsToDelete.Add(path); + } + else + { + notConflictedPaths.Add(path); + } + } + + // Make sure status will see the changes from before this + index.Write(); + + if (notConflictedPaths.Count > 0) + { + pathsToDelete.AddRange(RemoveStagedItems(repository, notConflictedPaths, removeFromWorkingDirectory, explicitPathsOptions)); + } + + if (removeFromWorkingDirectory) + { + RemoveFilesAndFolders(repository, pathsToDelete); + } + + index.Write(); + } + + private static void RemoveFilesAndFolders(IRepository repository, IEnumerable pathsList) + { + string wd = repository.Info.WorkingDirectory; + + foreach (string path in pathsList) + { + string fileName = Path.Combine(wd, path); + + if (Directory.Exists(fileName)) + { + Directory.Delete(fileName, true); + continue; + } + + if (!File.Exists(fileName)) + { + continue; + } + + File.Delete(fileName); + } + } + + private static IEnumerable RemoveStagedItems(IRepository repository, IEnumerable paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) + { + var removed = new List(); + var changes = repository.Diff.Compare(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, paths, explicitPathsOptions); + var index = repository.Index; + + foreach (var treeEntryChanges in changes) + { + var status = repository.RetrieveStatus(treeEntryChanges.Path); + + switch (treeEntryChanges.Status) + { + case ChangeKind.Added: + case ChangeKind.Deleted: + removed.Add(treeEntryChanges.Path); + index.Remove(treeEntryChanges.Path); + break; + + case ChangeKind.Unmodified: + if (removeFromWorkingDirectory && ( + status.HasFlag(FileStatus.ModifiedInIndex) || + status.HasFlag(FileStatus.NewInIndex))) + { + throw new RemoveFromIndexException("Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", + treeEntryChanges.Path); + } + removed.Add(treeEntryChanges.Path); + index.Remove(treeEntryChanges.Path); + continue; + + case ChangeKind.Modified: + if (status.HasFlag(FileStatus.ModifiedInWorkdir) && status.HasFlag(FileStatus.ModifiedInIndex)) + { + throw new RemoveFromIndexException("Unable to remove file '{0}', as it has staged content different from both the working directory and the HEAD.", + treeEntryChanges.Path); + } + if (removeFromWorkingDirectory) + { + throw new RemoveFromIndexException("Unable to remove file '{0}', as it has local modifications. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", + treeEntryChanges.Path); + } + removed.Add(treeEntryChanges.Path); + index.Remove(treeEntryChanges.Path); + continue; + + default: + throw new RemoveFromIndexException("Unable to remove file '{0}'. Its current status is '{1}'.", + treeEntryChanges.Path, + treeEntryChanges.Status); + } + } + + index.Write(); + + return removed; + } + } +} + diff --git a/LibGit2Sharp/IRepository.cs b/LibGit2Sharp/IRepository.cs index b430db07d..ea91d3c31 100644 --- a/LibGit2Sharp/IRepository.cs +++ b/LibGit2Sharp/IRepository.cs @@ -341,6 +341,7 @@ public interface IRepository : IDisposable /// The passed will be treated as an explicit path. /// Use these options to determine how unmatched explicit paths should be handled. /// + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Remove()")] void Remove(string path, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions); /// @@ -364,6 +365,7 @@ public interface IRepository : IDisposable /// The passed will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Unstage()")] void Remove(IEnumerable paths, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions); /// diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 09a3d8753..bd3ef3b15 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -353,6 +353,7 @@ + diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index c1eb4f679..b66b70ee1 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -1828,11 +1828,10 @@ public void Move(IEnumerable sourcePaths, IEnumerable destinatio /// The passed will be treated as an explicit path. /// Use these options to determine how unmatched explicit paths should be handled. /// + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Remove")] public void Remove(string path, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions) { - Ensure.ArgumentNotNull(path, "path"); - - Remove(new[] { path }, removeFromWorkingDirectory, explicitPathsOptions); + Commands.Remove(this, path, removeFromWorkingDirectory, explicitPathsOptions); } /// @@ -1856,40 +1855,10 @@ public void Remove(string path, bool removeFromWorkingDirectory, ExplicitPathsOp /// The passed will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Remove")] public void Remove(IEnumerable paths, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions) { - Ensure.ArgumentNotNullOrEmptyEnumerable(paths, "paths"); - - var pathsToDelete = paths.Where(p => Directory.Exists(Path.Combine(Info.WorkingDirectory, p))).ToList(); - var notConflictedPaths = new List(); - - foreach (var path in paths) - { - Ensure.ArgumentNotNullOrEmptyString(path, "path"); - - var conflict = Index.Conflicts[path]; - - if (conflict != null) - { - pathsToDelete.Add(RemoveFromIndex(path)); - } - else - { - notConflictedPaths.Add(path); - } - } - - if (notConflictedPaths.Count > 0) - { - pathsToDelete.AddRange(RemoveStagedItems(notConflictedPaths, removeFromWorkingDirectory, explicitPathsOptions)); - } - - if (removeFromWorkingDirectory) - { - RemoveFilesAndFolders(pathsToDelete); - } - - UpdatePhysicalIndex(); + Commands.Remove(this, paths, removeFromWorkingDirectory, explicitPathsOptions); } /// @@ -1979,80 +1948,6 @@ private IDictionary, Tuple> Prepar return dic; } - private void RemoveFilesAndFolders(IEnumerable pathsList) - { - string wd = Info.WorkingDirectory; - - foreach (string path in pathsList) - { - string fileName = Path.Combine(wd, path); - - if (Directory.Exists(fileName)) - { - Directory.Delete(fileName, true); - continue; - } - - if (!File.Exists(fileName)) - { - continue; - } - - File.Delete(fileName); - } - } - - private IEnumerable RemoveStagedItems(IEnumerable paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) - { - var removed = new List(); - var changes = Diff.Compare(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, paths, explicitPathsOptions); - - foreach (var treeEntryChanges in changes) - { - var status = RetrieveStatus(treeEntryChanges.Path); - - switch (treeEntryChanges.Status) - { - case ChangeKind.Added: - case ChangeKind.Deleted: - removed.Add(RemoveFromIndex(treeEntryChanges.Path)); - break; - - case ChangeKind.Unmodified: - if (removeFromWorkingDirectory && ( - status.HasFlag(FileStatus.ModifiedInIndex) || - status.HasFlag(FileStatus.NewInIndex))) - { - throw new RemoveFromIndexException("Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", - treeEntryChanges.Path); - } - removed.Add(RemoveFromIndex(treeEntryChanges.Path)); - continue; - - case ChangeKind.Modified: - if (status.HasFlag(FileStatus.ModifiedInWorkdir) && status.HasFlag(FileStatus.ModifiedInIndex)) - { - throw new RemoveFromIndexException("Unable to remove file '{0}', as it has staged content different from both the working directory and the HEAD.", - treeEntryChanges.Path); - } - if (removeFromWorkingDirectory) - { - throw new RemoveFromIndexException("Unable to remove file '{0}', as it has local modifications. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", - treeEntryChanges.Path); - } - removed.Add(RemoveFromIndex(treeEntryChanges.Path)); - continue; - - default: - throw new RemoveFromIndexException("Unable to remove file '{0}'. Its current status is '{1}'.", - treeEntryChanges.Path, - treeEntryChanges.Status); - } - } - - return removed; - } - /// /// Finds the most recent annotated tag that is reachable from a commit. /// diff --git a/LibGit2Sharp/RepositoryExtensions.cs b/LibGit2Sharp/RepositoryExtensions.cs index 9e4a69548..1e90080b4 100644 --- a/LibGit2Sharp/RepositoryExtensions.cs +++ b/LibGit2Sharp/RepositoryExtensions.cs @@ -611,9 +611,10 @@ public static void Unstage(this IRepository repository, IEnumerable path /// /// The being worked with. /// The path of the file within the working directory. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Remove")] public static void Remove(this IRepository repository, string path) { - repository.Remove(path, true, null); + Commands.Remove(repository, path, true, null); } /// @@ -629,9 +630,10 @@ public static void Remove(this IRepository repository, string path) /// The being worked with. /// The path of the file within the working directory. /// True to remove the file from the working directory, False otherwise. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Remove")] public static void Remove(this IRepository repository, string path, bool removeFromWorkingDirectory) { - repository.Remove(path, removeFromWorkingDirectory, null); + Commands.Remove(repository, path, removeFromWorkingDirectory, null); } /// @@ -646,9 +648,10 @@ public static void Remove(this IRepository repository, string path, bool removeF /// /// The being worked with. /// The collection of paths of the files within the working directory. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Remove")] public static void Remove(this IRepository repository, IEnumerable paths) { - repository.Remove(paths, true, null); + Commands.Remove(repository, paths, true, null); } /// @@ -664,6 +667,7 @@ public static void Remove(this IRepository repository, IEnumerable paths /// The being worked with. /// The collection of paths of the files within the working directory. /// True to remove the files from the working directory, False otherwise. + [Obsolete("This method is deprecated. Please use LibGit2Sharp.Commands.Remove")] public static void Remove(this IRepository repository, IEnumerable paths, bool removeFromWorkingDirectory) { repository.Remove(paths, removeFromWorkingDirectory, null); From 78be9800fbdc4e93eb0f1a5a9c3cf83b027a0a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Thu, 24 Mar 2016 08:52:48 +0100 Subject: [PATCH 3/3] Put Move in Commands --- LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs | 12 +- LibGit2Sharp.Tests/FileHistoryFixture.cs | 2 +- LibGit2Sharp.Tests/IndexFixture.cs | 6 +- LibGit2Sharp.Tests/ResetIndexFixture.cs | 6 +- LibGit2Sharp.Tests/UnstageFixture.cs | 6 +- LibGit2Sharp/Commands/Stage.cs | 118 ++++++++++++++++++++ LibGit2Sharp/IRepository.cs | 2 + LibGit2Sharp/Repository.cs | 104 +---------------- LibGit2Sharp/RepositoryExtensions.cs | 10 +- 9 files changed, 148 insertions(+), 118 deletions(-) diff --git a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs index 494642e9b..5be987aaf 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs @@ -293,7 +293,7 @@ public void DetectsTheExactRenamingOfFilesByDefault() Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); - repo.Move(originalPath, renamedPath); + Commands.Move(repo, originalPath, renamedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -331,7 +331,7 @@ public void RenameThresholdsAreObeyed() // 8 lines, 50% are from original file Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\ne\nf\ng\nh\n"); Commands.Stage(repo, originalPath); - repo.Move(originalPath, renamedPath); + Commands.Move(repo, originalPath, renamedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -369,7 +369,7 @@ public void ExactModeDetectsExactRenames() Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); - repo.Move(originalPath, renamedPath); + Commands.Move(repo, originalPath, renamedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -434,7 +434,7 @@ public void ExactModeDoesntDetectRenamesWithEdits() Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); - repo.Move(originalPath, renamedPath); + Commands.Move(repo, originalPath, renamedPath); File.AppendAllText(Path.Combine(repo.Info.WorkingDirectory, renamedPath), "e\nf\n"); Commands.Stage(repo, renamedPath); @@ -508,7 +508,7 @@ public void CanNotDetectTheExactRenamingFilesWhenNotEnabled() Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature); - repo.Move(originalPath, renamedPath); + Commands.Move(repo, originalPath, renamedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); @@ -725,7 +725,7 @@ public void CanDetectTheExactRenamingExactCopyingOfNonModifiedAndModifiedFilesWh Commands.Stage(repo, originalPath3); Commands.Stage(repo, copiedPath1); Commands.Stage(repo, copiedPath2); - repo.Move(originalPath, renamedPath); + Commands.Move(repo, originalPath, renamedPath); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp.Tests/FileHistoryFixture.cs b/LibGit2Sharp.Tests/FileHistoryFixture.cs index 0c4921a9d..2acd5d748 100644 --- a/LibGit2Sharp.Tests/FileHistoryFixture.cs +++ b/LibGit2Sharp.Tests/FileHistoryFixture.cs @@ -152,7 +152,7 @@ public void CanTellComplexCommitHistory() // Move the first file to a new directory. var newPath1 = Path.Combine(SubFolderPath1, path1); - repo.Move(path1, newPath1); + Commands.Move(repo, path1, newPath1); var commit3 = repo.Commit("Moved " + path1 + " to " + newPath1, Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp.Tests/IndexFixture.cs b/LibGit2Sharp.Tests/IndexFixture.cs index 6bf814732..cd23df948 100644 --- a/LibGit2Sharp.Tests/IndexFixture.cs +++ b/LibGit2Sharp.Tests/IndexFixture.cs @@ -120,7 +120,7 @@ public void CanRenameAFile() const string newName = "being.frakking.polite.txt"; - repo.Move(oldName, newName); + Commands.Move(repo, oldName, newName); Assert.Equal(FileStatus.DeletedFromIndex, repo.RetrieveStatus(oldName)); Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus(newName)); @@ -150,7 +150,7 @@ public void CanMoveAnExistingFileOverANonExistingFile(string sourcePath, FileSta Assert.Equal(sourceStatus, repo.RetrieveStatus(sourcePath)); Assert.Equal(destStatus, repo.RetrieveStatus(destPath)); - repo.Move(sourcePath, destPath); + Commands.Move(repo, sourcePath, destPath); Assert.Equal(sourcePostStatus, repo.RetrieveStatus(sourcePath)); Assert.Equal(destPostStatus, repo.RetrieveStatus(destPath)); @@ -193,7 +193,7 @@ private void InvalidMoveUseCases(string sourcePath, FileStatus sourceStatus, IEn foreach (var destPath in destPaths) { string path = destPath; - Assert.Throws(() => repo.Move(sourcePath, path)); + Assert.Throws(() => Commands.Move(repo, sourcePath, path)); } } } diff --git a/LibGit2Sharp.Tests/ResetIndexFixture.cs b/LibGit2Sharp.Tests/ResetIndexFixture.cs index 082566218..0952e55f5 100644 --- a/LibGit2Sharp.Tests/ResetIndexFixture.cs +++ b/LibGit2Sharp.Tests/ResetIndexFixture.cs @@ -116,7 +116,7 @@ public void CanResetTheIndexWhenARenameExists() { using (var repo = new Repository(SandboxStandardTestRepo())) { - repo.Move("branch_file.txt", "renamed_branch_file.txt"); + Commands.Move(repo, "branch_file.txt", "renamed_branch_file.txt"); repo.Index.Replace(repo.Lookup("32eab9c")); RepositoryStatus status = repo.RetrieveStatus(); @@ -129,7 +129,7 @@ public void CanResetSourceOfARenameInIndex() { using (var repo = new Repository(SandboxStandardTestRepo())) { - repo.Move("branch_file.txt", "renamed_branch_file.txt"); + Commands.Move(repo, "branch_file.txt", "renamed_branch_file.txt"); RepositoryStatus oldStatus = repo.RetrieveStatus(); Assert.Equal(1, oldStatus.RenamedInIndex.Count()); @@ -150,7 +150,7 @@ public void CanResetTargetOfARenameInIndex() { using (var repo = new Repository(SandboxStandardTestRepo())) { - repo.Move("branch_file.txt", "renamed_branch_file.txt"); + Commands.Move(repo, "branch_file.txt", "renamed_branch_file.txt"); RepositoryStatus oldStatus = repo.RetrieveStatus(); Assert.Equal(1, oldStatus.RenamedInIndex.Count()); diff --git a/LibGit2Sharp.Tests/UnstageFixture.cs b/LibGit2Sharp.Tests/UnstageFixture.cs index d58ffb122..786ed14c7 100644 --- a/LibGit2Sharp.Tests/UnstageFixture.cs +++ b/LibGit2Sharp.Tests/UnstageFixture.cs @@ -240,7 +240,7 @@ public void CanUnstageSourceOfARename() { using (var repo = new Repository(SandboxStandardTestRepo())) { - repo.Move("branch_file.txt", "renamed_branch_file.txt"); + Commands.Move(repo, "branch_file.txt", "renamed_branch_file.txt"); RepositoryStatus oldStatus = repo.RetrieveStatus(); Assert.Equal(1, oldStatus.RenamedInIndex.Count()); @@ -261,7 +261,7 @@ public void CanUnstageTargetOfARename() { using (var repo = new Repository(SandboxStandardTestRepo())) { - repo.Move("branch_file.txt", "renamed_branch_file.txt"); + Commands.Move(repo, "branch_file.txt", "renamed_branch_file.txt"); RepositoryStatus oldStatus = repo.RetrieveStatus(); Assert.Equal(1, oldStatus.RenamedInIndex.Count()); @@ -281,7 +281,7 @@ public void CanUnstageBothSidesOfARename() { using (var repo = new Repository(SandboxStandardTestRepo())) { - repo.Move("branch_file.txt", "renamed_branch_file.txt"); + Commands.Move(repo, "branch_file.txt", "renamed_branch_file.txt"); Commands.Unstage(repo, new string[] { "branch_file.txt", "renamed_branch_file.txt" }); RepositoryStatus status = repo.RetrieveStatus(); diff --git a/LibGit2Sharp/Commands/Stage.cs b/LibGit2Sharp/Commands/Stage.cs index 8db58931c..f3ff647a4 100644 --- a/LibGit2Sharp/Commands/Stage.cs +++ b/LibGit2Sharp/Commands/Stage.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using System.Globalization; using System.Collections.Generic; @@ -199,6 +200,123 @@ public static void Unstage(IRepository repository, IEnumerable paths, Ex repository.Index.Replace(repository.Head.Tip, paths, explicitPathsOptions); } } + + /// + /// Moves and/or renames a file in the working directory and promotes the change to the staging area. + /// + /// The repository to act on + /// 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 static void Move(IRepository repository, string sourcePath, string destinationPath) + { + Move(repository, new[] { sourcePath }, new[] { destinationPath }); + } + + /// + /// Moves and/or renames a collection of files in the working directory and promotes the changes to the staging area. + /// + /// The repository to act on + /// 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 static void Move(IRepository repository, IEnumerable sourcePaths, IEnumerable destinationPaths) + { + Ensure.ArgumentNotNull(repository, "repository"); + Ensure.ArgumentNotNull(sourcePaths, "sourcePaths"); + Ensure.ArgumentNotNull(destinationPaths, "destinationPaths"); + + //TODO: Move() should support following use cases: + // - Moving a file under a directory ('file' and 'dir' -> 'dir/file') + // - Moving a directory (and its content) under another directory ('dir1' and 'dir2' -> 'dir2/dir1/*') + + //TODO: Move() should throw when: + // - Moving a directory under a file + + IDictionary, Tuple> batch = PrepareBatch(repository, sourcePaths, destinationPaths); + + if (batch.Count == 0) + { + throw new ArgumentNullException("sourcePaths"); + } + + foreach (KeyValuePair, Tuple> keyValuePair in batch) + { + string sourcePath = keyValuePair.Key.Item1; + string destPath = keyValuePair.Value.Item1; + + if (Directory.Exists(sourcePath) || Directory.Exists(destPath)) + { + throw new NotImplementedException(); + } + + FileStatus sourceStatus = keyValuePair.Key.Item2; + if (sourceStatus.HasAny(new Enum[] { FileStatus.Nonexistent, FileStatus.DeletedFromIndex, FileStatus.NewInWorkdir, FileStatus.DeletedFromWorkdir })) + { + throw new LibGit2SharpException("Unable to move file '{0}'. Its current status is '{1}'.", + sourcePath, + sourceStatus); + } + + FileStatus desStatus = keyValuePair.Value.Item2; + if (desStatus.HasAny(new Enum[] { FileStatus.Nonexistent, FileStatus.DeletedFromWorkdir })) + { + continue; + } + + throw new LibGit2SharpException("Unable to overwrite file '{0}'. Its current status is '{1}'.", + destPath, + desStatus); + } + + string wd = repository.Info.WorkingDirectory; + var index = repository.Index; + foreach (KeyValuePair, Tuple> keyValuePair in batch) + { + string from = keyValuePair.Key.Item1; + string to = keyValuePair.Value.Item1; + + index.Remove(from); + File.Move(Path.Combine(wd, from), Path.Combine(wd, to)); + index.Add(to); + } + + index.Write(); + } + + private static bool Enumerate(IEnumerator leftEnum, IEnumerator rightEnum) + { + bool isLeftEoF = leftEnum.MoveNext(); + bool isRightEoF = rightEnum.MoveNext(); + + if (isLeftEoF == isRightEoF) + { + return isLeftEoF; + } + + throw new ArgumentException("The collection of paths are of different lengths."); + } + + private static IDictionary, Tuple> PrepareBatch(IRepository repository, IEnumerable leftPaths, IEnumerable rightPaths) + { + IDictionary, Tuple> dic = new Dictionary, Tuple>(); + + IEnumerator leftEnum = leftPaths.GetEnumerator(); + IEnumerator rightEnum = rightPaths.GetEnumerator(); + + while (Enumerate(leftEnum, rightEnum)) + { + Tuple from = BuildFrom(repository, leftEnum.Current); + Tuple to = BuildFrom(repository, rightEnum.Current); + dic.Add(from, to); + } + + return dic; + } + + private static Tuple BuildFrom(IRepository repository, string path) + { + string relativePath = repository.BuildRelativePathFrom(path); + return new Tuple(relativePath, repository.RetrieveStatus(relativePath)); + } } } diff --git a/LibGit2Sharp/IRepository.cs b/LibGit2Sharp/IRepository.cs index ea91d3c31..4f1f3f56a 100644 --- a/LibGit2Sharp/IRepository.cs +++ b/LibGit2Sharp/IRepository.cs @@ -311,6 +311,7 @@ public interface IRepository : IDisposable /// /// 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. + [Obsolete("This method is deprecatd. Please use LibGit2Sharp.Commands.Move()")] void Move(string sourcePath, string destinationPath); /// @@ -318,6 +319,7 @@ public interface IRepository : IDisposable /// /// 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. + [Obsolete("This method is deprecatd. Please use LibGit2Sharp.Commands.Move()")] void Move(IEnumerable sourcePaths, IEnumerable destinationPaths); /// diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index b66b70ee1..03307424d 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -1644,11 +1644,6 @@ internal StringComparer PathComparer get { return pathCase.Value.Comparer; } } - internal bool PathStartsWith(string path, string value) - { - return pathCase.Value.StartsWith(path, value); - } - internal FilePath[] ToFilePaths(IEnumerable paths) { if (paths == null) @@ -1735,9 +1730,10 @@ public void Unstage(IEnumerable paths, ExplicitPathsOptions explicitPath /// /// 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. + [Obsolete("This method is deprecatd. Please use LibGit2Sharp.Commands.Move()")] public void Move(string sourcePath, string destinationPath) { - Move(new[] { sourcePath }, new[] { destinationPath }); + Commands.Move(this, sourcePath, destinationPath); } /// @@ -1745,66 +1741,10 @@ public void Move(string sourcePath, string destinationPath) /// /// 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. + [Obsolete("This method is deprecatd. Please use LibGit2Sharp.Commands.Move()")] public void Move(IEnumerable sourcePaths, IEnumerable destinationPaths) { - Ensure.ArgumentNotNull(sourcePaths, "sourcePaths"); - Ensure.ArgumentNotNull(destinationPaths, "destinationPaths"); - - //TODO: Move() should support following use cases: - // - Moving a file under a directory ('file' and 'dir' -> 'dir/file') - // - Moving a directory (and its content) under another directory ('dir1' and 'dir2' -> 'dir2/dir1/*') - - //TODO: Move() should throw when: - // - Moving a directory under a file - - IDictionary, Tuple> batch = PrepareBatch(sourcePaths, destinationPaths); - - if (batch.Count == 0) - { - throw new ArgumentNullException("sourcePaths"); - } - - foreach (KeyValuePair, Tuple> keyValuePair in batch) - { - string sourcePath = keyValuePair.Key.Item1; - string destPath = keyValuePair.Value.Item1; - - if (Directory.Exists(sourcePath) || Directory.Exists(destPath)) - { - throw new NotImplementedException(); - } - - FileStatus sourceStatus = keyValuePair.Key.Item2; - if (sourceStatus.HasAny(new Enum[] { FileStatus.Nonexistent, FileStatus.DeletedFromIndex, FileStatus.NewInWorkdir, FileStatus.DeletedFromWorkdir })) - { - throw new LibGit2SharpException("Unable to move file '{0}'. Its current status is '{1}'.", - sourcePath, - sourceStatus); - } - - FileStatus desStatus = keyValuePair.Value.Item2; - if (desStatus.HasAny(new Enum[] { FileStatus.Nonexistent, FileStatus.DeletedFromWorkdir })) - { - continue; - } - - throw new LibGit2SharpException("Unable to overwrite file '{0}'. Its current status is '{1}'.", - destPath, - desStatus); - } - - string wd = Info.WorkingDirectory; - foreach (KeyValuePair, Tuple> keyValuePair in batch) - { - string from = keyValuePair.Key.Item1; - string to = keyValuePair.Value.Item1; - - RemoveFromIndex(from); - File.Move(Path.Combine(wd, from), Path.Combine(wd, to)); - AddToIndex(to); - } - - UpdatePhysicalIndex(); + Commands.Move(this, sourcePaths, destinationPaths); } /// @@ -1912,42 +1852,6 @@ internal void UpdatePhysicalIndex() Proxy.git_index_write(Index.Handle); } - private Tuple BuildFrom(string path) - { - string relativePath = this.BuildRelativePathFrom(path); - return new Tuple(relativePath, RetrieveStatus(relativePath)); - } - - private static bool Enumerate(IEnumerator leftEnum, IEnumerator rightEnum) - { - bool isLeftEoF = leftEnum.MoveNext(); - bool isRightEoF = rightEnum.MoveNext(); - - if (isLeftEoF == isRightEoF) - { - return isLeftEoF; - } - - throw new ArgumentException("The collection of paths are of different lengths."); - } - - private IDictionary, Tuple> PrepareBatch(IEnumerable leftPaths, IEnumerable rightPaths) - { - IDictionary, Tuple> dic = new Dictionary, Tuple>(); - - IEnumerator leftEnum = leftPaths.GetEnumerator(); - IEnumerator rightEnum = rightPaths.GetEnumerator(); - - while (Enumerate(leftEnum, rightEnum)) - { - Tuple from = BuildFrom(leftEnum.Current); - Tuple to = BuildFrom(rightEnum.Current); - dic.Add(from, to); - } - - return dic; - } - /// /// Finds the most recent annotated tag that is reachable from a commit. /// diff --git a/LibGit2Sharp/RepositoryExtensions.cs b/LibGit2Sharp/RepositoryExtensions.cs index 1e90080b4..96e412334 100644 --- a/LibGit2Sharp/RepositoryExtensions.cs +++ b/LibGit2Sharp/RepositoryExtensions.cs @@ -272,7 +272,7 @@ public static Branch Checkout(this IRepository repository, Commit commit) return repository.Checkout(commit, options); } - internal static string BuildRelativePathFrom(this Repository repo, string path) + internal static string BuildRelativePathFrom(this IRepository repo, string path) { //TODO: To be removed when libgit2 natively implements this if (!Path.IsPathRooted(path)) @@ -282,7 +282,7 @@ internal static string BuildRelativePathFrom(this Repository repo, string path) string normalizedPath = Path.GetFullPath(path); - if (!repo.PathStartsWith(normalizedPath, repo.Info.WorkingDirectory)) + if (!PathStartsWith(repo, normalizedPath, repo.Info.WorkingDirectory)) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Unable to process file '{0}'. This file is not located under the working directory of the repository ('{1}').", @@ -293,6 +293,12 @@ internal static string BuildRelativePathFrom(this Repository repo, string path) return normalizedPath.Substring(repo.Info.WorkingDirectory.Length); } + internal static bool PathStartsWith(IRepository repository, string path, string value) + { + var pathCase = new PathCase(repository); + return pathCase.StartsWith(path, value); + } + private static ObjectId DereferenceToCommit(Repository repo, string identifier) { var options = LookUpOptions.DereferenceResultToCommit;