ObjectId WriteWorkingDirectoryTree(RevTree headTree, DirCache index) { DirCache dc = DirCache.NewInCore(); DirCacheBuilder cb = dc.Builder(); ObjectInserter oi = _repo.NewObjectInserter(); try { TreeWalk tw = new TreeWalk(_repo); tw.Reset(); tw.AddTree(new FileTreeIterator(_repo)); tw.AddTree(headTree); tw.AddTree(new DirCacheIterator(index)); while (tw.Next()) { // Ignore untracked files if (tw.IsSubtree) { tw.EnterSubtree(); } else if (tw.GetFileMode(0) != NGit.FileMode.MISSING && (tw.GetFileMode(1) != NGit.FileMode.MISSING || tw.GetFileMode(2) != NGit.FileMode.MISSING)) { WorkingTreeIterator f = tw.GetTree <WorkingTreeIterator>(0); DirCacheIterator dcIter = tw.GetTree <DirCacheIterator>(2); DirCacheEntry currentEntry = dcIter.GetDirCacheEntry(); DirCacheEntry ce = new DirCacheEntry(tw.PathString); if (!f.IsModified(currentEntry, true)) { ce.SetLength(currentEntry.Length); ce.LastModified = currentEntry.LastModified; ce.FileMode = currentEntry.FileMode; ce.SetObjectId(currentEntry.GetObjectId()); } else { long sz = f.GetEntryLength(); ce.SetLength(sz); ce.LastModified = f.GetEntryLastModified(); ce.FileMode = f.EntryFileMode; var data = f.OpenEntryStream(); try { ce.SetObjectId(oi.Insert(Constants.OBJ_BLOB, sz, data)); } finally { data.Close(); } } cb.Add(ce); } } cb.Finish(); return(dc.WriteTree(oi)); } finally { oi.Release(); } }
/// <exception cref="System.IO.IOException"></exception> private void AssertEntry(FileMode type, bool entryIgnored, string pathName) { NUnit.Framework.Assert.IsTrue(walk.Next(), "walk has entry"); NUnit.Framework.Assert.AreEqual(pathName, walk.PathString); NUnit.Framework.Assert.AreEqual(type, walk.GetFileMode(0)); WorkingTreeIterator itr = walk.GetTree <WorkingTreeIterator>(0); NUnit.Framework.Assert.IsNotNull(itr, "has tree"); NUnit.Framework.Assert.AreEqual(entryIgnored, itr.IsEntryIgnored(), "is ignored"); if (D.Equals(type)) { walk.EnterSubtree(); } }
public virtual void TestNonRecursiveTreeWalk() { RevCommit commit = WriteFileInFolderAndCommit(); DeleteAll(); WriteFileWithFolderName(); TreeWalk treeWalk = CreateNonRecursiveTreeWalk(commit); NUnit.Framework.Assert.IsTrue(treeWalk.Next()); NUnit.Framework.Assert.AreEqual("folder", treeWalk.PathString); NUnit.Framework.Assert.IsTrue(treeWalk.Next()); NUnit.Framework.Assert.AreEqual("folder", treeWalk.PathString); NUnit.Framework.Assert.IsTrue(treeWalk.IsSubtree); treeWalk.EnterSubtree(); NUnit.Framework.Assert.IsTrue(treeWalk.Next()); NUnit.Framework.Assert.AreEqual("folder/file", treeWalk.PathString); NUnit.Framework.Assert.IsFalse(treeWalk.Next()); }
/// <exception cref="System.IO.IOException"></exception> private bool Find(RevCommit commit, PathFilter path) { treeWalk.Filter = path; treeWalk.Reset(commit.Tree); while (treeWalk.Next()) { if (path.IsDone(treeWalk)) { if (treeWalk.GetFileMode(0).GetObjectType() != Constants.OBJ_BLOB) { return(false); } treeWalk.GetObjectId(idBuf, 0); return(true); } if (treeWalk.IsSubtree) { treeWalk.EnterSubtree(); } } return(false); }
public virtual void TestFindObjects() { DirCache tree0 = DirCache.NewInCore(); DirCacheBuilder b0 = tree0.Builder(); ObjectReader or = db.NewObjectReader(); ObjectInserter oi = db.NewObjectInserter(); DirCacheEntry aDotB = CreateEntry("a.b", EXECUTABLE_FILE); b0.Add(aDotB); DirCacheEntry aSlashB = CreateEntry("a/b", REGULAR_FILE); b0.Add(aSlashB); DirCacheEntry aSlashCSlashD = CreateEntry("a/c/d", REGULAR_FILE); b0.Add(aSlashCSlashD); DirCacheEntry aZeroB = CreateEntry("a0b", SYMLINK); b0.Add(aZeroB); b0.Finish(); NUnit.Framework.Assert.AreEqual(4, tree0.GetEntryCount()); ObjectId tree = tree0.WriteTree(oi); // Find the directories that were implicitly created above. TreeWalk tw = new TreeWalk(or); tw.AddTree(tree); ObjectId a = null; ObjectId aSlashC = null; while (tw.Next()) { if (tw.PathString.Equals("a")) { a = tw.GetObjectId(0); tw.EnterSubtree(); while (tw.Next()) { if (tw.PathString.Equals("a/c")) { aSlashC = tw.GetObjectId(0); break; } } break; } } NUnit.Framework.Assert.AreEqual(a, TreeWalk.ForPath(or, "a", tree).GetObjectId(0) ); NUnit.Framework.Assert.AreEqual(a, TreeWalk.ForPath(or, "a/", tree).GetObjectId(0 )); NUnit.Framework.Assert.AreEqual(null, TreeWalk.ForPath(or, "/a", tree)); NUnit.Framework.Assert.AreEqual(null, TreeWalk.ForPath(or, "/a/", tree)); NUnit.Framework.Assert.AreEqual(aDotB.GetObjectId(), TreeWalk.ForPath(or, "a.b", tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(null, TreeWalk.ForPath(or, "/a.b", tree)); NUnit.Framework.Assert.AreEqual(null, TreeWalk.ForPath(or, "/a.b/", tree)); NUnit.Framework.Assert.AreEqual(aDotB.GetObjectId(), TreeWalk.ForPath(or, "a.b/", tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aZeroB.GetObjectId(), TreeWalk.ForPath(or, "a0b", tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aSlashB.GetObjectId(), TreeWalk.ForPath(or, "a/b" , tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aSlashB.GetObjectId(), TreeWalk.ForPath(or, "b", a).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aSlashC, TreeWalk.ForPath(or, "a/c", tree).GetObjectId (0)); NUnit.Framework.Assert.AreEqual(aSlashC, TreeWalk.ForPath(or, "c", a).GetObjectId (0)); NUnit.Framework.Assert.AreEqual(aSlashCSlashD.GetObjectId(), TreeWalk.ForPath(or, "a/c/d", tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aSlashCSlashD.GetObjectId(), TreeWalk.ForPath(or, "c/d", a).GetObjectId(0)); or.Release(); oi.Release(); }
/// <summary> /// Convert the TreeWalk into DiffEntry headers, depending on /// <code>includeTrees</code> /// it will add tree objects into result or not. /// </summary> /// <param name="walk"> /// the TreeWalk to walk through. Must have exactly two trees and /// when /// <code>includeTrees</code> /// parameter is /// <code>true</code> /// it can't /// be recursive. /// </param> /// <param name="includeTrees">include tree object's.</param> /// <returns>headers describing the changed files.</returns> /// <exception cref="System.IO.IOException">the repository cannot be accessed.</exception> /// <exception cref="System.ArgumentException"> /// when /// <code>includeTrees</code> /// is true and given TreeWalk is /// recursive. Or when given TreeWalk doesn't have exactly two /// trees /// </exception> public static IList <NGit.Diff.DiffEntry> Scan(TreeWalk walk, bool includeTrees) { if (walk.TreeCount != 2) { throw new ArgumentException(JGitText.Get().treeWalkMustHaveExactlyTwoTrees); } if (includeTrees && walk.Recursive) { throw new ArgumentException(JGitText.Get().cannotBeRecursiveWhenTreesAreIncluded); } IList <NGit.Diff.DiffEntry> r = new AList <NGit.Diff.DiffEntry>(); MutableObjectId idBuf = new MutableObjectId(); while (walk.Next()) { NGit.Diff.DiffEntry entry = new NGit.Diff.DiffEntry(); walk.GetObjectId(idBuf, 0); entry.oldId = AbbreviatedObjectId.FromObjectId(idBuf); walk.GetObjectId(idBuf, 1); entry.newId = AbbreviatedObjectId.FromObjectId(idBuf); entry.oldMode = walk.GetFileMode(0); entry.newMode = walk.GetFileMode(1); entry.newPath = entry.oldPath = walk.PathString; if (entry.oldMode == FileMode.MISSING) { entry.oldPath = NGit.Diff.DiffEntry.DEV_NULL; entry.changeType = DiffEntry.ChangeType.ADD; r.AddItem(entry); } else { if (entry.newMode == FileMode.MISSING) { entry.newPath = NGit.Diff.DiffEntry.DEV_NULL; entry.changeType = DiffEntry.ChangeType.DELETE; r.AddItem(entry); } else { if (!entry.oldId.Equals(entry.newId)) { entry.changeType = DiffEntry.ChangeType.MODIFY; if (RenameDetector.SameType(entry.oldMode, entry.newMode)) { r.AddItem(entry); } else { Sharpen.Collections.AddAll(r, BreakModify(entry)); } } else { if (entry.oldMode != entry.newMode) { entry.changeType = DiffEntry.ChangeType.MODIFY; r.AddItem(entry); } } } } if (includeTrees && walk.IsSubtree) { walk.EnterSubtree(); } } return(r); }
public string ReadCommit(string commitId, string fileName) { var repo = m_git.GetRepository(); var id = ObjectId.FromString(commitId); RevCommit commit = null; try { commit = ParseCommit(repo, id); if (commit == null) { return(null); } } catch (Exception ex) { Trace.WriteLine(ex.Message); return(null); } //var commits = m_git.Log().AddRange(id, id).Call(); //var commit = commits.SingleOrDefault(); //if (commit == null) // return null; TreeWalk walk = new TreeWalk(repo); //RevWalk r = new RevWalk(m_git.GetRepository()); //var tree = r.ParseTree(commit.Tree.Id); //r.LookupTree( //walk.AddTree(new FileTreeIterator(repo)); //var tree = ParseTree(repo, commit.Tree.Id); walk.AddTree(commit.Tree); var filter = GetGitFriendlyName(fileName); walk.Filter = PathFilterGroup.CreateFromStrings(new string[] { filter }); //walk.EnterSubtree(); while (walk.Next()) { var path = walk.PathString; if (walk.IsSubtree) { walk.EnterSubtree(); continue; } if (path == filter) { var cur = walk.GetObjectId(0); ObjectLoader ol = repo.Open(cur); // //Console.WriteLine(string.Format("Path: {0}{1}", walk.PathString, walk.IsSubtree ? "/" : "")); // //var loader = reader.Open(commit.Tree.Id); var text = ""; using (var stream = ol.OpenStream()) using (var sr = new System.IO.StreamReader(stream)) { text = sr.ReadToEnd(); } return(text); } } //walk.Reset(); //reader.Open(); return(""); }
/// <summary> /// Run the diff operation. Until this is called, all lists will be empty /// </summary> /// <returns>true if anything is different between index, tree, and workdir</returns> private void UpdateDirectory (IEnumerable<string> paths, bool recursive) { RevWalk rw = new RevWalk (Repository); ObjectId id = Repository.Resolve (Constants.HEAD); var commit = id != null ? rw.ParseCommit (id) : null; TreeWalk treeWalk = new TreeWalk (Repository); treeWalk.Reset (); treeWalk.Recursive = false; if (commit != null) treeWalk.AddTree (commit.Tree); else treeWalk.AddTree (new EmptyTreeIterator()); DirCache dc = Repository.ReadDirCache (); treeWalk.AddTree (new DirCacheIterator (dc)); FileTreeIterator workTree = new FileTreeIterator (Repository.WorkTree, Repository.FileSystem, WorkingTreeOptions.KEY.Parse(Repository.GetConfig())); treeWalk.AddTree (workTree); List<TreeFilter> filters = new List<TreeFilter> (); filters.Add (new SkipWorkTreeFilter(1)); var pathFilters = paths.Where (p => p != ".").Select (p => PathFilter.Create (p)).ToArray (); if (pathFilters.Length > 1) { filters.Add (OrTreeFilter.Create (pathFilters)); // Use an OR to join all path filters } else if (pathFilters.Length == 1) filters.Add (pathFilters[0]); if (filters.Count > 1) treeWalk.Filter = AndTreeFilter.Create(filters); else treeWalk.Filter = filters[0]; while (treeWalk.Next()) { AbstractTreeIterator treeIterator = treeWalk.GetTree<AbstractTreeIterator>(0); DirCacheIterator dirCacheIterator = treeWalk.GetTree<DirCacheIterator>(1); WorkingTreeIterator workingTreeIterator = treeWalk.GetTree<WorkingTreeIterator>(2); NGit.FileMode fileModeTree = treeWalk.GetFileMode(0); if (treeWalk.IsSubtree) { treeWalk.EnterSubtree (); continue; } int stage = dirCacheIterator != null ? dirCacheIterator.GetDirCacheEntry ().Stage : 0; if (stage > 1) continue; else if (stage == 1) { MergeConflict.Add(dirCacheIterator.EntryPathString); changesExist = true; continue; } if (treeIterator != null) { if (dirCacheIterator != null) { if (!treeIterator.EntryObjectId.Equals(dirCacheIterator.EntryObjectId)) { // in repo, in index, content diff => changed Modified.Add(dirCacheIterator.EntryPathString); changesExist = true; } } else { // in repo, not in index => removed if (!fileModeTree.Equals(NGit.FileMode.TYPE_TREE)) { Removed.Add(treeIterator.EntryPathString); changesExist = true; } } } else { if (dirCacheIterator != null) { // not in repo, in index => added Added.Add(dirCacheIterator.EntryPathString); changesExist = true; } else { // not in repo, not in index => untracked if (workingTreeIterator != null && !workingTreeIterator.IsEntryIgnored()) { Untracked.Add(workingTreeIterator.EntryPathString); changesExist = true; } } } if (dirCacheIterator != null) { if (workingTreeIterator == null) { // in index, not in workdir => missing Missing.Add(dirCacheIterator.EntryPathString); changesExist = true; } else { // Workaround to file time resolution issues long itime = dirCacheIterator.GetDirCacheEntry ().LastModified; long ftime = workingTreeIterator.GetEntryLastModified (); if (itime / 1000 != ftime / 1000) { if (!dirCacheIterator.IdEqual(workingTreeIterator)) { // in index, in workdir, content differs => modified Modified.Add(dirCacheIterator.EntryPathString); changesExist = true; } } } } } }
public string ReadCommit(string commitId, string fileName) { var repo = m_git.GetRepository(); var id = ObjectId.FromString(commitId); RevCommit commit = null; try { commit = ParseCommit(repo, id); if (commit == null) return null; } catch (Exception ex) { Trace.WriteLine(ex.Message); return null; } //var commits = m_git.Log().AddRange(id, id).Call(); //var commit = commits.SingleOrDefault(); //if (commit == null) // return null; TreeWalk walk = new TreeWalk(repo); //RevWalk r = new RevWalk(m_git.GetRepository()); //var tree = r.ParseTree(commit.Tree.Id); //r.LookupTree( //walk.AddTree(new FileTreeIterator(repo)); //var tree = ParseTree(repo, commit.Tree.Id); walk.AddTree(commit.Tree); var filter = GetGitFriendlyName(fileName); walk.Filter = PathFilterGroup.CreateFromStrings(new string[]{filter}); //walk.EnterSubtree(); while (walk.Next()) { var path = walk.PathString; if (walk.IsSubtree) { walk.EnterSubtree(); continue; } if (path == filter) { var cur = walk.GetObjectId(0); ObjectLoader ol = repo.Open(cur); // //Console.WriteLine(string.Format("Path: {0}{1}", walk.PathString, walk.IsSubtree ? "/" : "")); // //var loader = reader.Open(commit.Tree.Id); var text = ""; using (var stream = ol.OpenStream()) using (var sr = new System.IO.StreamReader(stream)) { text = sr.ReadToEnd(); } return text; } } //walk.Reset(); //reader.Open(); return ""; }
/// <summary> /// Convert the TreeWalk into DiffEntry headers, depending on /// <code>includeTrees</code> /// it will add tree objects into result or not. /// </summary> /// <param name="walk"> /// the TreeWalk to walk through. Must have exactly two trees and /// when /// <code>includeTrees</code> /// parameter is /// <code>true</code> /// it can't /// be recursive. /// </param> /// <param name="includeTrees">include tree object's.</param> /// <returns>headers describing the changed files.</returns> /// <exception cref="System.IO.IOException">the repository cannot be accessed.</exception> /// <exception cref="System.ArgumentException"> /// when /// <code>includeTrees</code> /// is true and given TreeWalk is /// recursive. Or when given TreeWalk doesn't have exactly two /// trees /// </exception> public static IList<NGit.Diff.DiffEntry> Scan(TreeWalk walk, bool includeTrees) { if (walk.TreeCount != 2) { throw new ArgumentException(JGitText.Get().treeWalkMustHaveExactlyTwoTrees); } if (includeTrees && walk.Recursive) { throw new ArgumentException(JGitText.Get().cannotBeRecursiveWhenTreesAreIncluded); } IList<NGit.Diff.DiffEntry> r = new AList<NGit.Diff.DiffEntry>(); MutableObjectId idBuf = new MutableObjectId(); while (walk.Next()) { NGit.Diff.DiffEntry entry = new NGit.Diff.DiffEntry(); walk.GetObjectId(idBuf, 0); entry.oldId = AbbreviatedObjectId.FromObjectId(idBuf); walk.GetObjectId(idBuf, 1); entry.newId = AbbreviatedObjectId.FromObjectId(idBuf); entry.oldMode = walk.GetFileMode(0); entry.newMode = walk.GetFileMode(1); entry.newPath = entry.oldPath = walk.PathString; if (entry.oldMode == FileMode.MISSING) { entry.oldPath = NGit.Diff.DiffEntry.DEV_NULL; entry.changeType = DiffEntry.ChangeType.ADD; r.AddItem(entry); } else { if (entry.newMode == FileMode.MISSING) { entry.newPath = NGit.Diff.DiffEntry.DEV_NULL; entry.changeType = DiffEntry.ChangeType.DELETE; r.AddItem(entry); } else { if (!entry.oldId.Equals(entry.newId)) { entry.changeType = DiffEntry.ChangeType.MODIFY; if (RenameDetector.SameType(entry.oldMode, entry.newMode)) { r.AddItem(entry); } else { Sharpen.Collections.AddAll(r, BreakModify(entry)); } } else { if (entry.oldMode != entry.newMode) { entry.changeType = DiffEntry.ChangeType.MODIFY; r.AddItem(entry); } } } } if (includeTrees && walk.IsSubtree) { walk.EnterSubtree(); } } return r; }
/// <summary> /// Run the diff operation. Until this is called, all lists will be empty /// </summary> /// <returns>true if anything is different between index, tree, and workdir</returns> private void UpdateDirectory(IEnumerable <string> paths, bool recursive) { RevWalk rw = new RevWalk(Repository); ObjectId id = Repository.Resolve(Constants.HEAD); var commit = id != null?rw.ParseCommit(id) : null; TreeWalk treeWalk = new TreeWalk(Repository); treeWalk.Reset(); treeWalk.Recursive = false; if (commit != null) { treeWalk.AddTree(commit.Tree); } else { treeWalk.AddTree(new EmptyTreeIterator()); } DirCache dc = Repository.ReadDirCache(); treeWalk.AddTree(new DirCacheIterator(dc)); FileTreeIterator workTree = new FileTreeIterator(Repository.WorkTree, Repository.FileSystem, WorkingTreeOptions.KEY.Parse(Repository.GetConfig())); treeWalk.AddTree(workTree); List <TreeFilter> filters = new List <TreeFilter> (); filters.Add(new SkipWorkTreeFilter(1)); var pathFilters = paths.Where(p => p != ".").Select(p => PathFilter.Create(p)).ToArray(); if (pathFilters.Length > 1) { filters.Add(OrTreeFilter.Create(pathFilters)); // Use an OR to join all path filters } else if (pathFilters.Length == 1) { filters.Add(pathFilters[0]); } if (filters.Count > 1) { treeWalk.Filter = AndTreeFilter.Create(filters); } else { treeWalk.Filter = filters[0]; } while (treeWalk.Next()) { AbstractTreeIterator treeIterator = treeWalk.GetTree <AbstractTreeIterator>(0); DirCacheIterator dirCacheIterator = treeWalk.GetTree <DirCacheIterator>(1); WorkingTreeIterator workingTreeIterator = treeWalk.GetTree <WorkingTreeIterator>(2); NGit.FileMode fileModeTree = treeWalk.GetFileMode(0); if (treeWalk.IsSubtree) { treeWalk.EnterSubtree(); continue; } int stage = dirCacheIterator != null?dirCacheIterator.GetDirCacheEntry().Stage : 0; if (stage > 1) { continue; } else if (stage == 1) { MergeConflict.Add(dirCacheIterator.EntryPathString); changesExist = true; continue; } if (treeIterator != null) { if (dirCacheIterator != null) { if (!treeIterator.EntryObjectId.Equals(dirCacheIterator.EntryObjectId)) { // in repo, in index, content diff => changed Modified.Add(dirCacheIterator.EntryPathString); changesExist = true; } } else { // in repo, not in index => removed if (!fileModeTree.Equals(NGit.FileMode.TYPE_TREE)) { Removed.Add(treeIterator.EntryPathString); changesExist = true; } } } else { if (dirCacheIterator != null) { // not in repo, in index => added Added.Add(dirCacheIterator.EntryPathString); changesExist = true; } else { // not in repo, not in index => untracked if (workingTreeIterator != null && !workingTreeIterator.IsEntryIgnored()) { Untracked.Add(workingTreeIterator.EntryPathString); changesExist = true; } } } if (dirCacheIterator != null) { if (workingTreeIterator == null) { // in index, not in workdir => missing Missing.Add(dirCacheIterator.EntryPathString); changesExist = true; } else { // Workaround to file time resolution issues long itime = dirCacheIterator.GetDirCacheEntry().LastModified; long ftime = workingTreeIterator.GetEntryLastModified(); if (itime / 1000 != ftime / 1000) { if (!dirCacheIterator.IdEqual(workingTreeIterator)) { // in index, in workdir, content differs => modified Modified.Add(dirCacheIterator.EntryPathString); changesExist = true; } } } } } }
public virtual void TestNoDF_NoGap() { DirCache tree0 = db.ReadDirCache(); DirCache tree1 = db.ReadDirCache(); { DirCacheBuilder b0 = tree0.Builder(); DirCacheBuilder b1 = tree1.Builder(); b0.Add(MakeEntry("a", REGULAR_FILE)); b0.Add(MakeEntry("a.b", EXECUTABLE_FILE)); b1.Add(MakeEntry("a/b", REGULAR_FILE)); b0.Add(MakeEntry("a0b", SYMLINK)); b0.Finish(); b1.Finish(); NUnit.Framework.Assert.AreEqual(3, tree0.GetEntryCount()); NUnit.Framework.Assert.AreEqual(1, tree1.GetEntryCount()); } TreeWalk tw = new TreeWalk(db); tw.AddTree(new DirCacheIterator(tree0)); tw.AddTree(new DirCacheIterator(tree1)); AssertModes("a", REGULAR_FILE, MISSING, tw); AssertModes("a.b", EXECUTABLE_FILE, MISSING, tw); AssertModes("a", MISSING, TREE, tw); tw.EnterSubtree(); AssertModes("a/b", MISSING, REGULAR_FILE, tw); AssertModes("a0b", SYMLINK, MISSING, tw); }
public virtual void TestNoPostOrder() { DirCache tree = db.ReadDirCache(); { DirCacheBuilder b = tree.Builder(); b.Add(MakeFile("a")); b.Add(MakeFile("b/c")); b.Add(MakeFile("b/d")); b.Add(MakeFile("q")); b.Finish(); NUnit.Framework.Assert.AreEqual(4, tree.GetEntryCount()); } TreeWalk tw = new TreeWalk(db); tw.PostOrderTraversal = false; tw.AddTree(new DirCacheIterator(tree)); AssertModes("a", FileMode.REGULAR_FILE, tw); AssertModes("b", FileMode.TREE, tw); NUnit.Framework.Assert.IsTrue(tw.IsSubtree); NUnit.Framework.Assert.IsFalse(tw.IsPostChildren); tw.EnterSubtree(); AssertModes("b/c", FileMode.REGULAR_FILE, tw); AssertModes("b/d", FileMode.REGULAR_FILE, tw); AssertModes("q", FileMode.REGULAR_FILE, tw); }