public virtual void TestCherryPickOverExecutableChangeOnNonExectuableFileSystem() { Git git = new Git(db); FilePath file = WriteTrashFile("test.txt", "a"); NUnit.Framework.Assert.IsNotNull(git.Add().AddFilepattern("test.txt").Call()); NUnit.Framework.Assert.IsNotNull(git.Commit().SetMessage("commit1").Call()); NUnit.Framework.Assert.IsNotNull(git.Checkout().SetCreateBranch(true).SetName("a" ).Call()); WriteTrashFile("test.txt", "b"); NUnit.Framework.Assert.IsNotNull(git.Add().AddFilepattern("test.txt").Call()); RevCommit commit2 = git.Commit().SetMessage("commit2").Call(); NUnit.Framework.Assert.IsNotNull(commit2); NUnit.Framework.Assert.IsNotNull(git.Checkout().SetName(Constants.MASTER).Call()); DirCache cache = db.LockDirCache(); cache.GetEntry("test.txt").FileMode = FileMode.EXECUTABLE_FILE; cache.Write(); NUnit.Framework.Assert.IsTrue(cache.Commit()); cache.Unlock(); NUnit.Framework.Assert.IsNotNull(git.Commit().SetMessage("commit3").Call()); git.GetRepository().GetConfig().SetBoolean(ConfigConstants.CONFIG_CORE_SECTION, null , ConfigConstants.CONFIG_KEY_FILEMODE, false); CherryPickResult result = git.CherryPick().Include(commit2).Call(); NUnit.Framework.Assert.IsNotNull(result); NUnit.Framework.Assert.AreEqual(CherryPickResult.CherryPickStatus.OK, result.GetStatus ()); }
private void ResetIndexForPaths(RevCommit commit) { DirCache dc = null; DirCacheEditor edit; try { dc = repo.LockDirCache(); edit = dc.Editor(); TreeWalk tw = new TreeWalk(repo); tw.AddTree(new DirCacheIterator(dc)); tw.AddTree(commit.Tree); tw.Filter = PathFilterGroup.CreateFromStrings(filepaths); tw.Recursive = true; while (tw.Next()) { string path = tw.PathString; // DirCacheIterator dci = tw.getTree(0, DirCacheIterator.class); CanonicalTreeParser tree = tw.GetTree <CanonicalTreeParser>(1); if (tree == null) { // file is not in the commit, remove from index edit.Add(new DirCacheEditor.DeletePath(path)); } else { // revert index to commit // it seams that there is concurrent access to tree // variable, therefore we need to keep references to // entryFileMode and entryObjectId in local // variables FileMode entryFileMode = tree.EntryFileMode; ObjectId entryObjectId = tree.EntryObjectId; edit.Add(new _PathEdit_305(entryFileMode, entryObjectId, path)); } } edit.Commit(); } catch (IOException e) { throw new RuntimeException(e); } finally { if (dc != null) { dc.Unlock(); } } }
/// <exception cref="System.InvalidOperationException"></exception> /// <exception cref="System.IO.IOException"></exception> public override void PrescanTwoTrees(Tree head, Tree merge) { DirCache dc = db.LockDirCache(); try { dco = new DirCacheCheckout(db, head.GetId(), dc, merge.GetId()); dco.PreScanTwoTrees(); } finally { dc.Unlock(); } }
/// <exception cref="System.IO.IOException"></exception> private void Checkout() { DirCache dc = db.LockDirCache(); try { dco = new DirCacheCheckout(db, theHead, dc, theMerge); dco.Checkout(); } finally { dc.Unlock(); } }
/// <exception cref="System.IO.IOException"></exception> public override void Checkout() { DirCache dc = db.LockDirCache(); try { dco = new DirCacheCheckout(db, theHead.GetId(), dc, theMerge.GetId()); dco.Checkout(); } finally { dc.Unlock(); } }
/// <exception cref="System.InvalidOperationException"></exception> /// <exception cref="System.IO.IOException"></exception> private void PrescanTwoTrees(ObjectId head, ObjectId merge) { DirCache dc = db.LockDirCache(); try { dco = new DirCacheCheckout(db, head, dc, merge); dco.PreScanTwoTrees(); } finally { dc.Unlock(); } }
/// <summary>Checkout paths into index and working directory</summary> /// <returns>this instance</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException /// </exception> protected internal virtual NGit.Api.CheckoutCommand CheckoutPaths() { RevWalk revWalk = new RevWalk(repo); DirCache dc = repo.LockDirCache(); try { DirCacheEditor editor = dc.Editor(); TreeWalk startWalk = new TreeWalk(revWalk.GetObjectReader()); startWalk.Recursive = true; if (!checkoutAllPaths) { startWalk.Filter = PathFilterGroup.CreateFromStrings(paths); } bool checkoutIndex = startCommit == null && startPoint == null; if (!checkoutIndex) { startWalk.AddTree(revWalk.ParseCommit(GetStartPoint()).Tree); } else { startWalk.AddTree(new DirCacheIterator(dc)); } FilePath workTree = repo.WorkTree; ObjectReader r = repo.ObjectDatabase.NewReader(); try { while (startWalk.Next()) { ObjectId blobId = startWalk.GetObjectId(0); FileMode mode = startWalk.GetFileMode(0); editor.Add(new _PathEdit_349(this, checkoutIndex, blobId, mode, workTree, r, startWalk .PathString)); } editor.Commit(); } finally { startWalk.Release(); r.Release(); } } finally { dc.Unlock(); revWalk.Release(); } return(this); }
/// <summary>Checkout paths into index and working directory</summary> /// <returns>this instance</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException /// </exception> protected internal virtual NGit.Api.CheckoutCommand CheckoutPaths() { RevWalk revWalk = new RevWalk(repo); DirCache dc = repo.LockDirCache(); try { TreeWalk treeWalk = new TreeWalk(revWalk.GetObjectReader()); treeWalk.Recursive = true; treeWalk.AddTree(new DirCacheIterator(dc)); treeWalk.Filter = PathFilterGroup.CreateFromStrings(paths); IList <string> files = new List <string>(); while (treeWalk.Next()) { files.AddItem(treeWalk.PathString); } if (startCommit != null || startPoint != null) { DirCacheEditor editor = dc.Editor(); TreeWalk startWalk = new TreeWalk(revWalk.GetObjectReader()); startWalk.Recursive = true; startWalk.Filter = treeWalk.Filter; startWalk.AddTree(revWalk.ParseCommit(GetStartPoint()).Tree); while (startWalk.Next()) { ObjectId blobId = startWalk.GetObjectId(0); editor.Add(new _PathEdit_258(blobId, startWalk.PathString)); } editor.Commit(); } FilePath workTree = repo.WorkTree; foreach (string file in files) { DirCacheCheckout.CheckoutEntry(repo, new FilePath(workTree, file), dc.GetEntry(file )); } } finally { dc.Unlock(); revWalk.Release(); } return(this); }
/// <exception cref="System.IO.IOException"></exception> private void ResetIndex(RevCommit commit) { DirCache dc = repo.LockDirCache(); TreeWalk walk = null; try { DirCacheEditor editor = dc.Editor(); walk = new TreeWalk(repo); walk.AddTree(commit.Tree); walk.AddTree(new DirCacheIterator(dc)); walk.Recursive = true; while (walk.Next()) { AbstractTreeIterator cIter = walk.GetTree <AbstractTreeIterator>(0); if (cIter == null) { editor.Add(new DirCacheEditor.DeletePath(walk.PathString)); continue; } DirCacheEntry entry = new DirCacheEntry(walk.RawPath); entry.FileMode = cIter.EntryFileMode; entry.SetObjectIdFromRaw(cIter.IdBuffer, cIter.IdOffset); DirCacheIterator dcIter = walk.GetTree <DirCacheIterator>(1); if (dcIter != null && dcIter.IdEqual(cIter)) { DirCacheEntry indexEntry = dcIter.GetDirCacheEntry(); entry.LastModified = indexEntry.LastModified; entry.SetLength(indexEntry.Length); } editor.Add(new _PathEdit_356(entry, entry)); } editor.Commit(); } finally { dc.Unlock(); if (walk != null) { walk.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; } }
private void ResetIndexForPaths(RevCommit commit) { DirCache dc = null; DirCacheEditor edit; try { dc = repo.LockDirCache(); edit = dc.Editor(); TreeWalk tw = new TreeWalk(repo); tw.AddTree(new DirCacheIterator(dc)); tw.AddTree(commit.Tree); tw.Filter = PathFilterGroup.CreateFromStrings(filepaths); while (tw.Next()) { string path = tw.PathString; // DirCacheIterator dci = tw.getTree(0, DirCacheIterator.class); CanonicalTreeParser tree = tw.GetTree <CanonicalTreeParser>(1); if (tree == null) { // file is not in the commit, remove from index edit.Add(new DirCacheEditor.DeletePath(path)); } else { // revert index to commit edit.Add(new _PathEdit_281(tree, path)); } } edit.Commit(); } catch (IOException e) { throw new RuntimeException(e); } finally { if (dc != null) { dc.Unlock(); } } }
private void ResetIndexForPaths(RevCommit commit) { DirCache dc = null; try { dc = repo.LockDirCache(); DirCacheBuilder builder = dc.Builder(); TreeWalk tw = new TreeWalk(repo); tw.AddTree(new DirCacheBuildIterator(builder)); tw.AddTree(commit.Tree); tw.Filter = PathFilterGroup.CreateFromStrings(filepaths); tw.Recursive = true; while (tw.Next()) { CanonicalTreeParser tree = tw.GetTree <CanonicalTreeParser>(1); // only keep file in index if it's in the commit if (tree != null) { // revert index to commit DirCacheEntry entry = new DirCacheEntry(tw.RawPath); entry.FileMode = tree.EntryFileMode; entry.SetObjectId(tree.EntryObjectId); builder.Add(entry); } } builder.Commit(); } catch (IOException e) { throw new RuntimeException(e); } finally { if (dc != null) { dc.Unlock(); } } }
/// <exception cref="System.IO.IOException"></exception> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> private void CheckoutIndex(RevCommit commit) { DirCache dc = repo.LockDirCache(); try { DirCacheCheckout checkout = new DirCacheCheckout(repo, dc, commit.Tree); checkout.SetFailOnConflict(false); try { checkout.Checkout(); } catch (NGit.Errors.CheckoutConflictException cce) { throw new NGit.Api.Errors.CheckoutConflictException(checkout.GetConflicts(), cce); } } finally { dc.Unlock(); } }
/// <exception cref="System.IO.IOException"></exception> /// <exception cref="NGit.Api.Errors.NoHeadException"></exception> /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception> private RevCommit CheckoutCurrentHead() { ObjectId headTree = repo.Resolve(Constants.HEAD + "^{tree}"); if (headTree == null) { throw new NoHeadException(JGitText.Get().cannotRebaseWithoutCurrentHead); } DirCache dc = repo.LockDirCache(); try { DirCacheCheckout dco = new DirCacheCheckout(repo, dc, headTree); dco.SetFailOnConflict(false); bool needsDeleteFiles = dco.Checkout(); if (needsDeleteFiles) { IList <string> fileList = dco.GetToBeDeleted(); foreach (string filePath in fileList) { FilePath fileToDelete = new FilePath(repo.WorkTree, filePath); if (fileToDelete.Exists()) { FileUtils.Delete(fileToDelete, FileUtils.RECURSIVE | FileUtils.RETRY); } } } } finally { dc.Unlock(); } RevWalk rw = new RevWalk(repo); RevCommit commit = rw.ParseCommit(repo.Resolve(Constants.HEAD)); rw.Release(); return(commit); }
/// <exception cref="NGit.Errors.NoWorkTreeException"></exception> /// <exception cref="System.IO.IOException"></exception> public static void ValidateIndex(Git git) { DirCache dc = git.GetRepository().LockDirCache(); ObjectReader r = git.GetRepository().ObjectDatabase.NewReader(); try { for (int i = 0; i < dc.GetEntryCount(); ++i) { DirCacheEntry entry = dc.GetEntry(i); if (entry.Length > 0) { NUnit.Framework.Assert.AreEqual(entry.Length, r.GetObjectSize(entry.GetObjectId() , ObjectReader.OBJ_ANY)); } } } finally { dc.Unlock(); r.Release(); } }
/// <exception cref="System.IO.IOException"></exception> private void CheckoutIndex(RevCommit commit) { DirCache dc = null; try { dc = repo.LockDirCache(); DirCacheCheckout checkout = new DirCacheCheckout(repo, dc, commit.Tree); checkout.SetFailOnConflict(false); checkout.Checkout(); } catch (IOException e) { throw; } finally { if (dc != null) { dc.Unlock(); } } }
/// <exception cref="System.IO.IOException"></exception> private void ResetIndex(RevCommit commit) { DirCache dc = null; try { dc = repo.LockDirCache(); dc.Clear(); DirCacheBuilder dcb = dc.Builder(); dcb.AddTree(new byte[0], 0, repo.NewObjectReader(), commit.Tree); dcb.Commit(); } catch (IOException e) { throw; } finally { if (dc != null) { dc.Unlock(); } } }
/// <summary> /// Executes the /// <code>commit</code> /// command with all the options and parameters /// collected by the setter methods of this class. Each instance of this /// class should only be used for one invocation of the command (means: one /// call to /// <see cref="Call()">Call()</see> /// ) /// </summary> /// <returns> /// a /// <see cref="NGit.Revwalk.RevCommit">NGit.Revwalk.RevCommit</see> /// object representing the successful commit. /// </returns> /// <exception cref="NGit.Api.Errors.NoHeadException">when called on a git repo without a HEAD reference /// </exception> /// <exception cref="NGit.Api.Errors.NoMessageException">when called without specifying a commit message /// </exception> /// <exception cref="NGit.Api.Errors.UnmergedPathsException">when the current index contained unmerged paths (conflicts) /// </exception> /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"> /// when HEAD or branch ref is updated concurrently by someone /// else /// </exception> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">when repository is not in the right state for committing /// </exception> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> public override RevCommit Call() { CheckCallable(); RepositoryState state = repo.GetRepositoryState(); if (!state.CanCommit()) { throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().cannotCommitOnARepoWithState , state.Name())); } ProcessOptions(state); try { if (all && !repo.IsBare && repo.WorkTree != null) { Git git = new Git(repo); try { git.Add().AddFilepattern(".").SetUpdate(true).Call(); } catch (NoFilepatternException e) { // should really not happen throw new JGitInternalException(e.Message, e); } } Ref head = repo.GetRef(Constants.HEAD); if (head == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } // determine the current HEAD and the commit it is referring to ObjectId headId = repo.Resolve(Constants.HEAD + "^{commit}"); if (headId == null && amend) { throw new WrongRepositoryStateException(JGitText.Get().commitAmendOnInitialNotPossible ); } if (headId != null) { if (amend) { RevCommit previousCommit = new RevWalk(repo).ParseCommit(headId); RevCommit[] p = previousCommit.Parents; for (int i = 0; i < p.Length; i++) { parents.Add(0, p[i].Id); } if (author == null) { author = previousCommit.GetAuthorIdent(); } } else { parents.Add(0, headId); } } // lock the index DirCache index = repo.LockDirCache(); try { if (!only.IsEmpty()) { index = CreateTemporaryIndex(headId, index); } ObjectInserter odi = repo.NewObjectInserter(); try { // Write the index as tree to the object database. This may // fail for example when the index contains unmerged paths // (unresolved conflicts) ObjectId indexTreeId = index.WriteTree(odi); if (insertChangeId) { InsertChangeId(indexTreeId); } // Create a Commit object, populate it and write it NGit.CommitBuilder commit = new NGit.CommitBuilder(); commit.Committer = committer; commit.Author = author; commit.Message = message; commit.SetParentIds(parents); commit.TreeId = indexTreeId; ObjectId commitId = odi.Insert(commit); odi.Flush(); RevWalk revWalk = new RevWalk(repo); try { RevCommit revCommit = revWalk.ParseCommit(commitId); RefUpdate ru = repo.UpdateRef(Constants.HEAD); ru.SetNewObjectId(commitId); if (reflogComment != null) { ru.SetRefLogMessage(reflogComment, false); } else { string prefix = amend ? "commit (amend): " : "commit: "; ru.SetRefLogMessage(prefix + revCommit.GetShortMessage(), false); } if (headId != null) { ru.SetExpectedOldObjectId(headId); } else { ru.SetExpectedOldObjectId(ObjectId.ZeroId); } RefUpdate.Result rc = ru.ForceUpdate(); switch (rc) { case RefUpdate.Result.NEW: case RefUpdate.Result.FORCED: case RefUpdate.Result.FAST_FORWARD: { SetCallable(false); if (state == RepositoryState.MERGING_RESOLVED) { // Commit was successful. Now delete the files // used for merge commits repo.WriteMergeCommitMsg(null); repo.WriteMergeHeads(null); } else { if (state == RepositoryState.CHERRY_PICKING_RESOLVED) { repo.WriteMergeCommitMsg(null); repo.WriteCherryPickHead(null); } } return(revCommit); } case RefUpdate.Result.REJECTED: case RefUpdate.Result.LOCK_FAILURE: { throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, ru.GetRef (), rc); } default: { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed , Constants.HEAD, commitId.ToString(), rc)); } } } finally { revWalk.Release(); } } finally { odi.Release(); } } finally { index.Unlock(); } } catch (UnmergedPathException e) { throw new UnmergedPathsException(e); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfCommitCommand , e); } }
/// <summary>Apply the changes in a stashed commit to the working directory and index /// </summary> /// <returns>id of stashed commit that was applied</returns> /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException /// </exception> public override ObjectId Call() { CheckCallable(); if (repo.GetRepositoryState() != RepositoryState.SAFE) { throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().stashApplyOnUnsafeRepository , repo.GetRepositoryState())); } ObjectId headTree = GetHeadTree(); ObjectId stashId = GetStashId(); ObjectReader reader = repo.NewObjectReader(); try { RevWalk revWalk = new RevWalk(reader); RevCommit stashCommit = revWalk.ParseCommit(stashId); if (stashCommit.ParentCount != 2) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().stashCommitMissingTwoParents , stashId.Name)); } RevTree stashWorkingTree = stashCommit.Tree; RevTree stashIndexTree = revWalk.ParseCommit(stashCommit.GetParent(1)).Tree; RevTree stashHeadTree = revWalk.ParseCommit(stashCommit.GetParent(0)).Tree; CanonicalTreeParser stashWorkingIter = new CanonicalTreeParser(); stashWorkingIter.Reset(reader, stashWorkingTree); CanonicalTreeParser stashIndexIter = new CanonicalTreeParser(); stashIndexIter.Reset(reader, stashIndexTree); CanonicalTreeParser stashHeadIter = new CanonicalTreeParser(); stashHeadIter.Reset(reader, stashHeadTree); CanonicalTreeParser headIter = new CanonicalTreeParser(); headIter.Reset(reader, headTree); DirCache cache = repo.LockDirCache(); DirCacheEditor editor = cache.Editor(); try { DirCacheIterator indexIter = new DirCacheIterator(cache); FileTreeIterator workingIter = new FileTreeIterator(repo); TreeWalk treeWalk = new TreeWalk(reader); treeWalk.Recursive = true; treeWalk.Filter = new StashApplyCommand.StashDiffFilter(); treeWalk.AddTree(stashHeadIter); treeWalk.AddTree(stashIndexIter); treeWalk.AddTree(stashWorkingIter); treeWalk.AddTree(headIter); treeWalk.AddTree(indexIter); treeWalk.AddTree(workingIter); ScanForConflicts(treeWalk); // Reset trees and walk treeWalk.Reset(); stashWorkingIter.Reset(reader, stashWorkingTree); stashIndexIter.Reset(reader, stashIndexTree); stashHeadIter.Reset(reader, stashHeadTree); treeWalk.AddTree(stashHeadIter); treeWalk.AddTree(stashIndexIter); treeWalk.AddTree(stashWorkingIter); ApplyChanges(treeWalk, cache, editor); } finally { editor.Commit(); cache.Unlock(); } } catch (JGitInternalException e) { throw; } catch (IOException e) { throw new JGitInternalException(JGitText.Get().stashApplyFailed, e); } finally { reader.Release(); } return(stashId); }
/// <exception cref="NGit.Api.Errors.RefAlreadyExistsException"> /// when trying to create (without force) a branch with a name /// that already exists /// </exception> /// <exception cref="NGit.Api.Errors.RefNotFoundException">if the start point or branch can not be found /// </exception> /// <exception cref="NGit.Api.Errors.InvalidRefNameException"> /// if the provided name is <code>null</code> or otherwise /// invalid /// </exception> /// <exception cref="NGit.Api.Errors.CheckoutConflictException">if the checkout results in a conflict /// </exception> /// <returns>the newly created branch</returns> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> public override Ref Call() { CheckCallable(); ProcessOptions(); try { if (checkoutAllPaths || !paths.IsEmpty()) { CheckoutPaths(); status = new CheckoutResult(CheckoutResult.Status.OK, paths); SetCallable(false); return(null); } if (createBranch) { Git git = new Git(repo); CreateBranchCommand command = git.BranchCreate(); command.SetName(name); command.SetStartPoint(GetStartPoint().Name); if (upstreamMode != null) { command.SetUpstreamMode(upstreamMode); } command.Call(); } Ref headRef = repo.GetRef(Constants.HEAD); string shortHeadRef = GetShortBranchName(headRef); string refLogMessage = "checkout: moving from " + shortHeadRef; ObjectId branch = repo.Resolve(name); if (branch == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , name)); } RevWalk revWalk = new RevWalk(repo); AnyObjectId headId = headRef.GetObjectId(); RevCommit headCommit = headId == null ? null : revWalk.ParseCommit(headId); RevCommit newCommit = revWalk.ParseCommit(branch); RevTree headTree = headCommit == null ? null : headCommit.Tree; DirCacheCheckout dco; DirCache dc = repo.LockDirCache(); try { dco = new DirCacheCheckout(repo, headTree, dc, newCommit.Tree); dco.SetFailOnConflict(true); try { dco.Checkout(); } catch (NGit.Errors.CheckoutConflictException e) { status = new CheckoutResult(CheckoutResult.Status.CONFLICTS, dco.GetConflicts()); throw new NGit.Api.Errors.CheckoutConflictException(dco.GetConflicts(), e); } } finally { dc.Unlock(); } Ref @ref = repo.GetRef(name); if (@ref != null && [email protected]().StartsWith(Constants.R_HEADS)) { @ref = null; } string toName = Repository.ShortenRefName(name); RefUpdate refUpdate = repo.UpdateRef(Constants.HEAD, @ref == null); refUpdate.SetForceUpdate(force); refUpdate.SetRefLogMessage(refLogMessage + " to " + toName, false); RefUpdate.Result updateResult; if (@ref != null) { updateResult = refUpdate.Link(@ref.GetName()); } else { refUpdate.SetNewObjectId(newCommit); updateResult = refUpdate.ForceUpdate(); } SetCallable(false); bool ok = false; switch (updateResult) { case RefUpdate.Result.NEW: { ok = true; break; } case RefUpdate.Result.NO_CHANGE: case RefUpdate.Result.FAST_FORWARD: case RefUpdate.Result.FORCED: { ok = true; break; } default: { break; break; } } if (!ok) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().checkoutUnexpectedResult , updateResult.ToString())); } if (!dco.GetToBeDeleted().IsEmpty()) { status = new CheckoutResult(CheckoutResult.Status.NONDELETED, dco.GetToBeDeleted( )); } else { status = new CheckoutResult(new AList <string>(dco.GetUpdated().Keys), dco.GetRemoved ()); } return(@ref); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } finally { if (status == null) { status = CheckoutResult.ERROR_RESULT; } } }
/// <summary> /// Stash the contents on the working directory and index in separate commits /// and reset to the current HEAD commit. /// </summary> /// <remarks> /// Stash the contents on the working directory and index in separate commits /// and reset to the current HEAD commit. /// </remarks> /// <returns>stashed commit or null if no changes to stash</returns> /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> public override RevCommit Call() { CheckCallable(); Ref head = GetHead(); ObjectReader reader = repo.NewObjectReader(); try { RevCommit headCommit = ParseCommit(reader, head.GetObjectId()); DirCache cache = repo.LockDirCache(); ObjectInserter inserter = repo.NewObjectInserter(); ObjectId commitId; try { TreeWalk treeWalk = new TreeWalk(reader); treeWalk.Recursive = true; treeWalk.AddTree(headCommit.Tree); treeWalk.AddTree(new DirCacheIterator(cache)); treeWalk.AddTree(new FileTreeIterator(repo)); treeWalk.Filter = AndTreeFilter.Create(new SkipWorkTreeFilter(1), new IndexDiffFilter (1, 2)); // Return null if no local changes to stash if (!treeWalk.Next()) { return(null); } MutableObjectId id = new MutableObjectId(); IList <DirCacheEditor.PathEdit> wtEdits = new AList <DirCacheEditor.PathEdit>(); IList <string> wtDeletes = new AList <string>(); do { AbstractTreeIterator headIter = treeWalk.GetTree <AbstractTreeIterator>(0); DirCacheIterator indexIter = treeWalk.GetTree <DirCacheIterator>(1); WorkingTreeIterator wtIter = treeWalk.GetTree <WorkingTreeIterator>(2); if (headIter != null && indexIter != null && wtIter != null) { if (!indexIter.GetDirCacheEntry().IsMerged()) { throw new UnmergedPathsException(new UnmergedPathException(indexIter.GetDirCacheEntry ())); } if (wtIter.IdEqual(indexIter) || wtIter.IdEqual(headIter)) { continue; } treeWalk.GetObjectId(id, 0); DirCacheEntry entry = new DirCacheEntry(treeWalk.RawPath); entry.SetLength(wtIter.GetEntryLength()); entry.LastModified = wtIter.GetEntryLastModified(); entry.FileMode = wtIter.EntryFileMode; long contentLength = wtIter.GetEntryContentLength(); InputStream @in = wtIter.OpenEntryStream(); try { entry.SetObjectId(inserter.Insert(Constants.OBJ_BLOB, contentLength, @in)); } finally { @in.Close(); } wtEdits.AddItem(new _PathEdit_273(entry, entry)); } else { if (indexIter == null) { wtDeletes.AddItem(treeWalk.PathString); } else { if (wtIter == null && headIter != null) { wtDeletes.AddItem(treeWalk.PathString); } } } }while (treeWalk.Next()); string branch = Repository.ShortenRefName(head.GetTarget().GetName()); // Commit index changes NGit.CommitBuilder builder = CreateBuilder(headCommit); builder.TreeId = cache.WriteTree(inserter); builder.Message = MessageFormat.Format(indexMessage, branch, headCommit.Abbreviate (7).Name, headCommit.GetShortMessage()); ObjectId indexCommit = inserter.Insert(builder); // Commit working tree changes if (!wtEdits.IsEmpty() || !wtDeletes.IsEmpty()) { DirCacheEditor editor = cache.Editor(); foreach (DirCacheEditor.PathEdit edit in wtEdits) { editor.Add(edit); } foreach (string path in wtDeletes) { editor.Add(new DirCacheEditor.DeletePath(path)); } editor.Finish(); } builder.AddParentId(indexCommit); builder.Message = MessageFormat.Format(workingDirectoryMessage, branch, headCommit .Abbreviate(7).Name, headCommit.GetShortMessage()); builder.TreeId = cache.WriteTree(inserter); commitId = inserter.Insert(builder); inserter.Flush(); UpdateStashRef(commitId, builder.Author, builder.Message); } finally { inserter.Release(); cache.Unlock(); } // Hard reset to HEAD new ResetCommand(repo).SetMode(ResetCommand.ResetType.HARD).Call(); // Return stashed commit return(ParseCommit(reader, commitId)); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().stashFailed, e); } finally { reader.Release(); } }
/// <exception cref="System.IO.IOException"></exception> protected internal override bool MergeImpl() { bool implicitDirCache = false; if (dircache == null) { dircache = GetRepository().LockDirCache(); implicitDirCache = true; } try { builder = dircache.Builder(); DirCacheBuildIterator buildIt = new DirCacheBuildIterator(builder); tw = new NameConflictTreeWalk(db); tw.AddTree(MergeBase()); tw.AddTree(sourceTrees[0]); tw.AddTree(sourceTrees[1]); tw.AddTree(buildIt); if (workingTreeIterator != null) { tw.AddTree(workingTreeIterator); } while (tw.Next()) { if (!ProcessEntry(tw.GetTree <CanonicalTreeParser>(T_BASE), tw.GetTree <CanonicalTreeParser >(T_OURS), tw.GetTree <CanonicalTreeParser>(T_THEIRS), tw.GetTree <DirCacheBuildIterator >(T_INDEX), (workingTreeIterator == null) ? null : tw.GetTree <WorkingTreeIterator >(T_FILE))) { CleanUp(); return(false); } if (tw.IsSubtree && enterSubtree) { tw.EnterSubtree(); } } if (!inCore) { // All content-merges are successfully done. If we can now write the // new index we are on quite safe ground. Even if the checkout of // files coming from "theirs" fails the user can work around such // failures by checking out the index again. if (!builder.Commit()) { CleanUp(); throw new IndexWriteException(); } builder = null; // No problem found. The only thing left to be done is to checkout // all files from "theirs" which have been selected to go into the // new index. Checkout(); } else { builder.Finish(); builder = null; } if (GetUnmergedPaths().IsEmpty()) { resultTree = dircache.WriteTree(oi); return(true); } else { resultTree = null; return(false); } } finally { if (implicitDirCache) { dircache.Unlock(); } } }