public virtual void TestMultipleDeletions() { Git git = new Git(db); WriteTrashFile("a", "1\na\n3\n"); git.Add().AddFilepattern("a").Call(); RevCommit initialCommit = git.Commit().SetMessage("initial").Call(); CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "a").Delete()); git.Add().AddFilepattern("a").SetUpdate(true).Call(); RevCommit secondCommit = git.Commit().SetMessage("side").Call(); NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "a").Exists()); CheckoutBranch("refs/heads/master"); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "a").Exists()); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "a").Delete()); git.Add().AddFilepattern("a").SetUpdate(true).Call(); git.Commit().SetMessage("main").Call(); // We are merging a deletion into our branch MergeCommandResult result = git.Merge().Include(secondCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.MERGED, result.GetMergeStatus()); }
public virtual void TestSuccessfulMergeFailsDueToDirtyIndex() { Git git = new Git(db); FilePath fileA = WriteTrashFile("a", "a"); RevCommit initialCommit = AddAllAndCommit(git); // switch branch CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); // modify file a Write(fileA, "a(side)"); WriteTrashFile("b", "b"); RevCommit sideCommit = AddAllAndCommit(git); // switch branch CheckoutBranch("refs/heads/master"); WriteTrashFile("c", "c"); AddAllAndCommit(git); // modify and add file a Write(fileA, "a(modified)"); git.Add().AddFilepattern("a").Call(); // do not commit // get current index state string indexState = IndexState(CONTENT); // merge MergeCommandResult result = git.Merge().Include(sideCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); CheckMergeFailedResult(result, ResolveMerger.MergeFailureReason.DIRTY_INDEX, indexState , fileA); }
public virtual void TestDeletionOnSideConflict() { Git git = new Git(db); WriteTrashFile("a", "1\na\n3\n"); WriteTrashFile("b", "1\nb\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").Call(); RevCommit initialCommit = git.Commit().SetMessage("initial").Call(); // create side branch and delete "a" CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); git.Rm().AddFilepattern("a").Call(); RevCommit secondCommit = git.Commit().SetMessage("side").Call(); // update a on master to generate conflict CheckoutBranch("refs/heads/master"); WriteTrashFile("a", "1\na(main)\n3\n"); git.Add().AddFilepattern("a").Call(); git.Commit().SetMessage("main").Call(); // merge side with master MergeCommandResult result = git.Merge().Include(secondCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.CONFLICTING, result.GetMergeStatus()); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "a").Exists()); NUnit.Framework.Assert.AreEqual("1\na(main)\n3\n", Read(new FilePath(db.WorkTree, "a"))); NUnit.Framework.Assert.AreEqual("1\nb\n3\n", Read(new FilePath(db.WorkTree, "b")) ); NUnit.Framework.Assert.AreEqual(1, result.GetConflicts().Count); NUnit.Framework.Assert.AreEqual(3, result.GetConflicts().Get("a")[0].Length); }
public virtual void TestConflictingMergeFailsDueToDirtyWorktree() { Git git = new Git(db); FilePath fileA = WriteTrashFile("a", "a"); RevCommit initialCommit = AddAllAndCommit(git); // switch branch CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); // modify file a Write(fileA, "a(side)"); WriteTrashFile("b", "b"); RevCommit sideCommit = AddAllAndCommit(git); // switch branch CheckoutBranch("refs/heads/master"); // modify file a - this will cause a conflict during merge Write(fileA, "a(master)"); WriteTrashFile("c", "c"); AddAllAndCommit(git); // modify file a Write(fileA, "a(modified)"); // do not add and commit // get current index state string indexState = IndexState(CONTENT); // merge MergeCommandResult result = git.Merge().Include(sideCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); CheckMergeFailedResult(result, ResolveMerger.MergeFailureReason.DIRTY_WORKTREE, indexState , fileA); }
public virtual void TestMultipleCreationsSameContent() { Git git = new Git(db); WriteTrashFile("a", "1\na\n3\n"); git.Add().AddFilepattern("a").Call(); RevCommit initialCommit = git.Commit().SetMessage("initial").Call(); CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); WriteTrashFile("b", "1\nb(1)\n3\n"); git.Add().AddFilepattern("b").Call(); RevCommit secondCommit = git.Commit().SetMessage("side").Call(); CheckoutBranch("refs/heads/master"); WriteTrashFile("b", "1\nb(1)\n3\n"); git.Add().AddFilepattern("b").Call(); git.Commit().SetMessage("main").Call(); MergeCommandResult result = git.Merge().Include(secondCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.MERGED, result.GetMergeStatus()); NUnit.Framework.Assert.AreEqual("1\nb(1)\n3\n", Read(new FilePath(db.WorkTree, "b" ))); }
public virtual void TestPullMerge() { PullResult res = target.Pull().Call(); // nothing to update since we don't have different data yet NUnit.Framework.Assert.IsTrue(res.GetFetchResult().GetTrackingRefUpdates().IsEmpty ()); NUnit.Framework.Assert.IsTrue(res.GetMergeResult().GetMergeStatus().Equals(MergeStatus .ALREADY_UP_TO_DATE)); WriteToFile(sourceFile, "Source change"); source.Add().AddFilepattern("SomeFile.txt"); RevCommit sourceCommit = source.Commit().SetMessage("Source change in remote").Call (); FilePath targetFile2 = new FilePath(dbTarget.WorkTree, "OtherFile.txt"); WriteToFile(targetFile2, "Unconflicting change"); target.Add().AddFilepattern("OtherFile.txt").Call(); RevCommit targetCommit = target.Commit().SetMessage("Unconflicting change in local" ).Call(); res = target.Pull().Call(); MergeCommandResult mergeResult = res.GetMergeResult(); ObjectId[] mergedCommits = mergeResult.GetMergedCommits(); NUnit.Framework.Assert.AreEqual(targetCommit.Id, mergedCommits[0]); NUnit.Framework.Assert.AreEqual(sourceCommit.Id, mergedCommits[1]); RevCommit mergeCommit = new RevWalk(dbTarget).ParseCommit(mergeResult.GetNewHead( )); string message = "Merge branch 'master' of " + db.WorkTree; NUnit.Framework.Assert.AreEqual(message, mergeCommit.GetShortMessage()); }
public virtual void TestFastForwardWithFiles() { Git git = new Git(db); WriteTrashFile("file1", "file1"); git.Add().AddFilepattern("file1").Call(); RevCommit first = git.Commit().SetMessage("initial commit").Call(); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file1").Exists()); CreateBranch(first, "refs/heads/branch1"); WriteTrashFile("file2", "file2"); git.Add().AddFilepattern("file2").Call(); RevCommit second = git.Commit().SetMessage("second commit").Call(); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file2").Exists()); CheckoutBranch("refs/heads/branch1"); NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "file2").Exists()); MergeCommandResult result = git.Merge().Include(db.GetRef(Constants.MASTER)).Call (); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file1").Exists()); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file2").Exists()); NUnit.Framework.Assert.AreEqual(MergeStatus.FAST_FORWARD, result.GetMergeStatus() ); NUnit.Framework.Assert.AreEqual(second, result.GetNewHead()); }
public virtual void TestHardResetAfterSquashMerge() { Git g = new Git(db); WriteTrashFile("file1", "file1"); g.Add().AddFilepattern("file1").Call(); RevCommit first = g.Commit().SetMessage("initial commit").Call(); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file1").Exists()); CreateBranch(first, "refs/heads/branch1"); CheckoutBranch("refs/heads/branch1"); WriteTrashFile("file2", "file2"); g.Add().AddFilepattern("file2").Call(); g.Commit().SetMessage("second commit").Call(); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file2").Exists()); CheckoutBranch("refs/heads/master"); MergeCommandResult result = g.Merge().Include(db.GetRef("branch1")).SetSquash(true ).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.FAST_FORWARD_SQUASHED, result.GetMergeStatus ()); NUnit.Framework.Assert.IsNotNull(db.ReadSquashCommitMsg()); g.Reset().SetMode(ResetCommand.ResetType.HARD).SetRef(first.GetName()).Call(); NUnit.Framework.Assert.IsNull(db.ReadSquashCommitMsg()); }
public virtual void TestPullFastForwardWithBranchInSource() { PullResult res = target.Pull().Call(); // nothing to update since we don't have different data yet NUnit.Framework.Assert.IsTrue(res.GetFetchResult().GetTrackingRefUpdates().IsEmpty ()); NUnit.Framework.Assert.AreEqual(RebaseResult.Status.UP_TO_DATE, res.GetRebaseResult ().GetStatus()); AssertFileContentsEqual(targetFile, "Hello world"); // change the source file WriteToFile(sourceFile, "Another change\n\n\n\nFoo"); source.Add().AddFilepattern("SomeFile.txt").Call(); RevCommit initialCommit = source.Commit().SetMessage("Some change in remote").Call (); // modify the source file in a branch CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); WriteToFile(sourceFile, "Another change\n\n\n\nBoo"); source.Add().AddFilepattern("SomeFile.txt").Call(); RevCommit sideCommit = source.Commit().SetMessage("Some change in remote").Call(); // modify the source file on master CheckoutBranch("refs/heads/master"); WriteToFile(sourceFile, "More change\n\n\n\nFoo"); source.Add().AddFilepattern("SomeFile.txt").Call(); source.Commit().SetMessage("Some change in remote").Call(); // merge side into master MergeCommandResult result = source.Merge().Include(sideCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.MERGED, result.GetMergeStatus()); }
public virtual void CommitAfterSquashMerge() { Git git = new Git(db); WriteTrashFile("file1", "file1"); git.Add().AddFilepattern("file1").Call(); RevCommit first = git.Commit().SetMessage("initial commit").Call(); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file1").Exists()); CreateBranch(first, "refs/heads/branch1"); CheckoutBranch("refs/heads/branch1"); WriteTrashFile("file2", "file2"); git.Add().AddFilepattern("file2").Call(); git.Commit().SetMessage("second commit").Call(); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file2").Exists()); CheckoutBranch("refs/heads/master"); MergeCommandResult result = git.Merge().Include(db.GetRef("branch1")).SetSquash(true ).Call(); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file1").Exists()); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file2").Exists()); NUnit.Framework.Assert.AreEqual(MergeStatus.FAST_FORWARD_SQUASHED, result.GetMergeStatus ()); // comment not set, should be inferred from SQUASH_MSG RevCommit squashedCommit = git.Commit().Call(); NUnit.Framework.Assert.AreEqual(1, squashedCommit.ParentCount); NUnit.Framework.Assert.IsNull(db.ReadSquashCommitMsg()); NUnit.Framework.Assert.AreEqual("commit: Squashed commit of the following:", db.GetReflogReader (Constants.HEAD).GetLastEntry().GetComment()); NUnit.Framework.Assert.AreEqual("commit: Squashed commit of the following:", db.GetReflogReader (db.GetBranch()).GetLastEntry().GetComment()); }
internal PullResult(FetchResult fetchResult, string fetchedFrom, MergeCommandResult mergeResult) { this.fetchResult = fetchResult; this.fetchedFrom = fetchedFrom; this.mergeResult = mergeResult; this.rebaseResult = null; }
internal PullResult(FetchResult fetchResult, string fetchedFrom, RebaseResult rebaseResult ) { this.fetchResult = fetchResult; this.fetchedFrom = fetchedFrom; this.mergeResult = null; this.rebaseResult = rebaseResult; }
public virtual void TestSuccessfulContentMergeAndDirtyworkingTree() { Git git = new Git(db); WriteTrashFile("a", "1\na\n3\n"); WriteTrashFile("b", "1\nb\n3\n"); WriteTrashFile("d", "1\nd\n3\n"); WriteTrashFile("c/c/c", "1\nc\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").AddFilepattern("c/c/c").AddFilepattern ("d").Call(); RevCommit initialCommit = git.Commit().SetMessage("initial").Call(); CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); WriteTrashFile("a", "1(side)\na\n3\n"); WriteTrashFile("b", "1\nb(side)\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").Call(); RevCommit secondCommit = git.Commit().SetMessage("side").Call(); NUnit.Framework.Assert.AreEqual("1\nb(side)\n3\n", Read(new FilePath(db.WorkTree, "b"))); CheckoutBranch("refs/heads/master"); NUnit.Framework.Assert.AreEqual("1\nb\n3\n", Read(new FilePath(db.WorkTree, "b")) ); WriteTrashFile("a", "1\na\n3(main)\n"); WriteTrashFile("c/c/c", "1\nc(main)\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("c/c/c").Call(); RevCommit thirdCommit = git.Commit().SetMessage("main").Call(); WriteTrashFile("d", "--- dirty ---"); MergeCommandResult result = git.Merge().Include(secondCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.MERGED, result.GetMergeStatus()); NUnit.Framework.Assert.AreEqual("1(side)\na\n3(main)\n", Read(new FilePath(db.WorkTree , "a"))); NUnit.Framework.Assert.AreEqual("1\nb(side)\n3\n", Read(new FilePath(db.WorkTree, "b"))); NUnit.Framework.Assert.AreEqual("1\nc(main)\n3\n", Read(new FilePath(db.WorkTree, "c/c/c"))); NUnit.Framework.Assert.AreEqual("--- dirty ---", Read(new FilePath(db.WorkTree, "d" ))); NUnit.Framework.Assert.AreEqual(null, result.GetConflicts()); NUnit.Framework.Assert.IsTrue(2 == result.GetMergedCommits().Length); NUnit.Framework.Assert.AreEqual(thirdCommit, result.GetMergedCommits()[0]); NUnit.Framework.Assert.AreEqual(secondCommit, result.GetMergedCommits()[1]); Iterator <RevCommit> it = git.Log().Call().Iterator(); RevCommit newHead = it.Next(); NUnit.Framework.Assert.AreEqual(newHead, result.GetNewHead()); NUnit.Framework.Assert.AreEqual(2, newHead.ParentCount); NUnit.Framework.Assert.AreEqual(thirdCommit, newHead.GetParent(0)); NUnit.Framework.Assert.AreEqual(secondCommit, newHead.GetParent(1)); NUnit.Framework.Assert.AreEqual("Merge commit '064d54d98a4cdb0fed1802a21c656bfda67fe879'" , newHead.GetFullMessage()); NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState()); }
public virtual void TestMergeInItself() { Git git = new Git(db); git.Commit().SetMessage("initial commit").Call(); MergeCommandResult result = git.Merge().Include(db.GetRef(Constants.HEAD)).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.ALREADY_UP_TO_DATE, result.GetMergeStatus ()); }
/// <exception cref="System.Exception"></exception> private void CheckMergeFailedResult(MergeCommandResult result, ResolveMerger.MergeFailureReason reason, string indexState, FilePath fileA) { NUnit.Framework.Assert.AreEqual(MergeStatus.FAILED, result.GetMergeStatus()); NUnit.Framework.Assert.AreEqual(reason, result.GetFailingPaths().Get("a")); NUnit.Framework.Assert.AreEqual("a(modified)", Read(fileA)); NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "b").Exists()); NUnit.Framework.Assert.AreEqual("c", Read(new FilePath(db.WorkTree, "c"))); NUnit.Framework.Assert.AreEqual(indexState, IndexState(CONTENT)); NUnit.Framework.Assert.AreEqual(null, result.GetConflicts()); NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState()); }
public virtual void TestSingleDeletion() { Git git = new Git(db); WriteTrashFile("a", "1\na\n3\n"); WriteTrashFile("b", "1\nb\n3\n"); WriteTrashFile("d", "1\nd\n3\n"); WriteTrashFile("c/c/c", "1\nc\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").AddFilepattern("c/c/c").AddFilepattern ("d").Call(); RevCommit initialCommit = git.Commit().SetMessage("initial").Call(); CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "b").Delete()); git.Add().AddFilepattern("b").SetUpdate(true).Call(); RevCommit secondCommit = git.Commit().SetMessage("side").Call(); NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "b").Exists()); CheckoutBranch("refs/heads/master"); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "b").Exists()); WriteTrashFile("a", "1\na\n3(main)\n"); WriteTrashFile("c/c/c", "1\nc(main)\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("c/c/c").Call(); RevCommit thirdCommit = git.Commit().SetMessage("main").Call(); // We are merging a deletion into our branch MergeCommandResult result = git.Merge().Include(secondCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.MERGED, result.GetMergeStatus()); NUnit.Framework.Assert.AreEqual("1\na\n3(main)\n", Read(new FilePath(db.WorkTree, "a"))); NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "b").Exists()); NUnit.Framework.Assert.AreEqual("1\nc(main)\n3\n", Read(new FilePath(db.WorkTree, "c/c/c"))); NUnit.Framework.Assert.AreEqual("1\nd\n3\n", Read(new FilePath(db.WorkTree, "d")) ); // Do the opposite, be on a branch where we have deleted a file and // merge in a old commit where this file was not deleted CheckoutBranch("refs/heads/side"); NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "b").Exists()); result = git.Merge().Include(thirdCommit.Id).SetStrategy(MergeStrategy.RESOLVE).Call (); NUnit.Framework.Assert.AreEqual(MergeStatus.MERGED, result.GetMergeStatus()); NUnit.Framework.Assert.AreEqual("1\na\n3(main)\n", Read(new FilePath(db.WorkTree, "a"))); NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "b").Exists()); NUnit.Framework.Assert.AreEqual("1\nc(main)\n3\n", Read(new FilePath(db.WorkTree, "c/c/c"))); NUnit.Framework.Assert.AreEqual("1\nd\n3\n", Read(new FilePath(db.WorkTree, "d")) ); }
public virtual void TestAlreadyUpToDate() { Git git = new Git(db); RevCommit first = git.Commit().SetMessage("initial commit").Call(); CreateBranch(first, "refs/heads/branch1"); RevCommit second = git.Commit().SetMessage("second commit").Call(); MergeCommandResult result = git.Merge().Include(db.GetRef("refs/heads/branch1")). Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.ALREADY_UP_TO_DATE, result.GetMergeStatus ()); NUnit.Framework.Assert.AreEqual(second, result.GetNewHead()); }
public virtual void TestFastForward() { Git git = new Git(db); RevCommit first = git.Commit().SetMessage("initial commit").Call(); CreateBranch(first, "refs/heads/branch1"); RevCommit second = git.Commit().SetMessage("second commit").Call(); CheckoutBranch("refs/heads/branch1"); MergeCommandResult result = git.Merge().Include(db.GetRef(Constants.MASTER)).Call (); NUnit.Framework.Assert.AreEqual(MergeStatus.FAST_FORWARD, result.GetMergeStatus() ); NUnit.Framework.Assert.AreEqual(second, result.GetNewHead()); }
public virtual void TestMergeNonVersionedPaths() { Git git = new Git(db); WriteTrashFile("a", "1\na\n3\n"); WriteTrashFile("b", "1\nb\n3\n"); WriteTrashFile("c/c/c", "1\nc\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").AddFilepattern("c/c/c").Call(); RevCommit initialCommit = git.Commit().SetMessage("initial").Call(); CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); WriteTrashFile("a", "1\na(side)\n3\n"); WriteTrashFile("b", "1\nb(side)\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").Call(); RevCommit secondCommit = git.Commit().SetMessage("side").Call(); NUnit.Framework.Assert.AreEqual("1\nb(side)\n3\n", Read(new FilePath(db.WorkTree, "b"))); CheckoutBranch("refs/heads/master"); NUnit.Framework.Assert.AreEqual("1\nb\n3\n", Read(new FilePath(db.WorkTree, "b")) ); WriteTrashFile("a", "1\na(main)\n3\n"); WriteTrashFile("c/c/c", "1\nc(main)\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("c/c/c").Call(); git.Commit().SetMessage("main").Call(); WriteTrashFile("d", "1\nd\n3\n"); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "e").Mkdir()); MergeCommandResult result = git.Merge().Include(secondCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.CONFLICTING, result.GetMergeStatus()); NUnit.Framework.Assert.AreEqual("1\n<<<<<<< HEAD\na(main)\n=======\na(side)\n>>>>>>> 86503e7e397465588cc267b65d778538bffccb83\n3\n" , Read(new FilePath(db.WorkTree, "a"))); NUnit.Framework.Assert.AreEqual("1\nb(side)\n3\n", Read(new FilePath(db.WorkTree, "b"))); NUnit.Framework.Assert.AreEqual("1\nc(main)\n3\n", Read(new FilePath(db.WorkTree, "c/c/c"))); NUnit.Framework.Assert.AreEqual("1\nd\n3\n", Read(new FilePath(db.WorkTree, "d")) ); FilePath dir = new FilePath(db.WorkTree, "e"); NUnit.Framework.Assert.IsTrue(dir.IsDirectory()); NUnit.Framework.Assert.AreEqual(1, result.GetConflicts().Count); NUnit.Framework.Assert.AreEqual(3, result.GetConflicts().Get("a")[0].Length); NUnit.Framework.Assert.AreEqual(RepositoryState.MERGING, db.GetRepositoryState()); }
public virtual void TestDeletionAndConflict() { Git git = new Git(db); WriteTrashFile("a", "1\na\n3\n"); WriteTrashFile("b", "1\nb\n3\n"); WriteTrashFile("d", "1\nd\n3\n"); WriteTrashFile("c/c/c", "1\nc\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").AddFilepattern("c/c/c").AddFilepattern ("d").Call(); RevCommit initialCommit = git.Commit().SetMessage("initial").Call(); CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "b").Delete()); WriteTrashFile("a", "1\na\n3(side)\n"); git.Add().AddFilepattern("b").SetUpdate(true).Call(); git.Add().AddFilepattern("a").SetUpdate(true).Call(); RevCommit secondCommit = git.Commit().SetMessage("side").Call(); NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "b").Exists()); CheckoutBranch("refs/heads/master"); NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "b").Exists()); WriteTrashFile("a", "1\na\n3(main)\n"); WriteTrashFile("c/c/c", "1\nc(main)\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("c/c/c").Call(); git.Commit().SetMessage("main").Call(); // We are merging a deletion into our branch MergeCommandResult result = git.Merge().Include(secondCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.CONFLICTING, result.GetMergeStatus()); NUnit.Framework.Assert.AreEqual("1\na\n<<<<<<< HEAD\n3(main)\n=======\n3(side)\n>>>>>>> 54ffed45d62d252715fc20e41da92d44c48fb0ff\n" , Read(new FilePath(db.WorkTree, "a"))); NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "b").Exists()); NUnit.Framework.Assert.AreEqual("1\nc(main)\n3\n", Read(new FilePath(db.WorkTree, "c/c/c"))); NUnit.Framework.Assert.AreEqual("1\nd\n3\n", Read(new FilePath(db.WorkTree, "d")) ); }
public virtual void TestModifiedAndRenamed() { // this test is essentially the same as testDeletionOnSideConflict, // however if once rename support is added this test should result in a // successful merge instead of a conflict Git git = new Git(db); WriteTrashFile("x", "add x"); git.Add().AddFilepattern("x").Call(); RevCommit initial = git.Commit().SetMessage("add x").Call(); CreateBranch(initial, "refs/heads/d1"); CreateBranch(initial, "refs/heads/d2"); // rename x to y on d1 CheckoutBranch("refs/heads/d1"); new FilePath(db.WorkTree, "x").RenameTo(new FilePath(db.WorkTree, "y")); git.Rm().AddFilepattern("x").Call(); git.Add().AddFilepattern("y").Call(); RevCommit d1Commit = git.Commit().SetMessage("d1 rename x -> y").Call(); CheckoutBranch("refs/heads/d2"); WriteTrashFile("x", "d2 change"); git.Add().AddFilepattern("x").Call(); RevCommit d2Commit = git.Commit().SetMessage("d2 change in x").Call(); CheckoutBranch("refs/heads/master"); MergeCommandResult d1Merge = git.Merge().Include(d1Commit).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.FAST_FORWARD, d1Merge.GetMergeStatus( )); MergeCommandResult d2Merge = git.Merge().Include(d2Commit).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.CONFLICTING, d2Merge.GetMergeStatus() ); NUnit.Framework.Assert.AreEqual(1, d2Merge.GetConflicts().Count); NUnit.Framework.Assert.AreEqual(3, d2Merge.GetConflicts().Get("x")[0].Length); }
public virtual void TestMergeFailingWithDirtyWorkingTree() { Git git = new Git(db); WriteTrashFile("a", "1\na\n3\n"); WriteTrashFile("b", "1\nb\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").Call(); RevCommit initialCommit = git.Commit().SetMessage("initial").Call(); CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); WriteTrashFile("a", "1(side)\na\n3\n"); WriteTrashFile("b", "1\nb(side)\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").Call(); RevCommit secondCommit = git.Commit().SetMessage("side").Call(); NUnit.Framework.Assert.AreEqual("1\nb(side)\n3\n", Read(new FilePath(db.WorkTree, "b"))); CheckoutBranch("refs/heads/master"); NUnit.Framework.Assert.AreEqual("1\nb\n3\n", Read(new FilePath(db.WorkTree, "b")) ); WriteTrashFile("a", "1\na\n3(main)\n"); git.Add().AddFilepattern("a").Call(); git.Commit().SetMessage("main").Call(); WriteTrashFile("a", "--- dirty ---"); MergeCommandResult result = git.Merge().Include(secondCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.FAILED, result.GetMergeStatus()); NUnit.Framework.Assert.AreEqual("--- dirty ---", Read(new FilePath(db.WorkTree, "a" ))); NUnit.Framework.Assert.AreEqual("1\nb\n3\n", Read(new FilePath(db.WorkTree, "b")) ); NUnit.Framework.Assert.AreEqual(null, result.GetConflicts()); NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState()); }
public virtual void TestMergeConflictFileFolder() { Git git = new Git(db); WriteTrashFile("a", "1\na\n3\n"); WriteTrashFile("b", "1\nb\n3\n"); git.Add().AddFilepattern("a").AddFilepattern("b").Call(); RevCommit initialCommit = git.Commit().SetMessage("initial").Call(); CreateBranch(initialCommit, "refs/heads/side"); CheckoutBranch("refs/heads/side"); WriteTrashFile("c/c/c", "1\nc(side)\n3\n"); WriteTrashFile("d", "1\nd(side)\n3\n"); git.Add().AddFilepattern("c/c/c").AddFilepattern("d").Call(); RevCommit secondCommit = git.Commit().SetMessage("side").Call(); CheckoutBranch("refs/heads/master"); WriteTrashFile("c", "1\nc(main)\n3\n"); WriteTrashFile("d/d/d", "1\nd(main)\n3\n"); git.Add().AddFilepattern("c").AddFilepattern("d/d/d").Call(); git.Commit().SetMessage("main").Call(); MergeCommandResult result = git.Merge().Include(secondCommit.Id).SetStrategy(MergeStrategy .RESOLVE).Call(); NUnit.Framework.Assert.AreEqual(MergeStatus.CONFLICTING, result.GetMergeStatus()); NUnit.Framework.Assert.AreEqual("1\na\n3\n", Read(new FilePath(db.WorkTree, "a")) ); NUnit.Framework.Assert.AreEqual("1\nb\n3\n", Read(new FilePath(db.WorkTree, "b")) ); NUnit.Framework.Assert.AreEqual("1\nc(main)\n3\n", Read(new FilePath(db.WorkTree, "c"))); NUnit.Framework.Assert.AreEqual("1\nd(main)\n3\n", Read(new FilePath(db.WorkTree, "d/d/d"))); NUnit.Framework.Assert.AreEqual(null, result.GetConflicts()); NUnit.Framework.Assert.AreEqual(RepositoryState.MERGING, db.GetRepositoryState()); }
/// <summary> /// Executes the /// <code>Pull</code> /// command with all the options and parameters /// collected by the setter methods (e.g. /// <see cref="SetProgressMonitor(NGit.ProgressMonitor)">SetProgressMonitor(NGit.ProgressMonitor) /// </see> /// ) of this class. Each /// instance of this class should only be used for one invocation of the /// command. Don't call this method twice on an instance. /// </summary> /// <returns>the result of the pull</returns> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException /// </exception> /// <exception cref="NGit.Api.Errors.InvalidConfigurationException">NGit.Api.Errors.InvalidConfigurationException /// </exception> /// <exception cref="NGit.Api.Errors.DetachedHeadException">NGit.Api.Errors.DetachedHeadException /// </exception> /// <exception cref="NGit.Api.Errors.InvalidRemoteException">NGit.Api.Errors.InvalidRemoteException /// </exception> /// <exception cref="NGit.Api.Errors.CanceledException">NGit.Api.Errors.CanceledException /// </exception> /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException /// </exception> /// <exception cref="NGit.Api.Errors.NoHeadException">NGit.Api.Errors.NoHeadException /// </exception> /// <exception cref="NGit.Api.Errors.TransportException">NGit.Api.Errors.TransportException /// </exception> /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> public override PullResult Call() { CheckCallable(); monitor.BeginTask(JGitText.Get().pullTaskName, 2); string branchName; try { string fullBranch = repo.GetFullBranch(); if (fullBranch == null) { throw new NoHeadException(JGitText.Get().pullOnRepoWithoutHEADCurrentlyNotSupported ); } if (!fullBranch.StartsWith(Constants.R_HEADS)) { // we can not pull if HEAD is detached and branch is not // specified explicitly throw new DetachedHeadException(); } branchName = Sharpen.Runtime.Substring(fullBranch, Constants.R_HEADS.Length); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPullCommand , e); } if (!repo.GetRepositoryState().Equals(RepositoryState.SAFE)) { throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().cannotPullOnARepoWithState , repo.GetRepositoryState().Name())); } // get the configured remote for the currently checked out branch // stored in configuration key branch.<branch name>.remote Config repoConfig = repo.GetConfig(); string remote = repoConfig.GetString(ConfigConstants.CONFIG_BRANCH_SECTION, branchName , ConfigConstants.CONFIG_KEY_REMOTE); if (remote == null) { // fall back to default remote remote = Constants.DEFAULT_REMOTE_NAME; } // get the name of the branch in the remote repository // stored in configuration key branch.<branch name>.merge string remoteBranchName = repoConfig.GetString(ConfigConstants.CONFIG_BRANCH_SECTION , branchName, ConfigConstants.CONFIG_KEY_MERGE); // check if the branch is configured for pull-rebase bool doRebase = repoConfig.GetBoolean(ConfigConstants.CONFIG_BRANCH_SECTION, branchName , ConfigConstants.CONFIG_KEY_REBASE, false); if (remoteBranchName == null) { string missingKey = ConfigConstants.CONFIG_BRANCH_SECTION + DOT + branchName + DOT + ConfigConstants.CONFIG_KEY_MERGE; throw new InvalidConfigurationException(MessageFormat.Format(JGitText.Get().missingConfigurationForKey , missingKey)); } bool isRemote = !remote.Equals("."); string remoteUri; FetchResult fetchRes; if (isRemote) { remoteUri = repoConfig.GetString(ConfigConstants.CONFIG_REMOTE_SECTION, remote, ConfigConstants .CONFIG_KEY_URL); if (remoteUri == null) { string missingKey = ConfigConstants.CONFIG_REMOTE_SECTION + DOT + remote + DOT + ConfigConstants.CONFIG_KEY_URL; throw new InvalidConfigurationException(MessageFormat.Format(JGitText.Get().missingConfigurationForKey , missingKey)); } if (monitor.IsCancelled()) { throw new CanceledException(MessageFormat.Format(JGitText.Get().operationCanceled , JGitText.Get().pullTaskName)); } FetchCommand fetch = new FetchCommand(repo); fetch.SetRemote(remote); fetch.SetProgressMonitor(monitor); Configure(fetch); fetchRes = fetch.Call(); } else { // we can skip the fetch altogether remoteUri = "local repository"; fetchRes = null; } monitor.Update(1); if (monitor.IsCancelled()) { throw new CanceledException(MessageFormat.Format(JGitText.Get().operationCanceled , JGitText.Get().pullTaskName)); } // we check the updates to see which of the updated branches // corresponds // to the remote branch name AnyObjectId commitToMerge; if (isRemote) { Ref r = null; if (fetchRes != null) { r = fetchRes.GetAdvertisedRef(remoteBranchName); if (r == null) { r = fetchRes.GetAdvertisedRef(Constants.R_HEADS + remoteBranchName); } } if (r == null) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().couldNotGetAdvertisedRef , remoteBranchName)); } else { commitToMerge = r.GetObjectId(); } } else { try { commitToMerge = repo.Resolve(remoteBranchName); if (commitToMerge == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , remoteBranchName)); } } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPullCommand , e); } } string upstreamName = "branch \'" + Repository.ShortenRefName(remoteBranchName) + "\' of " + remoteUri; PullResult result; if (doRebase) { RebaseCommand rebase = new RebaseCommand(repo); RebaseResult rebaseRes = rebase.SetUpstream(commitToMerge).SetUpstreamName(upstreamName ).SetProgressMonitor(monitor).SetOperation(RebaseCommand.Operation.BEGIN).Call(); result = new PullResult(fetchRes, remote, rebaseRes); } else { MergeCommand merge = new MergeCommand(repo); merge.Include(upstreamName, commitToMerge); MergeCommandResult mergeRes = merge.Call(); monitor.Update(1); result = new PullResult(fetchRes, remote, mergeRes); } monitor.EndTask(); return result; }
/// <summary> /// Executes the /// <code>revert</code> /// command with all the options and parameters /// collected by the setter methods (e.g. /// <see cref="Include(NGit.Ref)">Include(NGit.Ref)</see> /// of this /// class. Each instance of this class should only be used for one invocation /// of the command. Don't call this method twice on an instance. /// </summary> /// <returns> /// on success the /// <see cref="NGit.Revwalk.RevCommit">NGit.Revwalk.RevCommit</see> /// pointed to by the new HEAD is /// returned. If a failure occurred during revert <code>null</code> /// is returned. The list of successfully reverted /// <see cref="NGit.Ref">NGit.Ref</see> /// 's can /// be obtained by calling /// <see cref="GetRevertedRefs()">GetRevertedRefs()</see> /// </returns> /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException /// </exception> /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException">NGit.Api.Errors.ConcurrentRefUpdateException /// </exception> /// <exception cref="NGit.Api.Errors.UnmergedPathsException">NGit.Api.Errors.UnmergedPathsException /// </exception> /// <exception cref="NGit.Api.Errors.NoMessageException">NGit.Api.Errors.NoMessageException /// </exception> public override RevCommit Call() { RevCommit newHead = null; CheckCallable(); RevWalk revWalk = new RevWalk(repo); try { // get the head commit Ref headRef = repo.GetRef(Constants.HEAD); if (headRef == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId()); newHead = headCommit; // loop through all refs to be reverted foreach (Ref src in commits) { // get the commit to be reverted // handle annotated tags ObjectId srcObjectId = src.GetPeeledObjectId(); if (srcObjectId == null) { srcObjectId = src.GetObjectId(); } RevCommit srcCommit = revWalk.ParseCommit(srcObjectId); // get the parent of the commit to revert if (srcCommit.ParentCount != 1) { throw new MultipleParentsNotAllowedException(JGitText.Get().canOnlyRevertCommitsWithOneParent ); } RevCommit srcParent = srcCommit.GetParent(0); revWalk.ParseHeaders(srcParent); ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger (repo)); merger.SetWorkingTreeIterator(new FileTreeIterator(repo)); merger.SetBase(srcCommit.Tree); if (merger.Merge(headCommit, srcParent)) { if (AnyObjectId.Equals(headCommit.Tree.Id, merger.GetResultTreeId())) { continue; } DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache (), merger.GetResultTreeId()); dco.SetFailOnConflict(true); dco.Checkout(); string shortMessage = "Revert \"" + srcCommit.GetShortMessage() + "\""; string newMessage = shortMessage + "\n\n" + "This reverts commit " + srcCommit.Id .GetName() + ".\n"; newHead = new Git(GetRepository()).Commit().SetMessage(newMessage).SetReflogComment ("revert: " + shortMessage).Call(); revertedRefs.AddItem(src); } else { unmergedPaths = merger.GetUnmergedPaths(); IDictionary <string, ResolveMerger.MergeFailureReason> failingPaths = merger.GetFailingPaths (); if (failingPaths != null) { failingResult = new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId [] { headCommit.Id, srcParent.Id }, MergeStatus.FAILED, MergeStrategy.RESOLVE, merger .GetMergeResults(), failingPaths, null); } return(null); } } } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionCaughtDuringExecutionOfRevertCommand , e), e); } finally { revWalk.Release(); } return(newHead); }