public virtual void TestTrivialTwoWay_concurrentSubtreeChange() { DirCache treeB = db.ReadDirCache(); DirCache treeO = db.ReadDirCache(); DirCache treeT = db.ReadDirCache(); { DirCacheBuilder b = treeB.Builder(); DirCacheBuilder o = treeO.Builder(); DirCacheBuilder t = treeT.Builder(); b.Add(MakeEntry("d/o", FileMode.REGULAR_FILE)); b.Add(MakeEntry("d/t", FileMode.REGULAR_FILE)); o.Add(MakeEntry("d/o", FileMode.REGULAR_FILE, "o !")); o.Add(MakeEntry("d/t", FileMode.REGULAR_FILE)); t.Add(MakeEntry("d/o", FileMode.REGULAR_FILE)); t.Add(MakeEntry("d/t", FileMode.REGULAR_FILE, "t !")); b.Finish(); o.Finish(); t.Finish(); } ObjectInserter ow = db.NewObjectInserter(); ObjectId b_1 = Commit(ow, treeB, new ObjectId[] { }); ObjectId o_1 = Commit(ow, treeO, new ObjectId[] { b_1 }); ObjectId t_1 = Commit(ow, treeT, new ObjectId[] { b_1 }); Merger ourMerger = ((ThreeWayMerger)MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.NewMerger (db)); bool merge = ourMerger.Merge(new ObjectId[] { o_1, t_1 }); NUnit.Framework.Assert.IsTrue(merge); TreeWalk tw = new TreeWalk(db); tw.Recursive = true; tw.Reset(ourMerger.GetResultTreeId()); NUnit.Framework.Assert.IsTrue(tw.Next()); NUnit.Framework.Assert.AreEqual("d/o", tw.PathString); AssertCorrectId(treeO, tw); NUnit.Framework.Assert.IsTrue(tw.Next()); NUnit.Framework.Assert.AreEqual("d/t", tw.PathString); AssertCorrectId(treeT, tw); NUnit.Framework.Assert.IsFalse(tw.Next()); }
public virtual void TestWithPostOrder_NoEnterSubtree() { 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 = true; 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); AssertModes("q", FileMode.REGULAR_FILE, tw); }
public virtual void TestNonRecursiveFiltering() { ObjectInserter odi = db.NewObjectInserter(); ObjectId aSth = odi.Insert(Constants.OBJ_BLOB, Sharpen.Runtime.GetBytesForString( "a.sth")); ObjectId aTxt = odi.Insert(Constants.OBJ_BLOB, Sharpen.Runtime.GetBytesForString( "a.txt")); DirCache dc = db.ReadDirCache(); DirCacheBuilder builder = dc.Builder(); DirCacheEntry aSthEntry = new DirCacheEntry("a.sth"); aSthEntry.FileMode = FileMode.REGULAR_FILE; aSthEntry.SetObjectId(aSth); DirCacheEntry aTxtEntry = new DirCacheEntry("a.txt"); aTxtEntry.FileMode = FileMode.REGULAR_FILE; aTxtEntry.SetObjectId(aTxt); builder.Add(aSthEntry); builder.Add(aTxtEntry); builder.Finish(); ObjectId treeId = dc.WriteTree(odi); odi.Flush(); TreeWalk tw = new TreeWalk(db); tw.Filter = PathSuffixFilter.Create(".txt"); tw.AddTree(treeId); IList <string> paths = new List <string>(); while (tw.Next()) { paths.AddItem(tw.PathString); } IList <string> expected = new List <string>(); expected.AddItem("a.txt"); NUnit.Framework.Assert.AreEqual(expected, paths); }
public virtual void TestDF_DetectConflict() { DirCache tree0 = db.ReadDirCache(); DirCache tree1 = db.ReadDirCache(); { DirCacheBuilder b0 = tree0.Builder(); DirCacheBuilder b1 = tree1.Builder(); b0.Add(CreateEntry("0", REGULAR_FILE)); b0.Add(CreateEntry("a", REGULAR_FILE)); b1.Add(CreateEntry("0", REGULAR_FILE)); b1.Add(CreateEntry("a.b", REGULAR_FILE)); b1.Add(CreateEntry("a/b", REGULAR_FILE)); b1.Add(CreateEntry("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="System.IO.IOException"></exception> protected internal override bool MergeImpl() { tw.AddTree(MergeBase()); tw.AddTree(sourceTrees[0]); tw.AddTree(sourceTrees[1]); bool hasConflict = false; builder = cache.Builder(); while (tw.Next()) { int modeO = tw.GetRawMode(T_OURS); int modeT = tw.GetRawMode(T_THEIRS); if (modeO == modeT && tw.IdEqual(T_OURS, T_THEIRS)) { Add(T_OURS, DirCacheEntry.STAGE_0); continue; } int modeB = tw.GetRawMode(T_BASE); if (modeB == modeO && tw.IdEqual(T_BASE, T_OURS)) { Add(T_THEIRS, DirCacheEntry.STAGE_0); } else { if (modeB == modeT && tw.IdEqual(T_BASE, T_THEIRS)) { Add(T_OURS, DirCacheEntry.STAGE_0); } else { if (NonTree(modeB)) { Add(T_BASE, DirCacheEntry.STAGE_1); hasConflict = true; } if (NonTree(modeO)) { Add(T_OURS, DirCacheEntry.STAGE_2); hasConflict = true; } if (NonTree(modeT)) { Add(T_THEIRS, DirCacheEntry.STAGE_3); hasConflict = true; } if (tw.IsSubtree) { tw.EnterSubtree(); } } } } builder.Finish(); builder = null; if (hasConflict) { return(false); } try { ObjectInserter odi = GetObjectInserter(); resultTree = cache.WriteTree(odi); odi.Flush(); return(true); } catch (UnmergedPathException) { resultTree = null; return(false); } }
/// <exception cref="System.IO.IOException"></exception> private DirCache CreateTemporaryIndex(ObjectId headId, DirCache index) { ObjectInserter inserter = null; // get DirCacheEditor to modify the index if required DirCacheEditor dcEditor = index.Editor(); // get DirCacheBuilder for newly created in-core index to build a // temporary index for this commit DirCache inCoreIndex = DirCache.NewInCore(); DirCacheBuilder dcBuilder = inCoreIndex.Builder(); onlyProcessed = new bool[only.Count]; bool emptyCommit = true; TreeWalk treeWalk = new TreeWalk(repo); int dcIdx = treeWalk.AddTree(new DirCacheIterator(index)); int fIdx = treeWalk.AddTree(new FileTreeIterator(repo)); int hIdx = -1; if (headId != null) { hIdx = treeWalk.AddTree(new RevWalk(repo).ParseTree(headId)); } treeWalk.Recursive = true; while (treeWalk.Next()) { string path = treeWalk.PathString; // check if current entry's path matches a specified path int pos = LookupOnly(path); CanonicalTreeParser hTree = null; if (hIdx != -1) { hTree = treeWalk.GetTree <CanonicalTreeParser>(hIdx); } if (pos >= 0) { // include entry in commit DirCacheIterator dcTree = treeWalk.GetTree <DirCacheIterator>(dcIdx); FileTreeIterator fTree = treeWalk.GetTree <FileTreeIterator>(fIdx); // check if entry refers to a tracked file bool tracked = dcTree != null || hTree != null; if (!tracked) { break; } if (fTree != null) { // create a new DirCacheEntry with data retrieved from disk DirCacheEntry dcEntry = new DirCacheEntry(path); long entryLength = fTree.GetEntryLength(); dcEntry.SetLength(entryLength); dcEntry.LastModified = fTree.GetEntryLastModified(); dcEntry.FileMode = fTree.GetIndexFileMode(dcTree); bool objectExists = (dcTree != null && fTree.IdEqual(dcTree)) || (hTree != null && fTree.IdEqual(hTree)); if (objectExists) { dcEntry.SetObjectId(fTree.EntryObjectId); } else { if (FileMode.GITLINK.Equals(dcEntry.FileMode)) { dcEntry.SetObjectId(fTree.EntryObjectId); } else { // insert object if (inserter == null) { inserter = repo.NewObjectInserter(); } long contentLength = fTree.GetEntryContentLength(); InputStream inputStream = fTree.OpenEntryStream(); try { dcEntry.SetObjectId(inserter.Insert(Constants.OBJ_BLOB, contentLength, inputStream )); } finally { inputStream.Close(); } } } // update index dcEditor.Add(new _PathEdit_375(dcEntry, path)); // add to temporary in-core index dcBuilder.Add(dcEntry); if (emptyCommit && (hTree == null || !hTree.IdEqual(fTree) || hTree.EntryRawMode != fTree.EntryRawMode)) { // this is a change emptyCommit = false; } } else { // if no file exists on disk, remove entry from index and // don't add it to temporary in-core index dcEditor.Add(new DirCacheEditor.DeletePath(path)); if (emptyCommit && hTree != null) { // this is a change emptyCommit = false; } } // keep track of processed path onlyProcessed[pos] = true; } else { // add entries from HEAD for all other paths if (hTree != null) { // create a new DirCacheEntry with data retrieved from HEAD DirCacheEntry dcEntry = new DirCacheEntry(path); dcEntry.SetObjectId(hTree.EntryObjectId); dcEntry.FileMode = hTree.EntryFileMode; // add to temporary in-core index dcBuilder.Add(dcEntry); } } } // there must be no unprocessed paths left at this point; otherwise an // untracked or unknown path has been specified for (int i = 0; i < onlyProcessed.Length; i++) { if (!onlyProcessed[i]) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().entryNotFoundByPath , only[i])); } } // there must be at least one change if (emptyCommit) { throw new JGitInternalException(JGitText.Get().emptyCommit); } // update index dcEditor.Commit(); // finish temporary in-core index used for this commit dcBuilder.Finish(); return(inCoreIndex); }
/// <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(); } } }
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(); } }
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(); }