/// <summary> /// Executes the /// <code>Rm</code> /// command. 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 DirCache after Rm</returns> /// <exception cref="NGit.Api.Errors.NoFilepatternException"></exception> public override DirCache Call() { if (filepatterns.IsEmpty()) { throw new NoFilepatternException(JGitText.Get().atLeastOnePatternIsRequired); } CheckCallable(); DirCache dc = null; try { dc = repo.LockDirCache(); DirCacheBuilder builder = dc.Builder(); TreeWalk tw = new TreeWalk(repo); tw.Reset(); // drop the first empty tree, which we do not need here tw.Recursive = true; tw.Filter = PathFilterGroup.CreateFromStrings(filepatterns); tw.AddTree(new DirCacheBuildIterator(builder)); while (tw.Next()) { FilePath path = new FilePath(repo.WorkTree, tw.PathString); FileMode mode = tw.GetFileMode(0); if (mode.GetObjectType() == Constants.OBJ_BLOB) { // Deleting a blob is simply a matter of removing // the file or symlink named by the tree entry. Delete(path); } } builder.Commit(); SetCallable(false); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfRmCommand , e); } finally { if (dc != null) { dc.Unlock(); } } return(dc); }
/// <exception cref="System.IO.IOException"></exception> private void ResetIndex(RevCommit commit) { DirCache dc = repo.LockDirCache(); TreeWalk walk = null; try { DirCacheBuilder builder = dc.Builder(); 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) { // Not in commit, don't add to new index 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); } builder.Add(entry); } builder.Commit(); } finally { dc.Unlock(); if (walk != null) { walk.Release(); } } }
public virtual void TestAddWithConflicts() { // prepare conflict FilePath file = new FilePath(db.WorkTree, "a.txt"); FileUtils.CreateNewFile(file); PrintWriter writer = new PrintWriter(file); writer.Write("content"); writer.Close(); FilePath file2 = new FilePath(db.WorkTree, "b.txt"); FileUtils.CreateNewFile(file2); writer = new PrintWriter(file2); writer.Write("content b"); writer.Close(); ObjectInserter newObjectInserter = db.NewObjectInserter(); DirCache dc = db.LockDirCache(); DirCacheBuilder builder = dc.Builder(); AddEntryToBuilder("b.txt", file2, newObjectInserter, builder, 0); AddEntryToBuilder("a.txt", file, newObjectInserter, builder, 1); writer = new PrintWriter(file); writer.Write("other content"); writer.Close(); AddEntryToBuilder("a.txt", file, newObjectInserter, builder, 3); writer = new PrintWriter(file); writer.Write("our content"); writer.Close(); AddEntryToBuilder("a.txt", file, newObjectInserter, builder, 2).GetObjectId(); builder.Commit(); NUnit.Framework.Assert.AreEqual("[a.txt, mode:100644, stage:1, content:content]" + "[a.txt, mode:100644, stage:2, content:our content]" + "[a.txt, mode:100644, stage:3, content:other content]" + "[b.txt, mode:100644, content:content b]", IndexState(CONTENT)); // now the test begins Git git = new Git(db); dc = git.Add().AddFilepattern("a.txt").Call(); NUnit.Framework.Assert.AreEqual("[a.txt, mode:100644, content:our content]" + "[b.txt, mode:100644, content:content b]" , IndexState(CONTENT)); }
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(); } } }
public virtual void TestPathsResetWithUnmerged() { SetupRepository(); string file = "a.txt"; WriteTrashFile(file, "data"); git.Add().AddFilepattern(file).Call(); git.Commit().SetMessage("commit").Call(); DirCache index = db.LockDirCache(); DirCacheBuilder builder = index.Builder(); builder.Add(CreateEntry(file, FileMode.REGULAR_FILE, 1, string.Empty)); builder.Add(CreateEntry(file, FileMode.REGULAR_FILE, 2, string.Empty)); builder.Add(CreateEntry(file, FileMode.REGULAR_FILE, 3, string.Empty)); builder.Add(CreateEntry("b.txt", FileMode.REGULAR_FILE)); NUnit.Framework.Assert.IsTrue(builder.Commit()); NUnit.Framework.Assert.AreEqual("[a.txt, mode:100644, stage:1]" + "[a.txt, mode:100644, stage:2]" + "[a.txt, mode:100644, stage:3]" + "[b.txt, mode:100644]", IndexState(0)); git.Reset().AddPath(file).Call(); NUnit.Framework.Assert.AreEqual("[a.txt, mode:100644]" + "[b.txt, mode:100644]", IndexState(0)); }
/// <summary>Resets the index to represent exactly some filesystem content.</summary> /// <remarks> /// Resets the index to represent exactly some filesystem content. E.g. the /// following call will replace the index with the working tree content: /// <p> /// <code>resetIndex(new FileSystemIterator(db))</code> /// <p> /// This method can be used by testcases which first prepare a new commit /// somewhere in the filesystem (e.g. in the working-tree) and then want to /// have an index which matches their prepared content. /// </remarks> /// <param name="treeItr"> /// a /// <see cref="NGit.Treewalk.FileTreeIterator">NGit.Treewalk.FileTreeIterator</see> /// which determines which files should /// go into the new index /// </param> /// <exception cref="System.IO.FileNotFoundException">System.IO.FileNotFoundException /// </exception> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> protected internal virtual void ResetIndex(FileTreeIterator treeItr) { ObjectInserter inserter = db.NewObjectInserter(); DirCacheBuilder builder = db.LockDirCache().Builder(); DirCacheEntry dce; while (!treeItr.Eof) { long len = treeItr.GetEntryLength(); dce = new DirCacheEntry(treeItr.EntryPathString); dce.FileMode = treeItr.EntryFileMode; dce.LastModified = treeItr.GetEntryLastModified(); dce.SetLength((int)len); FileInputStream @in = new FileInputStream(treeItr.GetEntryFile()); dce.SetObjectId(inserter.Insert(Constants.OBJ_BLOB, len, @in)); @in.Close(); builder.Add(dce); treeItr.Next(1); } builder.Commit(); inserter.Flush(); inserter.Release(); }
/// <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(); } } }
public virtual void TestMixedResetWithUnmerged() { git = new Git(db); string file = "a.txt"; WriteTrashFile(file, "data"); string file2 = "b.txt"; WriteTrashFile(file2, "data"); git.Add().AddFilepattern(file).AddFilepattern(file2).Call(); git.Commit().SetMessage("commit").Call(); DirCache index = db.LockDirCache(); DirCacheBuilder builder = index.Builder(); builder.Add(CreateEntry(file, FileMode.REGULAR_FILE, 1, string.Empty)); builder.Add(CreateEntry(file, FileMode.REGULAR_FILE, 2, string.Empty)); builder.Add(CreateEntry(file, FileMode.REGULAR_FILE, 3, string.Empty)); NUnit.Framework.Assert.IsTrue(builder.Commit()); NUnit.Framework.Assert.AreEqual("[a.txt, mode:100644, stage:1]" + "[a.txt, mode:100644, stage:2]" + "[a.txt, mode:100644, stage:3]", IndexState(0)); git.Reset().SetMode(ResetCommand.ResetType.MIXED).Call(); NUnit.Framework.Assert.AreEqual("[a.txt, mode:100644]" + "[b.txt, mode:100644]", IndexState(0)); }
/// <summary> /// Executes the /// <code>Add</code> /// command. 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 DirCache after Add</returns> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> /// <exception cref="NGit.Api.Errors.NoFilepatternException"></exception> public override DirCache Call() { if (filepatterns.IsEmpty()) { throw new NoFilepatternException(JGitText.Get().atLeastOnePatternIsRequired); } CheckCallable(); DirCache dc = null; bool addAll = false; if (filepatterns.Contains(".")) { addAll = true; } ObjectInserter inserter = repo.NewObjectInserter(); try { dc = repo.LockDirCache(); DirCacheIterator c; DirCacheBuilder builder = dc.Builder(); TreeWalk tw = new TreeWalk(repo); tw.AddTree(new DirCacheBuildIterator(builder)); if (workingTreeIterator == null) { workingTreeIterator = new FileTreeIterator(repo); } tw.AddTree(workingTreeIterator); tw.Recursive = true; if (!addAll) { tw.Filter = PathFilterGroup.CreateFromStrings(filepatterns); } string lastAddedFile = null; while (tw.Next()) { string path = tw.PathString; WorkingTreeIterator f = tw.GetTree <WorkingTreeIterator>(1); if (tw.GetTree <DirCacheIterator>(0) == null && f != null && f.IsEntryIgnored()) { } else { // file is not in index but is ignored, do nothing // In case of an existing merge conflict the // DirCacheBuildIterator iterates over all stages of // this path, we however want to add only one // new DirCacheEntry per path. if (!(path.Equals(lastAddedFile))) { if (!(update && tw.GetTree <DirCacheIterator>(0) == null)) { c = tw.GetTree <DirCacheIterator>(0); if (f != null) { // the file exists long sz = f.GetEntryLength(); DirCacheEntry entry = new DirCacheEntry(path); if (c == null || c.GetDirCacheEntry() == null || !c.GetDirCacheEntry().IsAssumeValid) { FileMode mode = f.GetIndexFileMode(c); entry.FileMode = mode; if (FileMode.GITLINK != mode) { entry.SetLength(sz); entry.LastModified = f.GetEntryLastModified(); long contentSize = f.GetEntryContentLength(); InputStream @in = f.OpenEntryStream(); try { entry.SetObjectId(inserter.Insert(Constants.OBJ_BLOB, contentSize, @in)); } finally { @in.Close(); } } else { entry.SetObjectId(f.EntryObjectId); } builder.Add(entry); lastAddedFile = path; } else { builder.Add(c.GetDirCacheEntry()); } } else { if (c != null && (!update || FileMode.GITLINK == c.EntryFileMode)) { builder.Add(c.GetDirCacheEntry()); } } } } } } inserter.Flush(); builder.Commit(); SetCallable(false); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfAddCommand , e); } finally { inserter.Release(); if (dc != null) { dc.Unlock(); } } return(dc); }
/// <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(); } } }