diff options
Diffstat (limited to 'LibGit2Sharp.Tests')
-rw-r--r-- | LibGit2Sharp.Tests/CherryPickFixture.cs | 141 | ||||
-rw-r--r-- | LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj | 1 |
2 files changed, 142 insertions, 0 deletions
diff --git a/LibGit2Sharp.Tests/CherryPickFixture.cs b/LibGit2Sharp.Tests/CherryPickFixture.cs new file mode 100644 index 00000000..8ce6b04a --- /dev/null +++ b/LibGit2Sharp.Tests/CherryPickFixture.cs @@ -0,0 +1,141 @@ +using System.IO; +using System.Linq; +using LibGit2Sharp.Tests.TestHelpers; +using Xunit; +using Xunit.Extensions; +using System; + +namespace LibGit2Sharp.Tests +{ + public class CherryPickFixture : BaseFixture + { + [Theory] + [InlineData(true)] + [InlineData(false)] + public void CanCherryPick(bool fromDetachedHead) + { + string path = CloneMergeTestRepo(); + using (var repo = new Repository(path)) + { + if (fromDetachedHead) + { + repo.Checkout(repo.Head.Tip.Id.Sha); + } + + Commit commitToMerge = repo.Branches["fast_forward"].Tip; + + CherryPickResult result = repo.CherryPick(commitToMerge, Constants.Signature); + + Assert.Equal(CherryPickStatus.CherryPicked, result.Status); + Assert.Equal(cherryPickedCommitId, result.Commit.Id.Sha); + Assert.False(repo.Index.RetrieveStatus().Any()); + Assert.Equal(fromDetachedHead, repo.Info.IsHeadDetached); + Assert.Equal(commitToMerge.Author, result.Commit.Author); + Assert.Equal(Constants.Signature, result.Commit.Committer); + } + } + + [Fact] + public void CherryPickWithConflictDoesNotCommit() + { + const string firstBranchFileName = "first branch file.txt"; + const string secondBranchFileName = "second branch file.txt"; + const string sharedBranchFileName = "first+second branch file.txt"; + + string path = CloneStandardTestRepo(); + using (var repo = new Repository(path)) + { + var firstBranch = repo.CreateBranch("FirstBranch"); + firstBranch.Checkout(); + + // Commit with ONE new file to both first & second branch (SecondBranch is created on this commit). + AddFileCommitToRepo(repo, sharedBranchFileName); + + var secondBranch = repo.CreateBranch("SecondBranch"); + // Commit with ONE new file to first branch (FirstBranch moves forward as it is checked out, SecondBranch stays back one). + AddFileCommitToRepo(repo, firstBranchFileName); + AddFileCommitToRepo(repo, sharedBranchFileName, "The first branches comment"); // Change file in first branch + + secondBranch.Checkout(); + // Commit with ONE new file to second branch (FirstBranch and SecondBranch now point to separate commits that both have the same parent commit). + AddFileCommitToRepo(repo, secondBranchFileName); + AddFileCommitToRepo(repo, sharedBranchFileName, "The second branches comment"); // Change file in second branch + + CherryPickResult cherryPickResult = repo.CherryPick(repo.Branches["FirstBranch"].Tip, Constants.Signature); + + Assert.Equal(CherryPickStatus.Conflicts, cherryPickResult.Status); + + Assert.Null(cherryPickResult.Commit); + Assert.Equal(1, repo.Index.Conflicts.Count()); + + var conflict = repo.Index.Conflicts.First(); + var changes = repo.Diff.Compare(repo.Lookup<Blob>(conflict.Theirs.Id), repo.Lookup<Blob>(conflict.Ours.Id)); + + Assert.False(changes.IsBinaryComparison); + } + } + + [Theory] + [InlineData(CheckoutFileConflictStrategy.Ours)] + [InlineData(CheckoutFileConflictStrategy.Theirs)] + public void CanSpecifyConflictFileStrategy(CheckoutFileConflictStrategy conflictStrategy) + { + const string conflictFile = "a.txt"; + const string conflictBranchName = "conflicts"; + + string path = CloneMergeTestRepo(); + using (var repo = new Repository(path)) + { + Branch branch = repo.Branches[conflictBranchName]; + Assert.NotNull(branch); + + CherryPickOptions cherryPickOptions = new CherryPickOptions() + { + FileConflictStrategy = conflictStrategy, + }; + + CherryPickResult result = repo.CherryPick(branch.Tip, Constants.Signature, cherryPickOptions); + Assert.Equal(CherryPickStatus.Conflicts, result.Status); + + // Get the information on the conflict. + Conflict conflict = repo.Index.Conflicts[conflictFile]; + + Assert.NotNull(conflict); + Assert.NotNull(conflict.Theirs); + Assert.NotNull(conflict.Ours); + + // Get the blob containing the expected content. + Blob expectedBlob = null; + switch (conflictStrategy) + { + case CheckoutFileConflictStrategy.Theirs: + expectedBlob = repo.Lookup<Blob>(conflict.Theirs.Id); + break; + case CheckoutFileConflictStrategy.Ours: + expectedBlob = repo.Lookup<Blob>(conflict.Ours.Id); + break; + default: + throw new Exception("Unexpected FileConflictStrategy"); + } + + Assert.NotNull(expectedBlob); + + // Check the content of the file on disk matches what is expected. + string expectedContent = expectedBlob.GetContentText(new FilteringOptions(conflictFile)); + Assert.Equal(expectedContent, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, conflictFile))); + } + } + + private Commit AddFileCommitToRepo(IRepository repository, string filename, string content = null) + { + Touch(repository.Info.WorkingDirectory, filename, content); + + repository.Index.Stage(filename); + + return repository.Commit("New commit", Constants.Signature, Constants.Signature); + } + + // Commit IDs of the checked in merge_testrepo + private const string cherryPickedCommitId = "74b37f366b6e1c682c1c9fe0c6b006cbe909cf91"; + } +} diff --git a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj index b07fcec4..6a1fd403 100644 --- a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj +++ b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj @@ -62,6 +62,7 @@ <Compile Include="BlameFixture.cs" /> <Compile Include="ArchiveTarFixture.cs" /> <Compile Include="CheckoutFixture.cs" /> + <Compile Include="CherryPickFixture.cs" /> <Compile Include="GlobalSettingsFixture.cs" /> <Compile Include="PatchStatsFixture.cs" /> <Compile Include="RefSpecFixture.cs" /> |