public static MergeCommandResult MergeTrees (NGit.Repository repo, RevCommit srcBase, RevCommit srcCommit, string sourceDisplayName, bool commitResult) { RevCommit newHead = null; 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()); ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger (repo)); // CherryPick command sets the working tree, but this should not be necessary, and when setting it // untracked files are deleted during the merge // merger.SetWorkingTreeIterator(new FileTreeIterator(repo)); merger.SetBase(srcBase); bool noProblems; IDictionary<string, MergeResult<NGit.Diff.Sequence>> lowLevelResults = null; IDictionary<string, ResolveMerger.MergeFailureReason> failingPaths = null; IList<string> modifiedFiles = null; ResolveMerger resolveMerger = (ResolveMerger)merger; resolveMerger.SetCommitNames(new string[] { "BASE", "HEAD", sourceDisplayName }); noProblems = merger.Merge(headCommit, srcCommit); lowLevelResults = resolveMerger.GetMergeResults(); modifiedFiles = resolveMerger.GetModifiedFiles(); failingPaths = resolveMerger.GetFailingPaths(); if (noProblems) { if (modifiedFiles != null && modifiedFiles.Count == 0) { return new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.ALREADY_UP_TO_DATE, MergeStrategy.RESOLVE, null, null); } DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache (), merger.GetResultTreeId()); dco.SetFailOnConflict(true); dco.Checkout(); if (commitResult) { newHead = new NGit.Api.Git(repo).Commit().SetMessage(srcCommit.GetFullMessage() ).SetAuthor(srcCommit.GetAuthorIdent()).Call(); return new MergeCommandResult(newHead.Id, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null); } else { return new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null); } } else { if (failingPaths != null) { return new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { headCommit.Id, srcCommit.Id }, MergeStatus.FAILED, MergeStrategy.RESOLVE, lowLevelResults , null); } else { return new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { headCommit.Id, srcCommit.Id }, MergeStatus.CONFLICTING, MergeStrategy.RESOLVE, lowLevelResults , null); } } } finally { revWalk.Release(); } }
public static MergeCommandResult CherryPick (NGit.Repository repo, RevCommit srcCommit) { RevCommit newHead = null; 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()); // get the parent of the commit to cherry-pick if (srcCommit.ParentCount != 1) { throw new MultipleParentsNotAllowedException(JGitText.Get().canOnlyCherryPickCommitsWithOneParent ); } RevCommit srcParent = srcCommit.GetParent(0); revWalk.ParseHeaders(srcParent); return MergeTrees (repo, srcParent, srcCommit, srcCommit.Name, true); } catch (IOException e) { throw new Exception ("Commit failed", e); } finally { revWalk.Release(); } }