/// <summary>Represent the state of the index in one String.</summary> /// <remarks> /// Represent the state of the index in one String. This representation is /// useful when writing tests which do assertions on the state of the index. /// By default information about path, mode, stage (if different from 0) is /// included. A bitmask controls which additional info about /// modificationTimes, smudge state and length is included. /// <p> /// The format of the returned string is described with this BNF: /// <pre> /// result = ( "[" path mode stage? time? smudge? length? sha1? content? "]" )* . /// mode = ", mode:" number . /// stage = ", stage:" number . /// time = ", time:t" timestamp-index . /// smudge = "" | ", smudged" . /// length = ", length:" number . /// sha1 = ", sha1:" hex-sha1 . /// content = ", content:" blob-data . /// </pre> /// 'stage' is only presented when the stage is different from 0. All /// reported time stamps are mapped to strings like "t0", "t1", ... "tn". The /// smallest reported time-stamp will be called "t0". This allows to write /// assertions against the string although the concrete value of the time /// stamps is unknown. /// </remarks> /// <param name="repo">the repository the index state should be determined for</param> /// <param name="includedOptions"> /// a bitmask constructed out of the constants /// <see cref="MOD_TIME">MOD_TIME</see> /// , /// <see cref="SMUDGE">SMUDGE</see> /// , /// <see cref="LENGTH">LENGTH</see> /// , /// <see cref="CONTENT_ID">CONTENT_ID</see> /// and /// <see cref="CONTENT">CONTENT</see> /// controlling which info is present in the /// resulting string. /// </param> /// <returns>a string encoding the index state</returns> /// <exception cref="System.InvalidOperationException">System.InvalidOperationException /// </exception> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual string IndexState(Repository repo, int includedOptions) { DirCache dc = repo.ReadDirCache(); StringBuilder sb = new StringBuilder(); TreeSet <long> timeStamps = null; // iterate once over the dircache just to collect all time stamps if (0 != (includedOptions & MOD_TIME)) { timeStamps = new TreeSet <long>(); for (int i = 0; i < dc.GetEntryCount(); ++i) { timeStamps.AddItem(Sharpen.Extensions.ValueOf(dc.GetEntry(i).LastModified)); } } // iterate again, now produce the result string for (int i_1 = 0; i_1 < dc.GetEntryCount(); ++i_1) { DirCacheEntry entry = dc.GetEntry(i_1); sb.Append("[" + entry.PathString + ", mode:" + entry.FileMode); int stage = entry.Stage; if (stage != 0) { sb.Append(", stage:" + stage); } if (0 != (includedOptions & MOD_TIME)) { sb.Append(", time:t" + timeStamps.HeadSet(Sharpen.Extensions.ValueOf(entry.LastModified )).Count); } if (0 != (includedOptions & SMUDGE)) { if (entry.IsSmudged) { sb.Append(", smudged"); } } if (0 != (includedOptions & LENGTH)) { sb.Append(", length:" + Sharpen.Extensions.ToString(entry.Length)); } if (0 != (includedOptions & CONTENT_ID)) { sb.Append(", sha1:" + ObjectId.ToString(entry.GetObjectId())); } if (0 != (includedOptions & CONTENT)) { sb.Append(", content:" + Sharpen.Runtime.GetStringForBytes(db.Open(entry.GetObjectId (), Constants.OBJ_BLOB).GetCachedBytes(), "UTF-8")); } if (0 != (includedOptions & ASSUME_UNCHANGED)) { sb.Append(", assume-unchanged:" + entry.IsAssumeValid.ToString().ToLower()); } sb.Append("]"); } return(sb.ToString()); }
public virtual void TestDF_NoGap() { DirCache tree0 = db.ReadDirCache(); DirCache tree1 = db.ReadDirCache(); { DirCacheBuilder b0 = tree0.Builder(); DirCacheBuilder b1 = tree1.Builder(); b0.Add(CreateEntry("a", REGULAR_FILE)); b0.Add(CreateEntry("a.b", EXECUTABLE_FILE)); b1.Add(CreateEntry("a/b", REGULAR_FILE)); b0.Add(CreateEntry("a0b", SYMLINK)); b0.Finish(); b1.Finish(); NUnit.Framework.Assert.AreEqual(3, tree0.GetEntryCount()); NUnit.Framework.Assert.AreEqual(1, tree1.GetEntryCount()); } NameConflictTreeWalk tw = new NameConflictTreeWalk(db); tw.AddTree(new DirCacheIterator(tree0)); tw.AddTree(new DirCacheIterator(tree1)); AssertModes("a", REGULAR_FILE, TREE, tw); NUnit.Framework.Assert.IsTrue(tw.IsDirectoryFileConflict()); NUnit.Framework.Assert.IsTrue(tw.IsSubtree); tw.EnterSubtree(); AssertModes("a/b", MISSING, REGULAR_FILE, tw); NUnit.Framework.Assert.IsTrue(tw.IsDirectoryFileConflict()); AssertModes("a.b", EXECUTABLE_FILE, MISSING, tw); NUnit.Framework.Assert.IsFalse(tw.IsDirectoryFileConflict()); AssertModes("a0b", SYMLINK, MISSING, tw); NUnit.Framework.Assert.IsFalse(tw.IsDirectoryFileConflict()); }
public virtual void TestAddNonExistingSingleFile() { Git git = new Git(db); DirCache dc = git.Add().AddFilepattern("a.txt").Call(); NUnit.Framework.Assert.AreEqual(0, dc.GetEntryCount()); }
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); }
public virtual void TestReadIndex_LsFiles() { IDictionary<string, DirCacheCGitCompatabilityTest.CGitIndexRecord> ls = ReadLsFiles (); DirCache dc = new DirCache(index, FS.DETECTED); NUnit.Framework.Assert.AreEqual(0, dc.GetEntryCount()); dc.Read(); NUnit.Framework.Assert.AreEqual(ls.Count, dc.GetEntryCount()); { Iterator<DirCacheCGitCompatabilityTest.CGitIndexRecord> rItr = ls.Values.Iterator (); for (int i = 0; rItr.HasNext(); i++) { AssertEqual(rItr.Next(), dc.GetEntry(i)); } } }
/// <exception cref="NGit.Errors.CorruptObjectException"></exception> /// <exception cref="System.IO.IOException"></exception> private void AssertIndex(Dictionary <string, string> i) { string expectedValue; string path; DirCache read = DirCache.Read(db.GetIndexFile(), db.FileSystem); NUnit.Framework.Assert.AreEqual(i.Count, read.GetEntryCount(), "Index has not the right size." ); for (int j = 0; j < read.GetEntryCount(); j++) { path = read.GetEntry(j).PathString; expectedValue = i.Get(path); NUnit.Framework.Assert.IsNotNull(expectedValue, "found unexpected entry for path " + path + " in index"); NUnit.Framework.Assert.IsTrue(Arrays.Equals(db.Open(read.GetEntry(j).GetObjectId( )).GetCachedBytes(), Sharpen.Runtime.GetBytesForString(i.Get(path))), "unexpected content for path " + path + " in index. Expected: <" + expectedValue + ">"); } }
/// <returns>list of files with the flag assume-unchanged</returns> public virtual ICollection <string> GetAssumeUnchanged() { if (assumeUnchanged == null) { HashSet <string> unchanged = new HashSet <string>(); for (int i = 0; i < dirCache.GetEntryCount(); i++) { if (dirCache.GetEntry(i).IsAssumeValid) { unchanged.AddItem(dirCache.GetEntry(i).PathString); } } assumeUnchanged = unchanged; } return(assumeUnchanged); }
public virtual void TestDF_DetectConflict() { DirCache tree0 = db.ReadDirCache(); DirCache tree1 = db.ReadDirCache(); { DirCacheBuilder b0 = tree0.Builder(); DirCacheBuilder b1 = tree1.Builder(); b0.Add(MakeEntry("0", REGULAR_FILE)); b0.Add(MakeEntry("a", REGULAR_FILE)); b1.Add(MakeEntry("0", REGULAR_FILE)); b1.Add(MakeEntry("a.b", REGULAR_FILE)); b1.Add(MakeEntry("a/b", REGULAR_FILE)); b1.Add(MakeEntry("a/c/e", REGULAR_FILE)); b0.Finish(); b1.Finish(); NUnit.Framework.Assert.AreEqual(2, tree0.GetEntryCount()); NUnit.Framework.Assert.AreEqual(4, tree1.GetEntryCount()); } NameConflictTreeWalk tw = new NameConflictTreeWalk(db); tw.AddTree(new DirCacheIterator(tree0)); tw.AddTree(new DirCacheIterator(tree1)); AssertModes("0", REGULAR_FILE, REGULAR_FILE, tw); NUnit.Framework.Assert.IsFalse(tw.IsDirectoryFileConflict()); AssertModes("a", REGULAR_FILE, TREE, tw); NUnit.Framework.Assert.IsTrue(tw.IsSubtree); NUnit.Framework.Assert.IsTrue(tw.IsDirectoryFileConflict()); tw.EnterSubtree(); AssertModes("a/b", MISSING, REGULAR_FILE, tw); NUnit.Framework.Assert.IsTrue(tw.IsDirectoryFileConflict()); AssertModes("a/c", MISSING, TREE, tw); NUnit.Framework.Assert.IsTrue(tw.IsDirectoryFileConflict()); tw.EnterSubtree(); AssertModes("a/c/e", MISSING, REGULAR_FILE, tw); NUnit.Framework.Assert.IsTrue(tw.IsDirectoryFileConflict()); AssertModes("a.b", MISSING, REGULAR_FILE, tw); NUnit.Framework.Assert.IsFalse(tw.IsDirectoryFileConflict()); }
/// <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(); } }
/// <summary>Run the diff operation.</summary> /// <remarks> /// Run the diff operation. Until this is called, all lists will be empty. /// <p> /// The operation may be aborted by the progress monitor. In that event it /// will report what was found before the cancel operation was detected. /// Callers should ignore the result if monitor.isCancelled() is true. If a /// progress monitor is not needed, callers should use /// <see cref="Diff()">Diff()</see> /// instead. Progress reporting is crude and approximate and only intended /// for informing the user. /// </remarks> /// <param name="monitor">for reporting progress, may be null</param> /// <param name="estWorkTreeSize">number or estimated files in the working tree</param> /// <param name="estIndexSize">number of estimated entries in the cache</param> /// <param name="title"></param> /// <returns>if anything is different between index, tree, and workdir</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual bool Diff(ProgressMonitor monitor, int estWorkTreeSize, int estIndexSize , string title) { dirCache = repository.ReadDirCache(); TreeWalk treeWalk = new TreeWalk(repository); treeWalk.Recursive = true; // add the trees (tree, dirchache, workdir) if (tree != null) { treeWalk.AddTree(tree); } else { treeWalk.AddTree(new EmptyTreeIterator()); } treeWalk.AddTree(new DirCacheIterator(dirCache)); treeWalk.AddTree(initialWorkingTreeIterator); ICollection<TreeFilter> filters = new AList<TreeFilter>(4); if (monitor != null) { // Get the maximum size of the work tree and index // and add some (quite arbitrary) if (estIndexSize == 0) { estIndexSize = dirCache.GetEntryCount(); } int total = Math.Max(estIndexSize * 10 / 9, estWorkTreeSize * 10 / 9); monitor.BeginTask(title, total); filters.AddItem(new IndexDiff.ProgressReportingFilter(monitor, total)); } if (filter != null) { filters.AddItem(filter); } filters.AddItem(new SkipWorkTreeFilter(INDEX)); filters.AddItem(new IndexDiffFilter(INDEX, WORKDIR)); treeWalk.Filter = AndTreeFilter.Create(filters); while (treeWalk.Next()) { AbstractTreeIterator treeIterator = treeWalk.GetTree<AbstractTreeIterator>(TREE); DirCacheIterator dirCacheIterator = treeWalk.GetTree<DirCacheIterator>(INDEX); WorkingTreeIterator workingTreeIterator = treeWalk.GetTree<WorkingTreeIterator>(WORKDIR ); if (treeIterator != null) { if (dirCacheIterator != null) { if (!treeIterator.IdEqual(dirCacheIterator) || treeIterator.EntryRawMode != dirCacheIterator .EntryRawMode) { // in repo, in index, content diff => changed changed.AddItem(treeWalk.PathString); } } else { // in repo, not in index => removed removed.AddItem(treeWalk.PathString); if (workingTreeIterator != null) { untracked.AddItem(treeWalk.PathString); } } } else { if (dirCacheIterator != null) { // not in repo, in index => added added.AddItem(treeWalk.PathString); } else { // not in repo, not in index => untracked if (workingTreeIterator != null && !workingTreeIterator.IsEntryIgnored()) { untracked.AddItem(treeWalk.PathString); } } } if (dirCacheIterator != null) { if (workingTreeIterator == null) { // in index, not in workdir => missing missing.AddItem(treeWalk.PathString); } else { if (workingTreeIterator.IsModified(dirCacheIterator.GetDirCacheEntry(), true)) { // in index, in workdir, content differs => modified modified.AddItem(treeWalk.PathString); } } } } // consume the remaining work if (monitor != null) { monitor.EndTask(); } if (added.IsEmpty() && changed.IsEmpty() && removed.IsEmpty() && missing.IsEmpty( ) && modified.IsEmpty() && untracked.IsEmpty()) { return false; } else { return true; } }
/// <summary>Run the diff operation.</summary> /// <remarks> /// Run the diff operation. Until this is called, all lists will be empty. /// <p> /// The operation may be aborted by the progress monitor. In that event it /// will report what was found before the cancel operation was detected. /// Callers should ignore the result if monitor.isCancelled() is true. If a /// progress monitor is not needed, callers should use /// <see cref="Diff()">Diff()</see> /// instead. Progress reporting is crude and approximate and only intended /// for informing the user. /// </remarks> /// <param name="monitor">for reporting progress, may be null</param> /// <param name="estWorkTreeSize">number or estimated files in the working tree</param> /// <param name="estIndexSize">number of estimated entries in the cache</param> /// <param name="title"></param> /// <returns>if anything is different between index, tree, and workdir</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual bool Diff(ProgressMonitor monitor, int estWorkTreeSize, int estIndexSize , string title) { dirCache = repository.ReadDirCache(); TreeWalk treeWalk = new TreeWalk(repository); treeWalk.Recursive = true; // add the trees (tree, dirchache, workdir) if (tree != null) { treeWalk.AddTree(tree); } else { treeWalk.AddTree(new EmptyTreeIterator()); } treeWalk.AddTree(new DirCacheIterator(dirCache)); treeWalk.AddTree(initialWorkingTreeIterator); ICollection <TreeFilter> filters = new AList <TreeFilter>(4); if (monitor != null) { // Get the maximum size of the work tree and index // and add some (quite arbitrary) if (estIndexSize == 0) { estIndexSize = dirCache.GetEntryCount(); } int total = Math.Max(estIndexSize * 10 / 9, estWorkTreeSize * 10 / 9); monitor.BeginTask(title, total); filters.AddItem(new IndexDiff.ProgressReportingFilter(monitor, total)); } if (filter != null) { filters.AddItem(filter); } filters.AddItem(new SkipWorkTreeFilter(INDEX)); filters.AddItem(new IndexDiffFilter(INDEX, WORKDIR)); treeWalk.Filter = AndTreeFilter.Create(filters); while (treeWalk.Next()) { AbstractTreeIterator treeIterator = treeWalk.GetTree <AbstractTreeIterator>(TREE); DirCacheIterator dirCacheIterator = treeWalk.GetTree <DirCacheIterator>(INDEX); WorkingTreeIterator workingTreeIterator = treeWalk.GetTree <WorkingTreeIterator>(WORKDIR ); if (dirCacheIterator != null) { DirCacheEntry dirCacheEntry = dirCacheIterator.GetDirCacheEntry(); if (dirCacheEntry != null && dirCacheEntry.Stage > 0) { conflicts.AddItem(treeWalk.PathString); continue; } } if (treeIterator != null) { if (dirCacheIterator != null) { if (!treeIterator.IdEqual(dirCacheIterator) || treeIterator.EntryRawMode != dirCacheIterator .EntryRawMode) { // in repo, in index, content diff => changed changed.AddItem(treeWalk.PathString); } } else { // in repo, not in index => removed removed.AddItem(treeWalk.PathString); if (workingTreeIterator != null) { untracked.AddItem(treeWalk.PathString); } } } else { if (dirCacheIterator != null) { // not in repo, in index => added added.AddItem(treeWalk.PathString); } else { // not in repo, not in index => untracked if (workingTreeIterator != null && !workingTreeIterator.IsEntryIgnored()) { untracked.AddItem(treeWalk.PathString); } } } if (dirCacheIterator != null) { if (workingTreeIterator == null) { // in index, not in workdir => missing missing.AddItem(treeWalk.PathString); } else { if (workingTreeIterator.IsModified(dirCacheIterator.GetDirCacheEntry(), true)) { // in index, in workdir, content differs => modified modified.AddItem(treeWalk.PathString); } } } } // consume the remaining work if (monitor != null) { monitor.EndTask(); } if (added.IsEmpty() && changed.IsEmpty() && removed.IsEmpty() && missing.IsEmpty( ) && modified.IsEmpty() && untracked.IsEmpty()) { return(false); } else { return(true); } }
public virtual void TestTreeWalk_LsFiles() { Repository db = CreateBareRepository(); IDictionary<string, DirCacheCGitCompatabilityTest.CGitIndexRecord> ls = ReadLsFiles (); DirCache dc = new DirCache(index, db.FileSystem); NUnit.Framework.Assert.AreEqual(0, dc.GetEntryCount()); dc.Read(); NUnit.Framework.Assert.AreEqual(ls.Count, dc.GetEntryCount()); { Iterator<DirCacheCGitCompatabilityTest.CGitIndexRecord> rItr = ls.Values.Iterator (); TreeWalk tw = new TreeWalk(db); tw.Recursive = true; tw.AddTree(new DirCacheIterator(dc)); while (rItr.HasNext()) { DirCacheIterator dcItr; NUnit.Framework.Assert.IsTrue(tw.Next()); dcItr = tw.GetTree<DirCacheIterator>(0); NUnit.Framework.Assert.IsNotNull(dcItr); AssertEqual(rItr.Next(), dcItr.GetDirCacheEntry()); } } }
public virtual void TestReadWriteV3() { FilePath file = PathOf("gitgit.index.v3"); DirCache dc = new DirCache(file, FS.DETECTED); dc.Read(); NUnit.Framework.Assert.AreEqual(10, dc.GetEntryCount()); AssertV3TreeEntry(0, "dir1/file1.txt", false, false, dc); AssertV3TreeEntry(1, "dir2/file2.txt", true, false, dc); AssertV3TreeEntry(2, "dir3/file3.txt", false, false, dc); AssertV3TreeEntry(3, "dir3/file3a.txt", true, false, dc); AssertV3TreeEntry(4, "dir4/file4.txt", true, false, dc); AssertV3TreeEntry(5, "dir4/file4a.txt", false, false, dc); AssertV3TreeEntry(6, "file.txt", true, false, dc); AssertV3TreeEntry(7, "newdir1/newfile1.txt", false, true, dc); AssertV3TreeEntry(8, "newdir1/newfile2.txt", false, true, dc); AssertV3TreeEntry(9, "newfile.txt", false, true, dc); ByteArrayOutputStream bos = new ByteArrayOutputStream(); dc.WriteTo(bos); byte[] indexBytes = bos.ToByteArray(); byte[] expectedBytes = IOUtil.ReadFully(file); CollectionAssert.AreEquivalent(expectedBytes, indexBytes); }
public virtual void TestReadIndex_DirCacheTree() { IDictionary<string, DirCacheCGitCompatabilityTest.CGitIndexRecord> cList = ReadLsFiles (); IDictionary<string, DirCacheCGitCompatabilityTest.CGitLsTreeRecord> cTree = ReadLsTree (); DirCache dc = new DirCache(index, FS.DETECTED); NUnit.Framework.Assert.AreEqual(0, dc.GetEntryCount()); dc.Read(); NUnit.Framework.Assert.AreEqual(cList.Count, dc.GetEntryCount()); DirCacheTree jTree = dc.GetCacheTree(false); NUnit.Framework.Assert.IsNotNull(jTree); NUnit.Framework.Assert.AreEqual(string.Empty, jTree.GetNameString()); NUnit.Framework.Assert.AreEqual(string.Empty, jTree.GetPathString()); NUnit.Framework.Assert.IsTrue(jTree.IsValid()); NUnit.Framework.Assert.AreEqual(ObjectId.FromString("698dd0b8d0c299f080559a1cffc7fe029479a408" ), jTree.GetObjectId()); NUnit.Framework.Assert.AreEqual(cList.Count, jTree.GetEntrySpan()); AList<DirCacheCGitCompatabilityTest.CGitLsTreeRecord> subtrees = new AList<DirCacheCGitCompatabilityTest.CGitLsTreeRecord >(); foreach (DirCacheCGitCompatabilityTest.CGitLsTreeRecord r in cTree.Values) { if (FileMode.TREE.Equals(r.mode)) { subtrees.AddItem(r); } } NUnit.Framework.Assert.AreEqual(subtrees.Count, jTree.GetChildCount()); for (int i = 0; i < jTree.GetChildCount(); i++) { DirCacheTree sj = jTree.GetChild(i); DirCacheCGitCompatabilityTest.CGitLsTreeRecord sc = subtrees[i]; NUnit.Framework.Assert.AreEqual(sc.path, sj.GetNameString()); NUnit.Framework.Assert.AreEqual(sc.path + "/", sj.GetPathString()); NUnit.Framework.Assert.IsTrue(sj.IsValid()); NUnit.Framework.Assert.AreEqual(sc.id, sj.GetObjectId()); } }
public virtual void TestUnsupportedOptionalExtension() { DirCache dc = new DirCache(PathOf("gitgit.index.ZZZZ"), FS.DETECTED); dc.Read(); NUnit.Framework.Assert.AreEqual(1, dc.GetEntryCount()); NUnit.Framework.Assert.AreEqual("A", dc.GetEntry(0).PathString); }
public virtual void TestFindObjects() { DirCache tree0 = DirCache.NewInCore(); DirCacheBuilder b0 = tree0.Builder(); ObjectReader or = db.NewObjectReader(); ObjectInserter oi = db.NewObjectInserter(); DirCacheEntry aDotB = MakeEntry("a.b", EXECUTABLE_FILE); b0.Add(aDotB); DirCacheEntry aSlashB = MakeEntry("a/b", REGULAR_FILE); b0.Add(aSlashB); DirCacheEntry aSlashCSlashD = MakeEntry("a/c/d", REGULAR_FILE); b0.Add(aSlashCSlashD); DirCacheEntry aZeroB = MakeEntry("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(); }