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 void HardReset (NGit.Repository repo, ObjectId newHead) { DirCache dc = null; try { // Reset head to upstream RefUpdate ru = repo.UpdateRef (Constants.HEAD); ru.SetNewObjectId (newHead); ru.SetForceUpdate (true); RefUpdate.Result rc = ru.Update (); switch (rc) { case RefUpdate.Result.NO_CHANGE: case RefUpdate.Result.NEW: case RefUpdate.Result.FAST_FORWARD: case RefUpdate.Result.FORCED: break; case RefUpdate.Result.REJECTED: case RefUpdate.Result.LOCK_FAILURE: throw new ConcurrentRefUpdateException (JGitText.Get ().couldNotLockHEAD, ru.GetRef (), rc); default: throw new JGitInternalException ("Reference update failed: " + rc); } dc = repo.LockDirCache (); RevWalk rw = new RevWalk (repo); RevCommit c = rw.ParseCommit (newHead); DirCacheCheckout checkout = new DirCacheCheckout (repo, null, dc, c.Tree); checkout.Checkout (); } catch { if (dc != null) dc.Unlock (); throw; } }