示例#1
0
        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());
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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());
        }
示例#7
0
        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());
        }
示例#8
0
        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());
        }
示例#10
0
        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());
        }
示例#11
0
 internal PullResult(FetchResult fetchResult, string fetchedFrom, MergeCommandResult
                     mergeResult)
 {
     this.fetchResult  = fetchResult;
     this.fetchedFrom  = fetchedFrom;
     this.mergeResult  = mergeResult;
     this.rebaseResult = null;
 }
示例#12
0
 internal PullResult(FetchResult fetchResult, string fetchedFrom, RebaseResult rebaseResult
                     )
 {
     this.fetchResult  = fetchResult;
     this.fetchedFrom  = fetchedFrom;
     this.mergeResult  = null;
     this.rebaseResult = rebaseResult;
 }
示例#13
0
        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());
        }
示例#14
0
        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
                                                ());
        }
示例#15
0
 /// <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());
 }
示例#16
0
        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"))
                                            );
        }
示例#17
0
        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());
        }
示例#18
0
        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());
        }
示例#19
0
        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());
        }
示例#20
0
        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"))
                                            );
        }
示例#21
0
        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);
        }
示例#22
0
        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());
        }
示例#23
0
        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());
        }
示例#24
0
		/// <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;
		}
示例#25
0
        /// <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);
        }