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 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="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(); } } }
/// <summary>Scan head, index and merge tree.</summary> /// <remarks> /// Scan head, index and merge tree. Used during normal checkout or merge /// operations. /// </remarks> /// <exception cref="NGit.Errors.CorruptObjectException">NGit.Errors.CorruptObjectException /// </exception> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual void PreScanTwoTrees() { removed.Clear(); updated.Clear(); conflicts.Clear(); walk = new NameConflictTreeWalk(repo); builder = dc.Builder(); AddTree(walk, headCommitTree); AddTree(walk, mergeCommitTree); walk.AddTree(new DirCacheBuildIterator(builder)); walk.AddTree(workingTree); while (walk.Next()) { ProcessEntry(walk.GetTree<CanonicalTreeParser>(0), walk.GetTree<CanonicalTreeParser >(1), walk.GetTree<DirCacheBuildIterator>(2), walk.GetTree<WorkingTreeIterator>( 3)); if (walk.IsSubtree) { walk.EnterSubtree(); } } }
/// <exception cref="NGit.Errors.CorruptObjectException"></exception> /// <exception cref="System.IO.IOException"></exception> private bool IsModified(string path) { NameConflictTreeWalk tw = new NameConflictTreeWalk(repo); tw.AddTree(new DirCacheIterator(dc)); tw.AddTree(new FileTreeIterator(repo)); tw.Recursive = true; tw.Filter = PathFilter.Create(path); DirCacheIterator dcIt; WorkingTreeIterator wtIt; while (tw.Next()) { dcIt = tw.GetTree<DirCacheIterator>(0); wtIt = tw.GetTree<WorkingTreeIterator>(1); if (dcIt == null || wtIt == null) { return true; } if (wtIt.IsModified(dcIt.GetDirCacheEntry(), true)) { return true; } } return false; }
/// <exception cref="System.InvalidOperationException"></exception> /// <exception cref="System.IO.IOException"></exception> /// <exception cref="System.Exception"></exception> public virtual void TestIterator() { TreeSet<long> modTimes = new TreeSet<long>(); FilePath lastFile = null; for (int i = 0; i < 10; i++) { lastFile = new FilePath(db.WorkTree, "0." + i); FileUtils.CreateNewFile(lastFile); if (i == 5) { FsTick(lastFile); } } modTimes.AddItem(Sharpen.Extensions.ValueOf(FsTick(lastFile))); for (int i_1 = 0; i_1 < 10; i_1++) { lastFile = new FilePath(db.WorkTree, "1." + i_1); FileUtils.CreateNewFile(lastFile); } modTimes.AddItem(Sharpen.Extensions.ValueOf(FsTick(lastFile))); for (int i_2 = 0; i_2 < 10; i_2++) { lastFile = new FilePath(db.WorkTree, "2." + i_2); FileUtils.CreateNewFile(lastFile); if (i_2 % 4 == 0) { FsTick(lastFile); } } FileTreeIteratorWithTimeControl fileIt = new FileTreeIteratorWithTimeControl(db, modTimes); NameConflictTreeWalk tw = new NameConflictTreeWalk(db); tw.AddTree(fileIt); tw.Recursive = true; FileTreeIterator t; long t0 = 0; for (int i_3 = 0; i_3 < 10; i_3++) { NUnit.Framework.Assert.IsTrue(tw.Next()); t = tw.GetTree<FileTreeIterator>(0); if (i_3 == 0) { t0 = t.GetEntryLastModified(); } else { NUnit.Framework.Assert.AreEqual(t0, t.GetEntryLastModified()); } } long t1 = 0; for (int i_4 = 0; i_4 < 10; i_4++) { NUnit.Framework.Assert.IsTrue(tw.Next()); t = tw.GetTree<FileTreeIterator>(0); if (i_4 == 0) { t1 = t.GetEntryLastModified(); NUnit.Framework.Assert.IsTrue(t1 > t0); } else { NUnit.Framework.Assert.AreEqual(t1, t.GetEntryLastModified()); } } long t2 = 0; for (int i_5 = 0; i_5 < 10; i_5++) { NUnit.Framework.Assert.IsTrue(tw.Next()); t = tw.GetTree<FileTreeIterator>(0); if (i_5 == 0) { t2 = t.GetEntryLastModified(); NUnit.Framework.Assert.IsTrue(t2 > t1); } else { NUnit.Framework.Assert.AreEqual(t2, t.GetEntryLastModified()); } } }
public virtual void TestDF_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()); } 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 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()); }
public static void MergeTest(EngineContext engineContext) { // TODO: Currently hardcoded var db = new FileRepository(new FilePath(@"C:\DEV\hotei_scene", Constants.DOT_GIT)); var git = new Git(db); var tree1Ref = db.GetRef("test"); var tree2Ref = db.GetRef(Constants.HEAD); var tree1CommitId = tree1Ref.GetObjectId(); var tree2CommitId = tree2Ref.GetObjectId(); // Merge tree1 into current tree var mergeResult = git.Merge().Include(tree1CommitId).Call(); if (mergeResult.GetMergeStatus() == MergeStatus.CONFLICTING) { foreach (var conflict in mergeResult.GetConflicts()) { if (conflict.Key.EndsWith(".hotei")) { // Search base tree (common ancestor), if any var walk = new RevWalk(db); walk.SetRevFilter(RevFilter.MERGE_BASE); walk.MarkStart(walk.ParseCommit(tree1CommitId)); walk.MarkStart(walk.ParseCommit(tree2CommitId)); var baseTree = walk.Next(); var tw = new NameConflictTreeWalk(db); tw.AddTree(new RevWalk(db).ParseTree(tree1CommitId).ToObjectId()); tw.AddTree(new RevWalk(db).ParseTree(tree2CommitId).ToObjectId()); if (baseTree != null) tw.AddTree(new RevWalk(db).ParseTree(baseTree.ToObjectId()).ToObjectId()); tw.Filter = PathFilter.Create(conflict.Key); // Should be only one iteration while (tw.Next()) { var tree0 = baseTree != null ? tw.GetTree<AbstractTreeIterator>(2) : null; var tree1 = tw.GetTree<AbstractTreeIterator>(0); var tree2 = tw.GetTree<AbstractTreeIterator>(1); // Get contents of every versions for the 3-way merge var data0 = baseTree != null ? LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree0.EntryObjectId).GetBytes())) : null; var data1 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree1.EntryObjectId).GetBytes())); var data2 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree2.EntryObjectId).GetBytes())); // Perform 3-way merge var entities = new List<EntityDefinition>(); ThreeWayMergeOrdered.Merge(entities, data0, data1, data2, x => x.Guid, (x, y) => x == y, ResolveEntityConflicts); // Save new merged file var fileStream = new FileStream(new FilePath(db.WorkTree, conflict.Key), FileMode.Create, FileAccess.Write); var stream = new BinarySerializationWriter(fileStream); stream.Context.Serializer = Serializer; stream.SerializeClass(null, ref entities, ArchiveMode.Serialize); fileStream.Close(); // TODO: Check if all conflicts are really resolved // Add resolved file for merge commit git.Add().AddFilepattern(conflict.Key).Call(); } } } } }
protected internal InCoreMerger(Repository local) : base(local) { tw = new NameConflictTreeWalk(reader); cache = DirCache.NewInCore(); }