Example #1
0
        public virtual void TestExecutableRetention()
        {
            StoredConfig config = ((FileBasedConfig)db.GetConfig());

            config.SetBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_FILEMODE
                              , true);
            config.Save();
            FS     executableFs = new _FS_87();
            Git    git          = Git.Open(db.Directory, executableFs);
            string path         = "a.txt";

            WriteTrashFile(path, "content");
            git.Add().AddFilepattern(path).Call();
            RevCommit commit1 = git.Commit().SetMessage("commit").Call();
            TreeWalk  walk    = TreeWalk.ForPath(db, path, commit1.Tree);

            NUnit.Framework.Assert.IsNotNull(walk);
            NUnit.Framework.Assert.AreEqual(FileMode.EXECUTABLE_FILE, walk.GetFileMode(0));
            FS nonExecutableFs = new _FS_132();

            config = ((FileBasedConfig)db.GetConfig());
            config.SetBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_FILEMODE
                              , false);
            config.Save();
            Git git2 = Git.Open(db.Directory, nonExecutableFs);

            WriteTrashFile(path, "content2");
            RevCommit commit2 = git2.Commit().SetOnly(path).SetMessage("commit2").Call();

            walk = TreeWalk.ForPath(db, path, commit2.Tree);
            NUnit.Framework.Assert.IsNotNull(walk);
            NUnit.Framework.Assert.AreEqual(FileMode.EXECUTABLE_FILE, walk.GetFileMode(0));
        }
Example #2
0
        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();
            }
        }
Example #3
0
        public virtual void TestSingleSubtree_NoRecursion()
        {
            DirCache dc = DirCache.NewInCore();

            string[]        paths = new string[] { "a.", "a/b", "a/c", "a/d", "a0b" };
            DirCacheEntry[] ents  = new DirCacheEntry[paths.Length];
            for (int i = 0; i < paths.Length; i++)
            {
                ents[i]          = new DirCacheEntry(paths[i]);
                ents[i].FileMode = FileMode.REGULAR_FILE;
            }
            DirCacheBuilder b = dc.Builder();

            for (int i_1 = 0; i_1 < ents.Length; i_1++)
            {
                b.Add(ents[i_1]);
            }
            b.Finish();
            string[]   expPaths = new string[] { "a.", "a", "a0b" };
            FileMode[] expModes = new FileMode[] { FileMode.REGULAR_FILE, FileMode.TREE, FileMode
                                                   .REGULAR_FILE };
            int[]            expPos = new int[] { 0, -1, 4 };
            DirCacheIterator i_2    = new DirCacheIterator(dc);
            TreeWalk         tw     = new TreeWalk(db);

            tw.AddTree(i_2);
            tw.Recursive = false;
            int pathIdx = 0;

            while (tw.Next())
            {
                NUnit.Framework.Assert.AreSame(i_2, tw.GetTree <DirCacheIterator>(0));
                NUnit.Framework.Assert.AreEqual(expModes[pathIdx].GetBits(), tw.GetRawMode(0));
                NUnit.Framework.Assert.AreSame(expModes[pathIdx], tw.GetFileMode(0));
                NUnit.Framework.Assert.AreEqual(expPaths[pathIdx], tw.PathString);
                if (expPos[pathIdx] >= 0)
                {
                    NUnit.Framework.Assert.AreEqual(expPos[pathIdx], i_2.ptr);
                    NUnit.Framework.Assert.AreSame(ents[expPos[pathIdx]], i_2.GetDirCacheEntry());
                }
                else
                {
                    NUnit.Framework.Assert.AreSame(FileMode.TREE, tw.GetFileMode(0));
                }
                pathIdx++;
            }
            NUnit.Framework.Assert.AreEqual(expPaths.Length, pathIdx);
        }
Example #4
0
        // reduce the visibility of the default constructor
        /// <summary>Convert the TreeWalk into DiffEntry headers.</summary>
        /// <remarks>Convert the TreeWalk into DiffEntry headers.</remarks>
        /// <param name="walk">the TreeWalk to walk through. Must have exactly two trees.</param>
        /// <returns>headers describing the changed files.</returns>
        /// <exception cref="System.IO.IOException">the repository cannot be accessed.</exception>
        public static IList <NGit.Diff.DiffEntry> Scan(TreeWalk walk)
        {
            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
                    {
                        entry.changeType = DiffEntry.ChangeType.MODIFY;
                        if (RenameDetector.SameType(entry.oldMode, entry.newMode))
                        {
                            r.AddItem(entry);
                        }
                        else
                        {
                            Sharpen.Collections.AddAll(r, BreakModify(entry));
                        }
                    }
                }
            }
            return(r);
        }
Example #5
0
        public virtual void TestRemovedSubtree()
        {
            FilePath path = JGitTestUtil.GetTestResourceFile("dircache.testRemovedSubtree");
            DirCache dc   = DirCache.Read(path, FS.DETECTED);

            NUnit.Framework.Assert.AreEqual(2, dc.GetEntryCount());
            TreeWalk tw = new TreeWalk(db);

            tw.Recursive = true;
            tw.AddTree(new DirCacheIterator(dc));
            NUnit.Framework.Assert.IsTrue(tw.Next());
            NUnit.Framework.Assert.AreEqual("a/a", tw.PathString);
            NUnit.Framework.Assert.AreSame(FileMode.REGULAR_FILE, tw.GetFileMode(0));
            NUnit.Framework.Assert.IsTrue(tw.Next());
            NUnit.Framework.Assert.AreEqual("q", tw.PathString);
            NUnit.Framework.Assert.AreSame(FileMode.REGULAR_FILE, tw.GetFileMode(0));
            NUnit.Framework.Assert.IsFalse(tw.Next());
        }
Example #6
0
        private DirCacheEntry ToEntry(int stage, TreeWalk tw)
        {
            DirCacheEntry        e = new DirCacheEntry(tw.RawPath, stage);
            AbstractTreeIterator i;

            i          = tw.GetTree <AbstractTreeIterator>(0);
            e.FileMode = tw.GetFileMode(0);
            e.SetObjectIdFromRaw(i.IdBuffer, i.IdOffset);
            return(e);
        }
Example #7
0
 /// <summary>Advance to next submodule in the index tree.</summary>
 /// <remarks>
 /// Advance to next submodule in the index tree.
 /// The object id and path of the next entry can be obtained by calling
 /// <see cref="GetObjectId()">GetObjectId()</see>
 /// and
 /// <see cref="GetPath()">GetPath()</see>
 /// .
 /// </remarks>
 /// <returns>true if entry found, false otherwise</returns>
 /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
 public virtual bool Next()
 {
     while (walk.Next())
     {
         if (FileMode.GITLINK != walk.GetFileMode(0))
         {
             continue;
         }
         path = walk.PathString;
         return(true);
     }
     path = null;
     return(false);
 }
Example #8
0
        /// <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();
            }
        }
Example #9
0
        /// <summary>Checkout paths into index and working directory</summary>
        /// <returns>this instance</returns>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException
        ///     </exception>
        protected internal virtual NGit.Api.CheckoutCommand CheckoutPaths()
        {
            RevWalk  revWalk = new RevWalk(repo);
            DirCache dc      = repo.LockDirCache();

            try
            {
                DirCacheEditor editor    = dc.Editor();
                TreeWalk       startWalk = new TreeWalk(revWalk.GetObjectReader());
                startWalk.Recursive = true;
                if (!checkoutAllPaths)
                {
                    startWalk.Filter = PathFilterGroup.CreateFromStrings(paths);
                }
                bool checkoutIndex = startCommit == null && startPoint == null;
                if (!checkoutIndex)
                {
                    startWalk.AddTree(revWalk.ParseCommit(GetStartPoint()).Tree);
                }
                else
                {
                    startWalk.AddTree(new DirCacheIterator(dc));
                }
                FilePath     workTree = repo.WorkTree;
                ObjectReader r        = repo.ObjectDatabase.NewReader();
                try
                {
                    while (startWalk.Next())
                    {
                        ObjectId blobId = startWalk.GetObjectId(0);
                        FileMode mode   = startWalk.GetFileMode(0);
                        editor.Add(new _PathEdit_349(this, checkoutIndex, blobId, mode, workTree, r, startWalk
                                                     .PathString));
                    }
                    editor.Commit();
                }
                finally
                {
                    startWalk.Release();
                    r.Release();
                }
            }
            finally
            {
                dc.Unlock();
                revWalk.Release();
            }
            return(this);
        }
Example #10
0
        /// <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);
        }
Example #11
0
        public virtual void TestPathFilterGroup_DoesNotSkipTail()
        {
            DirCache dc   = db.ReadDirCache();
            FileMode mode = FileMode.REGULAR_FILE;

            string[]        paths = new string[] { "a.", "a/b", "a/c", "a/d", "a0b" };
            DirCacheEntry[] ents  = new DirCacheEntry[paths.Length];
            for (int i = 0; i < paths.Length; i++)
            {
                ents[i]          = new DirCacheEntry(paths[i]);
                ents[i].FileMode = mode;
            }
            {
                DirCacheBuilder b = dc.Builder();
                for (int i_1 = 0; i_1 < ents.Length; i_1++)
                {
                    b.Add(ents[i_1]);
                }
                b.Finish();
            }
            int             expIdx = 2;
            DirCacheBuilder b_1    = dc.Builder();
            TreeWalk        tw     = new TreeWalk(db);

            tw.AddTree(new DirCacheBuildIterator(b_1));
            tw.Recursive = true;
            tw.Filter    = PathFilterGroup.CreateFromStrings(Collections.Singleton(paths[expIdx]
                                                                                   ));
            NUnit.Framework.Assert.IsTrue(tw.Next(), "found " + paths[expIdx]);
            DirCacheIterator c = tw.GetTree <DirCacheIterator>(0);

            NUnit.Framework.Assert.IsNotNull(c);
            NUnit.Framework.Assert.AreEqual(expIdx, c.ptr);
            NUnit.Framework.Assert.AreSame(ents[expIdx], c.GetDirCacheEntry());
            NUnit.Framework.Assert.AreEqual(paths[expIdx], tw.PathString);
            NUnit.Framework.Assert.AreEqual(mode.GetBits(), tw.GetRawMode(0));
            NUnit.Framework.Assert.AreSame(mode, tw.GetFileMode(0));
            b_1.Add(c.GetDirCacheEntry());
            NUnit.Framework.Assert.IsFalse(tw.Next(), "no more entries");
            b_1.Finish();
            NUnit.Framework.Assert.AreEqual(ents.Length, dc.GetEntryCount());
            for (int i_2 = 0; i_2 < ents.Length; i_2++)
            {
                NUnit.Framework.Assert.AreSame(ents[i_2], dc.GetEntry(i_2));
            }
        }
Example #12
0
 /// <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);
 }
Example #13
0
        public virtual void TestTwoLevelSubtree_FilterPath()
        {
            DirCache dc   = DirCache.NewInCore();
            FileMode mode = FileMode.REGULAR_FILE;

            string[]        paths = new string[] { "a.", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
            DirCacheEntry[] ents  = new DirCacheEntry[paths.Length];
            for (int i = 0; i < paths.Length; i++)
            {
                ents[i]          = new DirCacheEntry(paths[i]);
                ents[i].FileMode = mode;
            }
            DirCacheBuilder b = dc.Builder();

            for (int i_1 = 0; i_1 < ents.Length; i_1++)
            {
                b.Add(ents[i_1]);
            }
            b.Finish();
            TreeWalk tw = new TreeWalk(db);

            for (int victimIdx = 0; victimIdx < paths.Length; victimIdx++)
            {
                tw.Reset();
                tw.AddTree(new DirCacheIterator(dc));
                tw.Filter = PathFilterGroup.CreateFromStrings(Collections.Singleton(paths[victimIdx
                                                                                    ]));
                tw.Recursive = tw.Filter.ShouldBeRecursive();
                NUnit.Framework.Assert.IsTrue(tw.Next());
                DirCacheIterator c = tw.GetTree <DirCacheIterator>(0);
                NUnit.Framework.Assert.IsNotNull(c);
                NUnit.Framework.Assert.AreEqual(victimIdx, c.ptr);
                NUnit.Framework.Assert.AreSame(ents[victimIdx], c.GetDirCacheEntry());
                NUnit.Framework.Assert.AreEqual(paths[victimIdx], tw.PathString);
                NUnit.Framework.Assert.AreEqual(mode.GetBits(), tw.GetRawMode(0));
                NUnit.Framework.Assert.AreSame(mode, tw.GetFileMode(0));
                NUnit.Framework.Assert.IsFalse(tw.Next());
            }
        }
Example #14
0
        public virtual void TestSingleSubtree_Recursive()
        {
            DirCache dc   = DirCache.NewInCore();
            FileMode mode = FileMode.REGULAR_FILE;

            string[]        paths = new string[] { "a.", "a/b", "a/c", "a/d", "a0b" };
            DirCacheEntry[] ents  = new DirCacheEntry[paths.Length];
            for (int i = 0; i < paths.Length; i++)
            {
                ents[i]          = new DirCacheEntry(paths[i]);
                ents[i].FileMode = mode;
            }
            DirCacheBuilder b = dc.Builder();

            for (int i_1 = 0; i_1 < ents.Length; i_1++)
            {
                b.Add(ents[i_1]);
            }
            b.Finish();
            DirCacheIterator i_2 = new DirCacheIterator(dc);
            TreeWalk         tw  = new TreeWalk(db);

            tw.AddTree(i_2);
            tw.Recursive = true;
            int pathIdx = 0;

            while (tw.Next())
            {
                DirCacheIterator c = tw.GetTree <DirCacheIterator>(0);
                NUnit.Framework.Assert.IsNotNull(c);
                NUnit.Framework.Assert.AreEqual(pathIdx, c.ptr);
                NUnit.Framework.Assert.AreSame(ents[pathIdx], c.GetDirCacheEntry());
                NUnit.Framework.Assert.AreEqual(paths[pathIdx], tw.PathString);
                NUnit.Framework.Assert.AreEqual(mode.GetBits(), tw.GetRawMode(0));
                NUnit.Framework.Assert.AreSame(mode, tw.GetFileMode(0));
                pathIdx++;
            }
            NUnit.Framework.Assert.AreEqual(paths.Length, pathIdx);
        }
Example #15
0
        public virtual void TestNoSubtree_WithTreeWalk()
        {
            DirCache dc = DirCache.NewInCore();

            string[]        paths = new string[] { "a.", "a0b" };
            FileMode[]      modes = new FileMode[] { FileMode.EXECUTABLE_FILE, FileMode.GITLINK };
            DirCacheEntry[] ents  = new DirCacheEntry[paths.Length];
            for (int i = 0; i < paths.Length; i++)
            {
                ents[i]          = new DirCacheEntry(paths[i]);
                ents[i].FileMode = modes[i];
            }
            DirCacheBuilder b = dc.Builder();

            for (int i_1 = 0; i_1 < ents.Length; i_1++)
            {
                b.Add(ents[i_1]);
            }
            b.Finish();
            DirCacheIterator i_2 = new DirCacheIterator(dc);
            TreeWalk         tw  = new TreeWalk(db);

            tw.AddTree(i_2);
            int pathIdx = 0;

            while (tw.Next())
            {
                NUnit.Framework.Assert.AreSame(i_2, tw.GetTree <DirCacheIterator>(0));
                NUnit.Framework.Assert.AreEqual(pathIdx, i_2.ptr);
                NUnit.Framework.Assert.AreSame(ents[pathIdx], i_2.GetDirCacheEntry());
                NUnit.Framework.Assert.AreEqual(paths[pathIdx], tw.PathString);
                NUnit.Framework.Assert.AreEqual(modes[pathIdx].GetBits(), tw.GetRawMode(0));
                NUnit.Framework.Assert.AreSame(modes[pathIdx], tw.GetFileMode(0));
                pathIdx++;
            }
            NUnit.Framework.Assert.AreEqual(paths.Length, pathIdx);
        }
        /// <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);
        }
Example #17
0
		// reduce the visibility of the default constructor
		/// <summary>Convert the TreeWalk into DiffEntry headers.</summary>
		/// <remarks>Convert the TreeWalk into DiffEntry headers.</remarks>
		/// <param name="walk">the TreeWalk to walk through. Must have exactly two trees.</param>
		/// <returns>headers describing the changed files.</returns>
		/// <exception cref="System.IO.IOException">the repository cannot be accessed.</exception>
		public static IList<NGit.Diff.DiffEntry> Scan(TreeWalk walk)
		{
			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
					{
						entry.changeType = DiffEntry.ChangeType.MODIFY;
						if (RenameDetector.SameType(entry.oldMode, entry.newMode))
						{
							r.AddItem(entry);
						}
						else
						{
							Sharpen.Collections.AddAll(r, BreakModify(entry));
						}
					}
				}
			}
			return r;
		}
Example #18
0
		private DirCacheEntry ToEntry(int stage, TreeWalk tw)
		{
			DirCacheEntry e = new DirCacheEntry(tw.RawPath, stage);
			AbstractTreeIterator i;
			i = tw.GetTree<AbstractTreeIterator>(0);
			e.FileMode = tw.GetFileMode(0);
			e.SetObjectIdFromRaw(i.IdBuffer, i.IdOffset);
			return e;
		}
Example #19
0
		public virtual void TestRemovedSubtree()
		{
			FilePath path = JGitTestUtil.GetTestResourceFile("dircache.testRemovedSubtree");
			DirCache dc = DirCache.Read(path, FS.DETECTED);
			NUnit.Framework.Assert.AreEqual(2, dc.GetEntryCount());
			TreeWalk tw = new TreeWalk(db);
			tw.Recursive = true;
			tw.AddTree(new DirCacheIterator(dc));
			NUnit.Framework.Assert.IsTrue(tw.Next());
			NUnit.Framework.Assert.AreEqual("a/a", tw.PathString);
			NUnit.Framework.Assert.AreSame(FileMode.REGULAR_FILE, tw.GetFileMode(0));
			NUnit.Framework.Assert.IsTrue(tw.Next());
			NUnit.Framework.Assert.AreEqual("q", tw.PathString);
			NUnit.Framework.Assert.AreSame(FileMode.REGULAR_FILE, tw.GetFileMode(0));
			NUnit.Framework.Assert.IsFalse(tw.Next());
		}
Example #20
0
		static IEnumerable<Change> CalculateCommitDiff (NGit.Repository repo, TreeWalk walk, RevCommit[] commits)
		{
			while (walk.Next ()) {
				int m0 = walk.GetRawMode (0);
				if (walk.TreeCount == 2) {
					int m1 = walk.GetRawMode (1);
					var change = new Change { ReferenceCommit = commits[0], ComparedCommit = commits[1], ReferencePermissions = walk.GetFileMode (0).GetBits (), ComparedPermissions = walk.GetFileMode (1).GetBits (), Name = walk.NameString, Path = walk.PathString };
					if (m0 != 0 && m1 == 0) {
						change.ChangeType = ChangeType.Added;
						change.ComparedObject = walk.GetObjectId (0);
					} else if (m0 == 0 && m1 != 0) {
						change.ChangeType = ChangeType.Deleted;
						change.ReferenceObject = walk.GetObjectId (0);
					} else if (m0 != m1 && walk.IdEqual (0, 1)) {
						change.ChangeType = ChangeType.TypeChanged;
						change.ReferenceObject = walk.GetObjectId (0);
						change.ComparedObject = walk.GetObjectId (1);
					} else {
						change.ChangeType = ChangeType.Modified;
						change.ReferenceObject = walk.GetObjectId (0);
						change.ComparedObject = walk.GetObjectId (1);
					}
					yield return change;
				} else {
					var raw_modes = new int[walk.TreeCount - 1];
					for (int i = 0; i < walk.TreeCount - 1; i++)
						raw_modes[i] = walk.GetRawMode (i + 1);
					//ComparedCommit = compared,
					var change = new Change { ReferenceCommit = commits[0], Name = walk.NameString, Path = walk.PathString };
					if (m0 != 0 && raw_modes.All (m1 => m1 == 0)) {
						change.ChangeType = ChangeType.Added;
						change.ComparedObject = walk.GetObjectId (0);
						yield return change;
					} else if (m0 == 0 && raw_modes.Any (m1 => m1 != 0)) {
						change.ChangeType = ChangeType.Deleted;
						yield return change;
					// TODO: not sure if this condition suffices in some special cases.
					} else if (raw_modes.Select ((m1, i) => new { Mode = m1, Index = i + 1 }).All (x => !walk.IdEqual (0, x.Index))) {
						change.ChangeType = ChangeType.Modified;
						change.ReferenceObject = walk.GetObjectId (0);
						yield return change;
					} else if (raw_modes.Select ((m1, i) => new { Mode = m1, Index = i + 1 }).Any (x => m0 != x.Mode && walk.IdEqual (0, x.Index))) {
						change.ChangeType = ChangeType.TypeChanged;
						change.ReferenceObject = walk.GetObjectId (0);
						yield return change;
					}
				}
			}
		}
Example #21
0
		public virtual void TestTwoLevelSubtree_Recursive()
		{
			DirCache dc = DirCache.NewInCore();
			FileMode mode = FileMode.REGULAR_FILE;
			string[] paths = new string[] { "a.", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
			DirCacheEntry[] ents = new DirCacheEntry[paths.Length];
			for (int i = 0; i < paths.Length; i++)
			{
				ents[i] = new DirCacheEntry(paths[i]);
				ents[i].FileMode = mode;
			}
			DirCacheBuilder b = dc.Builder();
			for (int i_1 = 0; i_1 < ents.Length; i_1++)
			{
				b.Add(ents[i_1]);
			}
			b.Finish();
			TreeWalk tw = new TreeWalk(db);
			tw.AddTree(new DirCacheIterator(dc));
			tw.Recursive = true;
			int pathIdx = 0;
			while (tw.Next())
			{
				DirCacheIterator c = tw.GetTree<DirCacheIterator>(0);
				NUnit.Framework.Assert.IsNotNull(c);
				NUnit.Framework.Assert.AreEqual(pathIdx, c.ptr);
				NUnit.Framework.Assert.AreSame(ents[pathIdx], c.GetDirCacheEntry());
				NUnit.Framework.Assert.AreEqual(paths[pathIdx], tw.PathString);
				NUnit.Framework.Assert.AreEqual(mode.GetBits(), tw.GetRawMode(0));
				NUnit.Framework.Assert.AreSame(mode, tw.GetFileMode(0));
				pathIdx++;
			}
			NUnit.Framework.Assert.AreEqual(paths.Length, pathIdx);
		}
Example #22
0
		public virtual void TestTwoLevelSubtree_FilterPath()
		{
			DirCache dc = DirCache.NewInCore();
			FileMode mode = FileMode.REGULAR_FILE;
			string[] paths = new string[] { "a.", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
			DirCacheEntry[] ents = new DirCacheEntry[paths.Length];
			for (int i = 0; i < paths.Length; i++)
			{
				ents[i] = new DirCacheEntry(paths[i]);
				ents[i].FileMode = mode;
			}
			DirCacheBuilder b = dc.Builder();
			for (int i_1 = 0; i_1 < ents.Length; i_1++)
			{
				b.Add(ents[i_1]);
			}
			b.Finish();
			TreeWalk tw = new TreeWalk(db);
			for (int victimIdx = 0; victimIdx < paths.Length; victimIdx++)
			{
				tw.Reset();
				tw.AddTree(new DirCacheIterator(dc));
				tw.Filter = PathFilterGroup.CreateFromStrings(Collections.Singleton(paths[victimIdx
					]));
				tw.Recursive = tw.Filter.ShouldBeRecursive();
				NUnit.Framework.Assert.IsTrue(tw.Next());
				DirCacheIterator c = tw.GetTree<DirCacheIterator>(0);
				NUnit.Framework.Assert.IsNotNull(c);
				NUnit.Framework.Assert.AreEqual(victimIdx, c.ptr);
				NUnit.Framework.Assert.AreSame(ents[victimIdx], c.GetDirCacheEntry());
				NUnit.Framework.Assert.AreEqual(paths[victimIdx], tw.PathString);
				NUnit.Framework.Assert.AreEqual(mode.GetBits(), tw.GetRawMode(0));
				NUnit.Framework.Assert.AreSame(mode, tw.GetFileMode(0));
				NUnit.Framework.Assert.IsFalse(tw.Next());
			}
		}
Example #23
0
		public virtual void TestNoSubtree_WithTreeWalk()
		{
			DirCache dc = DirCache.NewInCore();
			string[] paths = new string[] { "a.", "a0b" };
			FileMode[] modes = new FileMode[] { FileMode.EXECUTABLE_FILE, FileMode.GITLINK };
			DirCacheEntry[] ents = new DirCacheEntry[paths.Length];
			for (int i = 0; i < paths.Length; i++)
			{
				ents[i] = new DirCacheEntry(paths[i]);
				ents[i].FileMode = modes[i];
			}
			DirCacheBuilder b = dc.Builder();
			for (int i_1 = 0; i_1 < ents.Length; i_1++)
			{
				b.Add(ents[i_1]);
			}
			b.Finish();
			DirCacheIterator i_2 = new DirCacheIterator(dc);
			TreeWalk tw = new TreeWalk(db);
			tw.AddTree(i_2);
			int pathIdx = 0;
			while (tw.Next())
			{
				NUnit.Framework.Assert.AreSame(i_2, tw.GetTree<DirCacheIterator>(0));
				NUnit.Framework.Assert.AreEqual(pathIdx, i_2.ptr);
				NUnit.Framework.Assert.AreSame(ents[pathIdx], i_2.GetDirCacheEntry());
				NUnit.Framework.Assert.AreEqual(paths[pathIdx], tw.PathString);
				NUnit.Framework.Assert.AreEqual(modes[pathIdx].GetBits(), tw.GetRawMode(0));
				NUnit.Framework.Assert.AreSame(modes[pathIdx], tw.GetFileMode(0));
				pathIdx++;
			}
			NUnit.Framework.Assert.AreEqual(paths.Length, pathIdx);
		}
Example #24
0
		public virtual void TestSingleSubtree_NoRecursion()
		{
			DirCache dc = DirCache.NewInCore();
			string[] paths = new string[] { "a.", "a/b", "a/c", "a/d", "a0b" };
			DirCacheEntry[] ents = new DirCacheEntry[paths.Length];
			for (int i = 0; i < paths.Length; i++)
			{
				ents[i] = new DirCacheEntry(paths[i]);
				ents[i].FileMode = FileMode.REGULAR_FILE;
			}
			DirCacheBuilder b = dc.Builder();
			for (int i_1 = 0; i_1 < ents.Length; i_1++)
			{
				b.Add(ents[i_1]);
			}
			b.Finish();
			string[] expPaths = new string[] { "a.", "a", "a0b" };
			FileMode[] expModes = new FileMode[] { FileMode.REGULAR_FILE, FileMode.TREE, FileMode
				.REGULAR_FILE };
			int[] expPos = new int[] { 0, -1, 4 };
			DirCacheIterator i_2 = new DirCacheIterator(dc);
			TreeWalk tw = new TreeWalk(db);
			tw.AddTree(i_2);
			tw.Recursive = false;
			int pathIdx = 0;
			while (tw.Next())
			{
				NUnit.Framework.Assert.AreSame(i_2, tw.GetTree<DirCacheIterator>(0));
				NUnit.Framework.Assert.AreEqual(expModes[pathIdx].GetBits(), tw.GetRawMode(0));
				NUnit.Framework.Assert.AreSame(expModes[pathIdx], tw.GetFileMode(0));
				NUnit.Framework.Assert.AreEqual(expPaths[pathIdx], tw.PathString);
				if (expPos[pathIdx] >= 0)
				{
					NUnit.Framework.Assert.AreEqual(expPos[pathIdx], i_2.ptr);
					NUnit.Framework.Assert.AreSame(ents[expPos[pathIdx]], i_2.GetDirCacheEntry());
				}
				else
				{
					NUnit.Framework.Assert.AreSame(FileMode.TREE, tw.GetFileMode(0));
				}
				pathIdx++;
			}
			NUnit.Framework.Assert.AreEqual(expPaths.Length, pathIdx);
		}
		public virtual void TestPathFilterGroup_DoesNotSkipTail()
		{
			DirCache dc = db.ReadDirCache();
			FileMode mode = FileMode.REGULAR_FILE;
			string[] paths = new string[] { "a.", "a/b", "a/c", "a/d", "a0b" };
			DirCacheEntry[] ents = new DirCacheEntry[paths.Length];
			for (int i = 0; i < paths.Length; i++)
			{
				ents[i] = new DirCacheEntry(paths[i]);
				ents[i].FileMode = mode;
			}
			{
				DirCacheBuilder b = dc.Builder();
				for (int i_1 = 0; i_1 < ents.Length; i_1++)
				{
					b.Add(ents[i_1]);
				}
				b.Finish();
			}
			int expIdx = 2;
			DirCacheBuilder b_1 = dc.Builder();
			TreeWalk tw = new TreeWalk(db);
			tw.AddTree(new DirCacheBuildIterator(b_1));
			tw.Recursive = true;
			tw.Filter = PathFilterGroup.CreateFromStrings(Collections.Singleton(paths[expIdx]
				));
			NUnit.Framework.Assert.IsTrue(tw.Next(), "found " + paths[expIdx]);
			DirCacheIterator c = tw.GetTree<DirCacheIterator>(0);
			NUnit.Framework.Assert.IsNotNull(c);
			NUnit.Framework.Assert.AreEqual(expIdx, c.ptr);
			NUnit.Framework.Assert.AreSame(ents[expIdx], c.GetDirCacheEntry());
			NUnit.Framework.Assert.AreEqual(paths[expIdx], tw.PathString);
			NUnit.Framework.Assert.AreEqual(mode.GetBits(), tw.GetRawMode(0));
			NUnit.Framework.Assert.AreSame(mode, tw.GetFileMode(0));
			b_1.Add(c.GetDirCacheEntry());
			NUnit.Framework.Assert.IsFalse(tw.Next(), "no more entries");
			b_1.Finish();
			NUnit.Framework.Assert.AreEqual(ents.Length, dc.GetEntryCount());
			for (int i_2 = 0; i_2 < ents.Length; i_2++)
			{
				NUnit.Framework.Assert.AreSame(ents[i_2], dc.GetEntry(i_2));
			}
		}
Example #26
0
		/// <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;
							}
						}
					}
				}
			}
		}
Example #27
0
 static IEnumerable <Change> CalculateCommitDiff(NGit.Repository repo, TreeWalk walk, RevCommit[] commits)
 {
     while (walk.Next())
     {
         int m0 = walk.GetRawMode(0);
         if (walk.TreeCount == 2)
         {
             int m1     = walk.GetRawMode(1);
             var change = new Change {
                 ReferenceCommit = commits[0], ComparedCommit = commits[1], ReferencePermissions = walk.GetFileMode(0).GetBits(), ComparedPermissions = walk.GetFileMode(1).GetBits(), Name = walk.NameString, Path = walk.PathString
             };
             if (m0 != 0 && m1 == 0)
             {
                 change.ChangeType     = ChangeType.Added;
                 change.ComparedObject = walk.GetObjectId(0);
             }
             else if (m0 == 0 && m1 != 0)
             {
                 change.ChangeType      = ChangeType.Deleted;
                 change.ReferenceObject = walk.GetObjectId(0);
             }
             else if (m0 != m1 && walk.IdEqual(0, 1))
             {
                 change.ChangeType      = ChangeType.TypeChanged;
                 change.ReferenceObject = walk.GetObjectId(0);
                 change.ComparedObject  = walk.GetObjectId(1);
             }
             else
             {
                 change.ChangeType      = ChangeType.Modified;
                 change.ReferenceObject = walk.GetObjectId(0);
                 change.ComparedObject  = walk.GetObjectId(1);
             }
             yield return(change);
         }
         else
         {
             var raw_modes = new int[walk.TreeCount - 1];
             for (int i = 0; i < walk.TreeCount - 1; i++)
             {
                 raw_modes[i] = walk.GetRawMode(i + 1);
             }
             //ComparedCommit = compared,
             var change = new Change {
                 ReferenceCommit = commits[0], Name = walk.NameString, Path = walk.PathString
             };
             if (m0 != 0 && raw_modes.All(m1 => m1 == 0))
             {
                 change.ChangeType     = ChangeType.Added;
                 change.ComparedObject = walk.GetObjectId(0);
                 yield return(change);
             }
             else if (m0 == 0 && raw_modes.Any(m1 => m1 != 0))
             {
                 change.ChangeType = ChangeType.Deleted;
                 yield return(change);
                 // TODO: not sure if this condition suffices in some special cases.
             }
             else if (raw_modes.Select((m1, i) => new { Mode = m1, Index = i + 1 }).All(x => !walk.IdEqual(0, x.Index)))
             {
                 change.ChangeType      = ChangeType.Modified;
                 change.ReferenceObject = walk.GetObjectId(0);
                 yield return(change);
             }
             else if (raw_modes.Select((m1, i) => new { Mode = m1, Index = i + 1 }).Any(x => m0 != x.Mode && walk.IdEqual(0, x.Index)))
             {
                 change.ChangeType      = ChangeType.TypeChanged;
                 change.ReferenceObject = walk.GetObjectId(0);
                 yield return(change);
             }
         }
     }
 }
Example #28
0
		/// <exception cref="System.Exception"></exception>
		private static void AssertModes(string path, FileMode mode0, FileMode mode1, TreeWalk
			 tw)
		{
			NUnit.Framework.Assert.IsTrue(tw.Next(), "has " + path);
			NUnit.Framework.Assert.AreEqual(path, tw.PathString);
			NUnit.Framework.Assert.AreEqual(mode0, tw.GetFileMode(0));
			NUnit.Framework.Assert.AreEqual(mode1, tw.GetFileMode(1));
		}
Example #29
0
 /// <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;
 }
Example #30
0
        /// <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 TestMissingSubtree_DetectFileAdded_FileModified()
		{
			ObjectInserter inserter = db.NewObjectInserter();
			ObjectId aFileId = inserter.Insert(Constants.OBJ_BLOB, Constants.Encode("a"));
			ObjectId bFileId = inserter.Insert(Constants.OBJ_BLOB, Constants.Encode("b"));
			ObjectId cFileId1 = inserter.Insert(Constants.OBJ_BLOB, Constants.Encode("c-1"));
			ObjectId cFileId2 = inserter.Insert(Constants.OBJ_BLOB, Constants.Encode("c-2"));
			// Create sub-a/empty, sub-c/empty = hello.
			ObjectId oldTree;
			{
				Tree root = new Tree(db);
				{
					Tree subA = root.AddTree("sub-a");
					subA.AddFile("empty").SetId(aFileId);
					subA.SetId(inserter.Insert(Constants.OBJ_TREE, subA.Format()));
				}
				{
					Tree subC = root.AddTree("sub-c");
					subC.AddFile("empty").SetId(cFileId1);
					subC.SetId(inserter.Insert(Constants.OBJ_TREE, subC.Format()));
				}
				oldTree = inserter.Insert(Constants.OBJ_TREE, root.Format());
			}
			// Create sub-a/empty, sub-b/empty, sub-c/empty.
			ObjectId newTree;
			{
				Tree root = new Tree(db);
				{
					Tree subA = root.AddTree("sub-a");
					subA.AddFile("empty").SetId(aFileId);
					subA.SetId(inserter.Insert(Constants.OBJ_TREE, subA.Format()));
				}
				{
					Tree subB = root.AddTree("sub-b");
					subB.AddFile("empty").SetId(bFileId);
					subB.SetId(inserter.Insert(Constants.OBJ_TREE, subB.Format()));
				}
				{
					Tree subC = root.AddTree("sub-c");
					subC.AddFile("empty").SetId(cFileId2);
					subC.SetId(inserter.Insert(Constants.OBJ_TREE, subC.Format()));
				}
				newTree = inserter.Insert(Constants.OBJ_TREE, root.Format());
			}
			inserter.Flush();
			inserter.Release();
			TreeWalk tw = new TreeWalk(db);
			tw.Reset(oldTree, newTree);
			tw.Recursive = true;
			tw.Filter = TreeFilter.ANY_DIFF;
			NUnit.Framework.Assert.IsTrue(tw.Next());
			NUnit.Framework.Assert.AreEqual("sub-b/empty", tw.PathString);
			NUnit.Framework.Assert.AreEqual(FileMode.MISSING, tw.GetFileMode(0));
			NUnit.Framework.Assert.AreEqual(FileMode.REGULAR_FILE, tw.GetFileMode(1));
			NUnit.Framework.Assert.AreEqual(ObjectId.ZeroId, tw.GetObjectId(0));
			NUnit.Framework.Assert.AreEqual(bFileId, tw.GetObjectId(1));
			NUnit.Framework.Assert.IsTrue(tw.Next());
			NUnit.Framework.Assert.AreEqual("sub-c/empty", tw.PathString);
			NUnit.Framework.Assert.AreEqual(FileMode.REGULAR_FILE, tw.GetFileMode(0));
			NUnit.Framework.Assert.AreEqual(FileMode.REGULAR_FILE, tw.GetFileMode(1));
			NUnit.Framework.Assert.AreEqual(cFileId1, tw.GetObjectId(0));
			NUnit.Framework.Assert.AreEqual(cFileId2, tw.GetObjectId(1));
			NUnit.Framework.Assert.IsFalse(tw.Next());
		}