示例#1
0
 /// <summary>Create an iterator for a subtree of an existing iterator.</summary>
 /// <remarks>
 /// Create an iterator for a subtree of an existing iterator.
 /// <p>
 /// The caller is responsible for setting up the path of the child iterator.
 /// </remarks>
 /// <param name="p">parent tree iterator.</param>
 /// <param name="childPath">
 /// path array to be used by the child iterator. This path must
 /// contain the path from the top of the walk to the first child
 /// and must end with a '/'.
 /// </param>
 /// <param name="childPathOffset">
 /// position within <code>childPath</code> where the child can
 /// insert its data. The value at
 /// <code>childPath[childPathOffset-1]</code> must be '/'.
 /// </param>
 protected internal AbstractTreeIterator(NGit.Treewalk.AbstractTreeIterator p, byte
                                         [] childPath, int childPathOffset)
 {
     parent     = p;
     path       = childPath;
     pathOffset = childPathOffset;
 }
示例#2
0
 /// <summary>Reset this walker to run over a single existing tree.</summary>
 /// <remarks>Reset this walker to run over a single existing tree.</remarks>
 /// <param name="id">
 /// the tree we need to parse. The walker will execute over this
 /// single tree if the reset is successful.
 /// </param>
 /// <exception cref="NGit.Errors.MissingObjectException">the given tree object does not exist in this repository.
 ///     </exception>
 /// <exception cref="NGit.Errors.IncorrectObjectTypeException">
 /// the given object id does not denote a tree, but instead names
 /// some other non-tree type of object. Note that commits are not
 /// trees, even if they are sometimes called a "tree-ish".
 /// </exception>
 /// <exception cref="NGit.Errors.CorruptObjectException">
 /// the object claimed to be a tree, but its contents did not
 /// appear to be a tree. The repository may have data corruption.
 /// </exception>
 /// <exception cref="System.IO.IOException">a loose object or pack file could not be read.
 ///     </exception>
 public virtual void Reset(AnyObjectId id)
 {
     if (trees.Length == 1)
     {
         AbstractTreeIterator o = trees[0];
         while (o.parent != null)
         {
             o = o.parent;
         }
         if (o is CanonicalTreeParser)
         {
             o.matches    = null;
             o.matchShift = 0;
             ((CanonicalTreeParser)o).Reset(reader, id);
             trees[0] = o;
         }
         else
         {
             trees[0] = ParserFor(id);
         }
     }
     else
     {
         trees = new AbstractTreeIterator[] { ParserFor(id) };
     }
     advance = false;
     depth   = 0;
 }
示例#3
0
        /// <summary>Obtain the tree iterator for the current entry.</summary>
        /// <remarks>
        /// Obtain the tree iterator for the current entry.
        /// <p>
        /// Entering into (or exiting out of) a subtree causes the current tree
        /// iterator instance to be changed for the nth tree. This allows the tree
        /// iterators to manage only one list of items, with the diving handled by
        /// recursive trees.
        /// </remarks>
        /// <?></?>
        /// <param name="nth">tree to obtain the current iterator of.</param>
        /// <param name="clazz">type of the tree iterator expected by the caller.</param>
        /// <returns>
        /// r the current iterator of the requested type; null if the tree
        /// has no entry to match the current path.
        /// </returns>
        public virtual T GetTree <T>(int nth) where T : AbstractTreeIterator
        {
            System.Type          clazz = typeof(T);
            AbstractTreeIterator t     = trees[nth];

            return(t.matches == currentHead ? (T)t : null);
        }
示例#4
0
 /// <exception cref="NGit.Errors.CorruptObjectException"></exception>
 internal override AbstractTreeIterator Min()
 {
     for (; ;)
     {
         AbstractTreeIterator minRef = FastMin();
         if (fastMinHasMatch)
         {
             return(minRef);
         }
         if (IsTree(minRef))
         {
             if (SkipEntry(minRef))
             {
                 foreach (AbstractTreeIterator t in trees)
                 {
                     if (t.matches == minRef)
                     {
                         t.Next(1);
                         t.matches = null;
                     }
                 }
                 continue;
             }
             return(minRef);
         }
         return(CombineDF(minRef));
     }
 }
示例#5
0
        /// <exception cref="NGit.Errors.CorruptObjectException"></exception>
        internal override void SkipEntriesEqual()
        {
            AbstractTreeIterator ch = currentHead;

            for (int i = 0; i < trees.Length; i++)
            {
                AbstractTreeIterator t = trees[i];
                if (t.matches == ch)
                {
                    if (t.matchShift == 0)
                    {
                        t.Skip();
                    }
                    else
                    {
                        t.Back(t.matchShift);
                        t.matchShift = 0;
                    }
                    t.matches = null;
                }
            }
            if (ch == dfConflict)
            {
                dfConflict = null;
            }
        }
示例#6
0
        internal virtual int PathCompare(NGit.Treewalk.AbstractTreeIterator p, int pMode)
        {
            // Its common when we are a subtree for both parents to match;
            // when this happens everything in path[0..cPos] is known to
            // be equal and does not require evaluation again.
            //
            int cPos = AlreadyMatch(this, p);

            return(PathCompare(p.path, cPos, p.pathLen, pMode, cPos));
        }
示例#7
0
 /// <summary>Set path buffer capacity to the specified size</summary>
 /// <param name="capacity">the new size</param>
 /// <param name="len">the amount of bytes to copy</param>
 private void SetPathCapacity(int capacity, int len)
 {
     byte[] o = path;
     byte[] n = new byte[capacity];
     System.Array.Copy(o, 0, n, 0, len);
     for (NGit.Treewalk.AbstractTreeIterator p = this; p != null && p.path == o; p = p
                                                                                     .parent)
     {
         p.path = n;
     }
 }
        public virtual void TestCreateSubtreeIterator()
        {
            EmptyTreeIterator    etp    = new EmptyTreeIterator();
            ObjectReader         reader = db.NewObjectReader();
            AbstractTreeIterator sub    = etp.CreateSubtreeIterator(reader);

            NUnit.Framework.Assert.IsNotNull(sub);
            NUnit.Framework.Assert.IsTrue(sub.First);
            NUnit.Framework.Assert.IsTrue(sub.Eof);
            NUnit.Framework.Assert.IsTrue(sub is EmptyTreeIterator);
        }
示例#9
0
 /// <summary>Advance this walker to the next relevant entry.</summary>
 /// <remarks>Advance this walker to the next relevant entry.</remarks>
 /// <returns>
 /// true if there is an entry available; false if all entries have
 /// been walked and the walk of this set of tree iterators is over.
 /// </returns>
 /// <exception cref="NGit.Errors.MissingObjectException">
 /// <see cref="Recursive()">Recursive()</see>
 /// was enabled, a subtree was found, but
 /// the subtree object does not exist in this repository. The
 /// repository may be missing objects.
 /// </exception>
 /// <exception cref="NGit.Errors.IncorrectObjectTypeException">
 /// <see cref="Recursive()">Recursive()</see>
 /// was enabled, a subtree was found, and
 /// the subtree id does not denote a tree, but instead names some
 /// other non-tree type of object. The repository may have data
 /// corruption.
 /// </exception>
 /// <exception cref="NGit.Errors.CorruptObjectException">
 /// the contents of a tree did not appear to be a tree. The
 /// repository may have data corruption.
 /// </exception>
 /// <exception cref="System.IO.IOException">a loose object or pack file could not be read.
 ///     </exception>
 public virtual bool Next()
 {
     try
     {
         if (advance)
         {
             advance      = false;
             postChildren = false;
             PopEntriesEqual();
         }
         for (; ;)
         {
             AbstractTreeIterator t = Min();
             if (t.Eof)
             {
                 if (depth > 0)
                 {
                     ExitSubtree();
                     if (postOrderTraversal)
                     {
                         advance      = true;
                         postChildren = true;
                         return(true);
                     }
                     PopEntriesEqual();
                     continue;
                 }
                 return(false);
             }
             currentHead = t;
             if (!filter.Include(this))
             {
                 SkipEntriesEqual();
                 continue;
             }
             if (recursive && FileMode.TREE.Equals(t.mode))
             {
                 EnterSubtree();
                 continue;
             }
             advance = true;
             return(true);
         }
     }
     catch (StopWalkException)
     {
         foreach (AbstractTreeIterator t in trees)
         {
             t.StopWalk();
         }
         return(false);
     }
 }
示例#10
0
        /// <summary>Add an already created tree iterator for walking.</summary>
        /// <remarks>
        /// Add an already created tree iterator for walking.
        /// <p>
        /// The position of this tree is returned to the caller, in case the caller
        /// has lost track of the order they added the trees into the walker.
        /// <p>
        /// The tree which the iterator operates on must have the same root as
        /// existing trees in the walk.
        /// </remarks>
        /// <param name="p">
        /// an iterator to walk over. The iterator should be new, with no
        /// parent, and should still be positioned before the first entry.
        /// The tree which the iterator operates on must have the same root
        /// as other trees in the walk.
        /// </param>
        /// <returns>position of this tree within the walker.</returns>
        /// <exception cref="NGit.Errors.CorruptObjectException">
        /// the iterator was unable to obtain its first entry, due to
        /// possible data corruption within the backing data store.
        /// </exception>
        public virtual int AddTree(AbstractTreeIterator p)
        {
            int n = trees.Length;

            AbstractTreeIterator[] newTrees = new AbstractTreeIterator[n + 1];
            System.Array.Copy(trees, 0, newTrees, 0, n);
            newTrees[n]  = p;
            p.matches    = null;
            p.matchShift = 0;
            trees        = newTrees;
            return(n);
        }
示例#11
0
        /// <summary>Obtain the ObjectId for the current entry.</summary>
        /// <remarks>
        /// Obtain the ObjectId for the current entry.
        /// <p>
        /// Every tree supplies an object id, even if the tree does not contain the
        /// current entry. In the latter case
        /// <see cref="NGit.ObjectId.ZeroId()">NGit.ObjectId.ZeroId()</see>
        /// is supplied.
        /// <p>
        /// Applications should try to use
        /// <see cref="IdEqual(int, int)">IdEqual(int, int)</see>
        /// when possible
        /// as it avoids conversion overheads.
        /// </remarks>
        /// <param name="out">buffer to copy the object id into.</param>
        /// <param name="nth">tree to obtain the object identifier from.</param>
        /// <seealso cref="IdEqual(int, int)">IdEqual(int, int)</seealso>
        public virtual void GetObjectId(MutableObjectId @out, int nth)
        {
            AbstractTreeIterator t = trees[nth];

            if (t.matches == currentHead)
            {
                t.GetEntryObjectId(@out);
            }
            else
            {
                @out.Clear();
            }
        }
示例#12
0
        /// <exception cref="NGit.Errors.CorruptObjectException"></exception>
        internal virtual void SkipEntriesEqual()
        {
            AbstractTreeIterator ch = currentHead;

            for (int i = 0; i < trees.Length; i++)
            {
                AbstractTreeIterator t = trees[i];
                if (t.matches == ch)
                {
                    t.Skip();
                    t.matches = null;
                }
            }
        }
示例#13
0
 /// <summary>Create an iterator for a subtree of an existing iterator.</summary>
 /// <remarks>Create an iterator for a subtree of an existing iterator.</remarks>
 /// <param name="p">parent tree iterator.</param>
 protected internal AbstractTreeIterator(NGit.Treewalk.AbstractTreeIterator p)
 {
     parent     = p;
     path       = p.path;
     pathOffset = p.pathLen + 1;
     try
     {
         path[pathOffset - 1] = (byte)('/');
     }
     catch (IndexOutOfRangeException)
     {
         GrowPath(p.pathLen);
         path[pathOffset - 1] = (byte)('/');
     }
 }
示例#14
0
        /// <summary>
        /// Test if the supplied path matches (being suffix of) the current entry's
        /// path.
        /// </summary>
        /// <remarks>
        /// Test if the supplied path matches (being suffix of) the current entry's
        /// path.
        /// <p>
        /// This method tests that the supplied path is exactly equal to the current
        /// entry, or is relative to one of entry's parent directories. It is faster
        /// to use this method then to use
        /// <see cref="PathString()">PathString()</see>
        /// to first create
        /// a String object, then test <code>endsWith</code> or some other type of
        /// string match function.
        /// </remarks>
        /// <param name="p">path buffer to test.</param>
        /// <param name="pLen">number of bytes from <code>buf</code> to test.</param>
        /// <returns>
        /// true if p is suffix of the current path;
        /// false if otherwise
        /// </returns>
        public virtual bool IsPathSuffix(byte[] p, int pLen)
        {
            AbstractTreeIterator t = currentHead;

            byte[] c    = t.path;
            int    cLen = t.pathLen;
            int    ci;

            for (ci = 1; ci < cLen && ci < pLen; ci++)
            {
                if (c[cLen - ci] != p[pLen - ci])
                {
                    return(false);
                }
            }
            return(true);
        }
        public virtual void TestSimpleIterate()
        {
            FileTreeIterator top = new FileTreeIterator(trash, db.FileSystem, ((FileBasedConfig
                                                                                )db.GetConfig()).Get(WorkingTreeOptions.KEY));

            NUnit.Framework.Assert.IsTrue(top.First);
            NUnit.Framework.Assert.IsFalse(top.Eof);
            NUnit.Framework.Assert.AreEqual(FileMode.REGULAR_FILE.GetBits(), top.mode);
            NUnit.Framework.Assert.AreEqual(paths[0], NameOf(top));
            NUnit.Framework.Assert.AreEqual(paths[0].Length, top.GetEntryLength());
            NUnit.Framework.Assert.AreEqual(mtime[0], top.GetEntryLastModified());
            top.Next(1);
            NUnit.Framework.Assert.IsFalse(top.First);
            NUnit.Framework.Assert.IsFalse(top.Eof);
            NUnit.Framework.Assert.AreEqual(FileMode.REGULAR_FILE.GetBits(), top.mode);
            NUnit.Framework.Assert.AreEqual(paths[1], NameOf(top));
            NUnit.Framework.Assert.AreEqual(paths[1].Length, top.GetEntryLength());
            NUnit.Framework.Assert.AreEqual(mtime[1], top.GetEntryLastModified());
            top.Next(1);
            NUnit.Framework.Assert.IsFalse(top.First);
            NUnit.Framework.Assert.IsFalse(top.Eof);
            NUnit.Framework.Assert.AreEqual(FileMode.TREE.GetBits(), top.mode);
            ObjectReader         reader = db.NewObjectReader();
            AbstractTreeIterator sub    = top.CreateSubtreeIterator(reader);

            NUnit.Framework.Assert.IsTrue(sub is FileTreeIterator);
            FileTreeIterator subfti = (FileTreeIterator)sub;

            NUnit.Framework.Assert.IsTrue(sub.First);
            NUnit.Framework.Assert.IsFalse(sub.Eof);
            NUnit.Framework.Assert.AreEqual(paths[2], NameOf(sub));
            NUnit.Framework.Assert.AreEqual(paths[2].Length, subfti.GetEntryLength());
            NUnit.Framework.Assert.AreEqual(mtime[2], subfti.GetEntryLastModified());
            sub.Next(1);
            NUnit.Framework.Assert.IsTrue(sub.Eof);
            top.Next(1);
            NUnit.Framework.Assert.IsFalse(top.First);
            NUnit.Framework.Assert.IsFalse(top.Eof);
            NUnit.Framework.Assert.AreEqual(FileMode.REGULAR_FILE.GetBits(), top.mode);
            NUnit.Framework.Assert.AreEqual(paths[3], NameOf(top));
            NUnit.Framework.Assert.AreEqual(paths[3].Length, top.GetEntryLength());
            NUnit.Framework.Assert.AreEqual(mtime[3], top.GetEntryLastModified());
            top.Next(1);
            NUnit.Framework.Assert.IsTrue(top.Eof);
        }
示例#16
0
 private static int AlreadyMatch(NGit.Treewalk.AbstractTreeIterator a, NGit.Treewalk.AbstractTreeIterator
                                 b)
 {
     for (; ;)
     {
         NGit.Treewalk.AbstractTreeIterator ap = a.parent;
         NGit.Treewalk.AbstractTreeIterator bp = b.parent;
         if (ap == null || bp == null)
         {
             return(0);
         }
         if (ap.matches == bp.matches)
         {
             return(a.pathOffset);
         }
         a = ap;
         b = bp;
     }
 }
示例#17
0
 /// <summary>Create a new iterator with no parent and a prefix.</summary>
 /// <remarks>
 /// Create a new iterator with no parent and a prefix.
 /// <p>
 /// The prefix path supplied is inserted in front of all paths generated by
 /// this iterator. It is intended to be used when an iterator is being
 /// created for a subsection of an overall repository and needs to be
 /// combined with other iterators that are created to run over the entire
 /// repository namespace.
 /// </remarks>
 /// <param name="prefix">
 /// position of this iterator in the repository tree. The value
 /// may be null or the empty array to indicate the prefix is the
 /// root of the repository. A trailing slash ('/') is
 /// automatically appended if the prefix does not end in '/'.
 /// </param>
 protected internal AbstractTreeIterator(byte[] prefix)
 {
     parent = null;
     if (prefix != null && prefix.Length > 0)
     {
         pathLen = prefix.Length;
         path    = new byte[Math.Max(DEFAULT_PATH_SIZE, pathLen + 1)];
         System.Array.Copy(prefix, 0, path, 0, pathLen);
         if (path[pathLen - 1] != '/')
         {
             path[pathLen++] = (byte)('/');
         }
         pathOffset = pathLen;
     }
     else
     {
         path       = new byte[DEFAULT_PATH_SIZE];
         pathOffset = 0;
     }
 }
示例#18
0
 /// <exception cref="NGit.Errors.CorruptObjectException"></exception>
 private bool SkipEntry(AbstractTreeIterator minRef)
 {
     // A tree D/F may have been handled earlier. We need to
     // not report this path if it has already been reported.
     //
     foreach (AbstractTreeIterator t in trees)
     {
         if (t.matches == minRef || t.First)
         {
             continue;
         }
         int stepsBack = 0;
         for (; ;)
         {
             stepsBack++;
             t.Back(1);
             int cmp = t.PathCompare(minRef, 0);
             if (cmp == 0)
             {
                 // We have already seen this "$path" before. Skip it.
                 //
                 t.Next(stepsBack);
                 return(true);
             }
             else
             {
                 if (cmp < 0 || t.First)
                 {
                     // We cannot find "$path" in t; it will never appear.
                     //
                     t.Next(stepsBack);
                     break;
                 }
             }
         }
     }
     // We have never seen the current path before.
     //
     return(false);
 }
示例#19
0
 /// <summary>Create a new iterator with no parent and a prefix.</summary>
 /// <remarks>
 /// Create a new iterator with no parent and a prefix.
 /// <p>
 /// The prefix path supplied is inserted in front of all paths generated by
 /// this iterator. It is intended to be used when an iterator is being
 /// created for a subsection of an overall repository and needs to be
 /// combined with other iterators that are created to run over the entire
 /// repository namespace.
 /// </remarks>
 /// <param name="prefix">
 /// position of this iterator in the repository tree. The value
 /// may be null or the empty string to indicate the prefix is the
 /// root of the repository. A trailing slash ('/') is
 /// automatically appended if the prefix does not end in '/'.
 /// </param>
 protected internal AbstractTreeIterator(string prefix)
 {
     parent = null;
     if (prefix != null && prefix.Length > 0)
     {
         ByteBuffer b;
         b       = Constants.CHARSET.Encode(CharBuffer.Wrap(prefix));
         pathLen = b.Limit();
         path    = new byte[Math.Max(DEFAULT_PATH_SIZE, pathLen + 1)];
         b.Get(path, 0, pathLen);
         if (path[pathLen - 1] != '/')
         {
             path[pathLen++] = (byte)('/');
         }
         pathOffset = pathLen;
     }
     else
     {
         path       = new byte[DEFAULT_PATH_SIZE];
         pathOffset = 0;
     }
 }
示例#20
0
        private void ExitSubtree()
        {
            depth--;
            for (int i = 0; i < trees.Length; i++)
            {
                trees[i] = trees[i].parent;
            }
            AbstractTreeIterator minRef = null;

            foreach (AbstractTreeIterator t in trees)
            {
                if (t.matches != t)
                {
                    continue;
                }
                if (minRef == null || t.PathCompare(minRef) < 0)
                {
                    minRef = t;
                }
            }
            currentHead = minRef;
        }
示例#21
0
        /// <summary>Enter into the current subtree.</summary>
        /// <remarks>
        /// Enter into the current subtree.
        /// <p>
        /// If the current entry is a subtree this method arranges for its children
        /// to be returned before the next sibling following the subtree is returned.
        /// </remarks>
        /// <exception cref="NGit.Errors.MissingObjectException">
        /// a subtree was found, but the subtree object does not exist in
        /// this repository. The repository may be missing objects.
        /// </exception>
        /// <exception cref="NGit.Errors.IncorrectObjectTypeException">
        /// a subtree was found, and the subtree id does not denote a
        /// tree, but instead names some other non-tree type of object.
        /// The repository may have data corruption.
        /// </exception>
        /// <exception cref="NGit.Errors.CorruptObjectException">
        /// the contents of a tree did not appear to be a tree. The
        /// repository may have data corruption.
        /// </exception>
        /// <exception cref="System.IO.IOException">a loose object or pack file could not be read.
        ///     </exception>
        public virtual void EnterSubtree()
        {
            AbstractTreeIterator ch = currentHead;

            AbstractTreeIterator[] tmp = new AbstractTreeIterator[trees.Length];
            for (int i = 0; i < trees.Length; i++)
            {
                AbstractTreeIterator t = trees[i];
                AbstractTreeIterator n;
                if (t.matches == ch && !t.Eof && FileMode.TREE.Equals(t.mode))
                {
                    n = t.CreateSubtreeIterator(reader, idBuffer);
                }
                else
                {
                    n = t.CreateEmptyTreeIterator();
                }
                tmp[i] = n;
            }
            depth++;
            advance = false;
            System.Array.Copy(tmp, 0, trees, 0, trees.Length);
        }
示例#22
0
        /// <exception cref="NGit.Errors.CorruptObjectException"></exception>
        internal virtual AbstractTreeIterator Min()
        {
            int i = 0;
            AbstractTreeIterator minRef = trees[i];

            while (minRef.Eof && ++i < trees.Length)
            {
                minRef = trees[i];
            }
            if (minRef.Eof)
            {
                return(minRef);
            }
            minRef.matches = minRef;
            while (++i < trees.Length)
            {
                AbstractTreeIterator t = trees[i];
                if (t.Eof)
                {
                    continue;
                }
                int cmp = t.PathCompare(minRef);
                if (cmp < 0)
                {
                    t.matches = t;
                    minRef    = t;
                }
                else
                {
                    if (cmp == 0)
                    {
                        t.matches = minRef;
                    }
                }
            }
            return(minRef);
        }
示例#23
0
        /// <summary>Compare two tree's current ObjectId values for equality.</summary>
        /// <remarks>Compare two tree's current ObjectId values for equality.</remarks>
        /// <param name="nthA">first tree to compare the object id from.</param>
        /// <param name="nthB">second tree to compare the object id from.</param>
        /// <returns>
        /// result of
        /// <code>getObjectId(nthA).equals(getObjectId(nthB))</code>.
        /// </returns>
        /// <seealso cref="GetObjectId(int)">GetObjectId(int)</seealso>
        public virtual bool IdEqual(int nthA, int nthB)
        {
            AbstractTreeIterator ch = currentHead;
            AbstractTreeIterator a  = trees[nthA];
            AbstractTreeIterator b  = trees[nthB];

            if (a.matches != ch && b.matches != ch)
            {
                // If neither tree matches the current path node then neither
                // tree has this entry. In such case the ObjectId is zero(),
                // and zero() is always equal to zero().
                //
                return(true);
            }
            if (!a.HasId || !b.HasId)
            {
                return(false);
            }
            if (a.matches == ch && b.matches == ch)
            {
                return(a.IdEqual(b));
            }
            return(false);
        }
示例#24
0
        /// <summary>Test if the supplied path matches the current entry's path.</summary>
        /// <remarks>
        /// Test if the supplied path matches the current entry's path.
        /// <p>
        /// This method tests that the supplied path is exactly equal to the current
        /// entry, or is one of its parent directories. It is faster to use this
        /// method then to use
        /// <see cref="PathString()">PathString()</see>
        /// to first create a String
        /// object, then test <code>startsWith</code> or some other type of string
        /// match function.
        /// </remarks>
        /// <param name="p">
        /// path buffer to test. Callers should ensure the path does not
        /// end with '/' prior to invocation.
        /// </param>
        /// <param name="pLen">number of bytes from <code>buf</code> to test.</param>
        /// <returns>
        /// &lt; 0 if p is before the current path; 0 if p matches the current
        /// path; 1 if the current path is past p and p will never match
        /// again on this tree walk.
        /// </returns>
        public virtual int IsPathPrefix(byte[] p, int pLen)
        {
            AbstractTreeIterator t = currentHead;

            byte[] c    = t.path;
            int    cLen = t.pathLen;
            int    ci;

            for (ci = 0; ci < cLen && ci < pLen; ci++)
            {
                int c_value = (c[ci] & unchecked ((int)(0xff))) - (p[ci] & unchecked ((int)(0xff)));
                if (c_value != 0)
                {
                    return(c_value);
                }
            }
            if (ci < cLen)
            {
                // Ran out of pattern but we still had current data.
                // If c[ci] == '/' then pattern matches the subtree.
                // Otherwise we cannot be certain so we return -1.
                //
                return(c[ci] == '/' ? 0 : -1);
            }
            if (ci < pLen)
            {
                // Ran out of current, but we still have pattern data.
                // If p[ci] == '/' then pattern matches this subtree,
                // otherwise we cannot be certain so we return -1.
                //
                return(p[ci] == '/' ? 0 : -1);
            }
            // Both strings are identical.
            //
            return(0);
        }
示例#25
0
		/// <summary>Create an iterator for a subtree of an existing iterator.</summary>
		/// <remarks>
		/// Create an iterator for a subtree of an existing iterator.
		/// <p>
		/// The caller is responsible for setting up the path of the child iterator.
		/// </remarks>
		/// <param name="p">parent tree iterator.</param>
		/// <param name="childPath">
		/// path array to be used by the child iterator. This path must
		/// contain the path from the top of the walk to the first child
		/// and must end with a '/'.
		/// </param>
		/// <param name="childPathOffset">
		/// position within <code>childPath</code> where the child can
		/// insert its data. The value at
		/// <code>childPath[childPathOffset-1]</code> must be '/'.
		/// </param>
		protected internal EmptyTreeIterator(AbstractTreeIterator p, byte[] childPath, int
			 childPathOffset) : base(p, childPath, childPathOffset)
		{
			pathLen = childPathOffset - 1;
		}
示例#26
0
		protected internal EmptyTreeIterator(AbstractTreeIterator p) : base(p)
		{
			// Create a root empty tree.
			pathLen = pathOffset;
		}
示例#27
0
		/// <summary>
		/// Set the tree used by this walk for finding
		/// <code>.gitmodules</code>
		/// .
		/// <p>
		/// The root tree is not read until the first submodule is encountered by the
		/// walk.
		/// <p>
		/// This method need only be called if constructing a walk manually instead of
		/// with one of the static factory methods above.
		/// </summary>
		/// <param name="id">ID of a tree containing .gitmodules</param>
		/// <returns>this generator</returns>
		/// <exception cref="System.IO.IOException">System.IO.IOException</exception>
		public virtual NGit.Submodule.SubmoduleWalk SetRootTree(AnyObjectId id)
		{
			CanonicalTreeParser p = new CanonicalTreeParser();
			p.Reset(walk.ObjectReader, id);
			rootTree = p;
			modulesConfig = null;
			return this;
		}
示例#28
0
		/// <summary>
		/// Create a generator and advance it to the submodule entry at the given
		/// path
		/// </summary>
		/// <param name="repository"></param>
		/// <param name="iterator"></param>
		/// <param name="path"></param>
		/// <returns>generator at given path, null if no submodule at given path</returns>
		/// <exception cref="System.IO.IOException">System.IO.IOException</exception>
		public static NGit.Submodule.SubmoduleWalk ForPath(Repository repository, AbstractTreeIterator
			 iterator, string path)
		{
			NGit.Submodule.SubmoduleWalk generator = new NGit.Submodule.SubmoduleWalk(repository
				);
			generator.SetTree(iterator);
			PathFilter filter = PathFilter.Create(path);
			generator.SetFilter(filter);
			while (generator.Next())
			{
				if (filter.IsDone(generator.walk))
				{
					return generator;
				}
			}
			return null;
		}
示例#29
0
		private static string NameOf(AbstractTreeIterator i)
		{
			return RawParseUtils.Decode(Constants.CHARSET, i.path, 0, i.pathLen);
		}
示例#30
0
		/// <summary>Create a new iterator with no parent and a prefix.</summary>
		/// <remarks>
		/// Create a new iterator with no parent and a prefix.
		/// <p>
		/// The prefix path supplied is inserted in front of all paths generated by
		/// this iterator. It is intended to be used when an iterator is being
		/// created for a subsection of an overall repository and needs to be
		/// combined with other iterators that are created to run over the entire
		/// repository namespace.
		/// </remarks>
		/// <param name="prefix">
		/// position of this iterator in the repository tree. The value
		/// may be null or the empty string to indicate the prefix is the
		/// root of the repository. A trailing slash ('/') is
		/// automatically appended if the prefix does not end in '/'.
		/// </param>
		protected internal AbstractTreeIterator(string prefix)
		{
			parent = null;
			if (prefix != null && prefix.Length > 0)
			{
				ByteBuffer b;
				b = Constants.CHARSET.Encode(CharBuffer.Wrap(prefix));
				pathLen = b.Limit();
				path = new byte[Math.Max(DEFAULT_PATH_SIZE, pathLen + 1)];
				b.Get(path, 0, pathLen);
				if (path[pathLen - 1] != '/')
				{
					path[pathLen++] = (byte)('/');
				}
				pathOffset = pathLen;
			}
			else
			{
				path = new byte[DEFAULT_PATH_SIZE];
				pathOffset = 0;
			}
		}
示例#31
0
 private static bool NameEqual(AbstractTreeIterator a, AbstractTreeIterator b)
 {
     return(a.PathCompare(b, TREE_MODE) == 0);
 }
 /// <summary>Create an iterator for a subtree of an existing iterator.</summary>
 /// <remarks>
 /// Create an iterator for a subtree of an existing iterator.
 /// <p>
 /// The caller is responsible for setting up the path of the child iterator.
 /// </remarks>
 /// <param name="p">parent tree iterator.</param>
 /// <param name="childPath">
 /// path array to be used by the child iterator. This path must
 /// contain the path from the top of the walk to the first child
 /// and must end with a '/'.
 /// </param>
 /// <param name="childPathOffset">
 /// position within <code>childPath</code> where the child can
 /// insert its data. The value at
 /// <code>childPath[childPathOffset-1]</code> must be '/'.
 /// </param>
 protected internal EmptyTreeIterator(AbstractTreeIterator p, byte[] childPath, int
                                      childPathOffset) : base(p, childPath, childPathOffset)
 {
     pathLen = childPathOffset - 1;
 }
示例#33
0
		/// <summary>Create an iterator for a subtree of an existing iterator.</summary>
		/// <remarks>Create an iterator for a subtree of an existing iterator.</remarks>
		/// <param name="p">parent tree iterator.</param>
		protected internal AbstractTreeIterator(NGit.Treewalk.AbstractTreeIterator p)
		{
			parent = p;
			path = p.path;
			pathOffset = p.pathLen + 1;
			try
			{
				path[pathOffset - 1] = (byte)('/');
			}
			catch (IndexOutOfRangeException)
			{
				GrowPath(p.pathLen);
				path[pathOffset - 1] = (byte)('/');
			}
		}
 private static string NameOf(AbstractTreeIterator i)
 {
     return(RawParseUtils.Decode(Constants.CHARSET, i.path, 0, i.pathLen));
 }
示例#35
0
		/// <summary>
		/// Set the tree used by this walk for finding
		/// <code>.gitmodules</code>
		/// .
		/// <p>
		/// The root tree is not read until the first submodule is encountered by the
		/// walk.
		/// <p>
		/// This method need only be called if constructing a walk manually instead of
		/// with one of the static factory methods above.
		/// </summary>
		/// <param name="tree">tree containing .gitmodules</param>
		/// <returns>this generator</returns>
		public virtual NGit.Submodule.SubmoduleWalk SetRootTree(AbstractTreeIterator tree
			)
		{
			rootTree = tree;
			modulesConfig = null;
			return this;
		}
示例#36
0
        /// <summary>A conflict is detected - add the three different stages to the index</summary>
        /// <param name="path">the path of the conflicting entry</param>
        /// <param name="e">the previous index entry</param>
        /// <param name="h">the first tree you want to merge (the HEAD)</param>
        /// <param name="m">the second tree you want to merge</param>
        private void Conflict(string path, DirCacheEntry e, AbstractTreeIterator h, AbstractTreeIterator
			 m)
        {
            conflicts.AddItem(path);
            DirCacheEntry entry;
            if (e != null)
            {
                entry = new DirCacheEntry(e.PathString, DirCacheEntry.STAGE_1);
                entry.CopyMetaData(e, true);
                builder.Add(entry);
            }
            if (h != null && !FileMode.TREE.Equals(h.EntryFileMode))
            {
                entry = new DirCacheEntry(h.EntryPathString, DirCacheEntry.STAGE_2);
                entry.FileMode = h.EntryFileMode;
                entry.SetObjectId(h.EntryObjectId);
                builder.Add(entry);
            }
            if (m != null && !FileMode.TREE.Equals(m.EntryFileMode))
            {
                entry = new DirCacheEntry(m.EntryPathString, DirCacheEntry.STAGE_3);
                entry.FileMode = m.EntryFileMode;
                entry.SetObjectId(m.EntryObjectId);
                builder.Add(entry);
            }
        }
示例#37
0
		/// <exception cref="NGit.Errors.CorruptObjectException"></exception>
		private AbstractTreeIterator CombineDF(AbstractTreeIterator minRef)
		{
			// Look for a possible D/F conflict forward in the tree(s)
			// as there may be a "$path/" which matches "$path". Make
			// such entries match this entry.
			//
			AbstractTreeIterator treeMatch = null;
			foreach (AbstractTreeIterator t in trees)
			{
				if (t.matches == minRef || t.Eof)
				{
					continue;
				}
				for (; ; )
				{
					int cmp = t.PathCompare(minRef, TREE_MODE);
					if (cmp < 0)
					{
						// The "$path/" may still appear later.
						//
						t.matchShift++;
						t.Next(1);
						if (t.Eof)
						{
							t.Back(t.matchShift);
							t.matchShift = 0;
							break;
						}
					}
					else
					{
						if (cmp == 0)
						{
							// We have a conflict match here.
							//
							t.matches = minRef;
							treeMatch = t;
							break;
						}
						else
						{
							// A conflict match is not possible.
							//
							if (t.matchShift != 0)
							{
								t.Back(t.matchShift);
								t.matchShift = 0;
							}
							break;
						}
					}
				}
			}
			if (treeMatch != null)
			{
				// If we do have a conflict use one of the directory
				// matching iterators instead of the file iterator.
				// This way isSubtree is true and isRecursive works.
				//
				foreach (AbstractTreeIterator t_1 in trees)
				{
					if (t_1.matches == minRef)
					{
						t_1.matches = treeMatch;
					}
				}
				if (dfConflict == null)
				{
					dfConflict = treeMatch;
				}
				return treeMatch;
			}
			return minRef;
		}
示例#38
0
		/// <summary>Set the tree iterator used for finding submodule entries</summary>
		/// <param name="iterator"></param>
		/// <returns>this generator</returns>
		/// <exception cref="NGit.Errors.CorruptObjectException">NGit.Errors.CorruptObjectException
		/// 	</exception>
		public virtual NGit.Submodule.SubmoduleWalk SetTree(AbstractTreeIterator iterator
			)
		{
			walk.AddTree(iterator);
			return this;
		}
示例#39
0
		/// <exception cref="NGit.Errors.CorruptObjectException"></exception>
		internal override void SkipEntriesEqual()
		{
			AbstractTreeIterator ch = currentHead;
			for (int i = 0; i < trees.Length; i++)
			{
				AbstractTreeIterator t = trees[i];
				if (t.matches == ch)
				{
					if (t.matchShift == 0)
					{
						t.Skip();
					}
					else
					{
						t.Back(t.matchShift);
						t.matchShift = 0;
					}
					t.matches = null;
				}
			}
			if (ch == dfConflict)
			{
				dfConflict = null;
			}
		}
示例#40
0
        private AbstractTreeIterator FastMin()
        {
            fastMinHasMatch = true;
            int i = 0;
            AbstractTreeIterator minRef = trees[i];

            while (minRef.Eof && ++i < trees.Length)
            {
                minRef = trees[i];
            }
            if (minRef.Eof)
            {
                return(minRef);
            }
            bool hasConflict = false;

            minRef.matches = minRef;
            while (++i < trees.Length)
            {
                AbstractTreeIterator t = trees[i];
                if (t.Eof)
                {
                    continue;
                }
                int cmp = t.PathCompare(minRef);
                if (cmp < 0)
                {
                    if (fastMinHasMatch && IsTree(minRef) && !IsTree(t) && NameEqual(minRef, t))
                    {
                        // We used to be at a tree, but now we are at a file
                        // with the same name. Allow the file to match the
                        // tree anyway.
                        //
                        t.matches   = minRef;
                        hasConflict = true;
                    }
                    else
                    {
                        fastMinHasMatch = false;
                        t.matches       = t;
                        minRef          = t;
                    }
                }
                else
                {
                    if (cmp == 0)
                    {
                        // Exact name/mode match is best.
                        //
                        t.matches = minRef;
                    }
                    else
                    {
                        if (fastMinHasMatch && IsTree(t) && !IsTree(minRef) && NameEqual(t, minRef))
                        {
                            // The minimum is a file (non-tree) but the next entry
                            // of this iterator is a tree whose name matches our file.
                            // This is a classic D/F conflict and commonly occurs like
                            // this, with no gaps in between the file and directory.
                            //
                            // Use the tree as the minimum instead (see combineDF).
                            //
                            for (int k = 0; k < i; k++)
                            {
                                AbstractTreeIterator p = trees[k];
                                if (p.matches == minRef)
                                {
                                    p.matches = t;
                                }
                            }
                            t.matches   = t;
                            minRef      = t;
                            hasConflict = true;
                        }
                        else
                        {
                            fastMinHasMatch = false;
                        }
                    }
                }
            }
            if (hasConflict && fastMinHasMatch && dfConflict == null)
            {
                dfConflict = minRef;
            }
            return(minRef);
        }
示例#41
0
		/// <summary>Here the main work is done.</summary>
		/// <remarks>
		/// Here the main work is done. This method is called for each existing path
		/// in head, index and merge. This method decides what to do with the
		/// corresponding index entry: keep it, update it, remove it or mark a
		/// conflict.
		/// </remarks>
		/// <param name="h">the entry for the head</param>
		/// <param name="m">the entry for the merge</param>
		/// <param name="i">the entry for the index</param>
		/// <param name="f">the file in the working tree</param>
		/// <exception cref="System.IO.IOException">System.IO.IOException</exception>
		internal virtual void ProcessEntry(AbstractTreeIterator h, AbstractTreeIterator m
			, DirCacheBuildIterator i, WorkingTreeIterator f)
		{
			DirCacheEntry dce;
			string name = walk.PathString;
			if (i == null && m == null && h == null)
			{
				// File/Directory conflict case #20
				if (walk.IsDirectoryFileConflict())
				{
					// TODO: check whether it is always correct to report a conflict here
					Conflict(name, null, null, null);
				}
				// file only exists in working tree -> ignore it
				return;
			}
			ObjectId iId = (i == null ? null : i.EntryObjectId);
			ObjectId mId = (m == null ? null : m.EntryObjectId);
			ObjectId hId = (h == null ? null : h.EntryObjectId);
			// The information whether head,index,merge iterators are currently
			// pointing to file/folder/non-existing is encoded into this variable.
			//
			// To decode write down ffMask in hexadecimal form. The last digit
			// represents the state for the merge iterator, the second last the
			// state for the index iterator and the third last represents the state
			// for the head iterator. The hexadecimal constant "F" stands for
			// "file",
			// an "D" stands for "directory" (tree), and a "0" stands for
			// non-existing
			//
			// Examples:
			// ffMask == 0xFFD -> Head=File, Index=File, Merge=Tree
			// ffMask == 0xDD0 -> Head=Tree, Index=Tree, Merge=Non-Existing
			int ffMask = 0;
			if (h != null)
			{
				ffMask = FileMode.TREE.Equals(h.EntryFileMode) ? unchecked((int)(0xD00)) : unchecked(
					(int)(0xF00));
			}
			if (i != null)
			{
				ffMask |= FileMode.TREE.Equals(i.EntryFileMode) ? unchecked((int)(0x0D0)) : unchecked(
					(int)(0x0F0));
			}
			if (m != null)
			{
				ffMask |= FileMode.TREE.Equals(m.EntryFileMode) ? unchecked((int)(0x00D)) : unchecked(
					(int)(0x00F));
			}
			// Check whether we have a possible file/folder conflict. Therefore we
			// need a least one file and one folder.
			if (((ffMask & unchecked((int)(0x222))) != unchecked((int)(0x000))) && (((ffMask 
				& unchecked((int)(0x00F))) == unchecked((int)(0x00D))) || ((ffMask & unchecked((
				int)(0x0F0))) == unchecked((int)(0x0D0))) || ((ffMask & unchecked((int)(0xF00)))
				 == unchecked((int)(0xD00)))))
			{
				switch (ffMask)
				{
					case unchecked((int)(0xDDF)):
					{
						// There are 3*3*3=27 possible combinations of file/folder
						// conflicts. Some of them are not-relevant because
						// they represent no conflict, e.g. 0xFFF, 0xDDD, ... The following
						// switch processes all relevant cases.
						// 1 2
						if (IsModified(name))
						{
							Conflict(name, i.GetDirCacheEntry(), h, m);
						}
						else
						{
							// 1
							Update(name, m.EntryObjectId, m.EntryFileMode);
						}
						// 2
						break;
					}

					case unchecked((int)(0xDFD)):
					{
						// 3 4
						// CAUTION: I put it into removed instead of updated, because
						// that's what our tests expect
						// updated.put(name, mId);
						Remove(name);
						break;
					}

					case unchecked((int)(0xF0D)):
					{
						// 18
						Remove(name);
						break;
					}

					case unchecked((int)(0xDFF)):
					case unchecked((int)(0xFDD)):
					{
						// 5 6
						// 10 11
						// TODO: make use of tree extension as soon as available in jgit
						// we would like to do something like
						// if (!iId.equals(mId))
						//   conflict(name, i.getDirCacheEntry(), h, m);
						// But since we don't know the id of a tree in the index we do
						// nothing here and wait that conflicts between index and merge
						// are found later
						break;
					}

					case unchecked((int)(0xD0F)):
					{
						// 19
						Update(name, mId, m.EntryFileMode);
						break;
					}

					case unchecked((int)(0xDF0)):
					case unchecked((int)(0x0FD)):
					{
						// conflict without a rule
						// 15
						Conflict(name, (i != null) ? i.GetDirCacheEntry() : null, h, m);
						break;
					}

					case unchecked((int)(0xFDF)):
					{
						// 7 8 9
						if (hId.Equals(mId))
						{
							if (IsModified(name))
							{
								Conflict(name, i.GetDirCacheEntry(), h, m);
							}
							else
							{
								// 8
								Update(name, mId, m.EntryFileMode);
							}
						}
						else
						{
							// 7
							if (!IsModified(name))
							{
								Update(name, mId, m.EntryFileMode);
							}
							else
							{
								// 9
								// To be confirmed - this case is not in the table.
								Conflict(name, i.GetDirCacheEntry(), h, m);
							}
						}
						break;
					}

					case unchecked((int)(0xFD0)):
					{
						// keep without a rule
						Keep(i.GetDirCacheEntry());
						break;
					}

					case unchecked((int)(0xFFD)):
					{
						// 12 13 14
						if (hId.Equals(iId))
						{
							dce = i.GetDirCacheEntry();
							if (f == null || f.IsModified(dce, true))
							{
								Conflict(name, i.GetDirCacheEntry(), h, m);
							}
							else
							{
								Remove(name);
							}
						}
						else
						{
							Conflict(name, i.GetDirCacheEntry(), h, m);
						}
						break;
					}

					case unchecked((int)(0x0DF)):
					{
						// 16 17
						if (!IsModified(name))
						{
							Update(name, mId, m.EntryFileMode);
						}
						else
						{
							Conflict(name, i.GetDirCacheEntry(), h, m);
						}
						break;
					}

					default:
					{
						Keep(i.GetDirCacheEntry());
						break;
					}
				}
				return;
			}
			// if we have no file at all then there is nothing to do
			if ((ffMask & unchecked((int)(0x222))) == 0)
			{
				return;
			}
			if ((ffMask == unchecked((int)(0x00F))) && f != null && FileMode.TREE.Equals(f.EntryFileMode
				))
			{
				// File/Directory conflict case #20
				Conflict(name, null, h, m);
			}
			if (i == null)
			{
				if (h == null)
				{
					Update(name, mId, m.EntryFileMode);
				}
				else
				{
					// 1
					if (m == null)
					{
						Remove(name);
					}
					else
					{
						// 2
						Update(name, mId, m.EntryFileMode);
					}
				}
			}
			else
			{
				// 3
				dce = i.GetDirCacheEntry();
				if (h == null)
				{
					if (m == null || mId.Equals(iId))
					{
						if (m == null && walk.IsDirectoryFileConflict())
						{
							if (dce != null && (f == null || f.IsModified(dce, true)))
							{
								Conflict(name, i.GetDirCacheEntry(), h, m);
							}
							else
							{
								Remove(name);
							}
						}
						else
						{
							Keep(i.GetDirCacheEntry());
						}
					}
					else
					{
						Conflict(name, i.GetDirCacheEntry(), h, m);
					}
				}
				else
				{
					if (m == null)
					{
						if (hId.Equals(iId))
						{
							if (f == null || f.IsModified(dce, true))
							{
								Conflict(name, i.GetDirCacheEntry(), h, m);
							}
							else
							{
								Remove(name);
							}
						}
						else
						{
							Conflict(name, i.GetDirCacheEntry(), h, m);
						}
					}
					else
					{
						if (!hId.Equals(mId) && !hId.Equals(iId) && !mId.Equals(iId))
						{
							Conflict(name, i.GetDirCacheEntry(), h, m);
						}
						else
						{
							if (hId.Equals(iId) && !mId.Equals(iId))
							{
								if (dce != null && (f == null || f.IsModified(dce, true)))
								{
									Conflict(name, i.GetDirCacheEntry(), h, m);
								}
								else
								{
									Update(name, mId, m.EntryFileMode);
								}
							}
							else
							{
								Keep(i.GetDirCacheEntry());
							}
						}
					}
				}
			}
		}
示例#42
0
 private static bool IsTree(AbstractTreeIterator p)
 {
     return(FileMode.TREE.Equals(p.mode));
 }
示例#43
0
		private AbstractTreeIterator FastMin()
		{
			fastMinHasMatch = true;
			int i = 0;
			AbstractTreeIterator minRef = trees[i];
			while (minRef.Eof && ++i < trees.Length)
			{
				minRef = trees[i];
			}
			if (minRef.Eof)
			{
				return minRef;
			}
			bool hasConflict = false;
			minRef.matches = minRef;
			while (++i < trees.Length)
			{
				AbstractTreeIterator t = trees[i];
				if (t.Eof)
				{
					continue;
				}
				int cmp = t.PathCompare(minRef);
				if (cmp < 0)
				{
					if (fastMinHasMatch && IsTree(minRef) && !IsTree(t) && NameEqual(minRef, t))
					{
						// We used to be at a tree, but now we are at a file
						// with the same name. Allow the file to match the
						// tree anyway.
						//
						t.matches = minRef;
						hasConflict = true;
					}
					else
					{
						fastMinHasMatch = false;
						t.matches = t;
						minRef = t;
					}
				}
				else
				{
					if (cmp == 0)
					{
						// Exact name/mode match is best.
						//
						t.matches = minRef;
					}
					else
					{
						if (fastMinHasMatch && IsTree(t) && !IsTree(minRef) && NameEqual(t, minRef))
						{
							// The minimum is a file (non-tree) but the next entry
							// of this iterator is a tree whose name matches our file.
							// This is a classic D/F conflict and commonly occurs like
							// this, with no gaps in between the file and directory.
							//
							// Use the tree as the minimum instead (see combineDF).
							//
							for (int k = 0; k < i; k++)
							{
								AbstractTreeIterator p = trees[k];
								if (p.matches == minRef)
								{
									p.matches = t;
								}
							}
							t.matches = t;
							minRef = t;
							hasConflict = true;
						}
						else
						{
							fastMinHasMatch = false;
						}
					}
				}
			}
			if (hasConflict && fastMinHasMatch && dfConflict == null)
			{
				dfConflict = minRef;
			}
			return minRef;
		}
示例#44
0
        /// <exception cref="NGit.Errors.CorruptObjectException"></exception>
        private AbstractTreeIterator CombineDF(AbstractTreeIterator minRef)
        {
            // Look for a possible D/F conflict forward in the tree(s)
            // as there may be a "$path/" which matches "$path". Make
            // such entries match this entry.
            //
            AbstractTreeIterator treeMatch = null;

            foreach (AbstractTreeIterator t in trees)
            {
                if (t.matches == minRef || t.Eof)
                {
                    continue;
                }
                for (; ;)
                {
                    int cmp = t.PathCompare(minRef, TREE_MODE);
                    if (cmp < 0)
                    {
                        // The "$path/" may still appear later.
                        //
                        t.matchShift++;
                        t.Next(1);
                        if (t.Eof)
                        {
                            t.Back(t.matchShift);
                            t.matchShift = 0;
                            break;
                        }
                    }
                    else
                    {
                        if (cmp == 0)
                        {
                            // We have a conflict match here.
                            //
                            t.matches = minRef;
                            treeMatch = t;
                            break;
                        }
                        else
                        {
                            // A conflict match is not possible.
                            //
                            if (t.matchShift != 0)
                            {
                                t.Back(t.matchShift);
                                t.matchShift = 0;
                            }
                            break;
                        }
                    }
                }
            }
            if (treeMatch != null)
            {
                // If we do have a conflict use one of the directory
                // matching iterators instead of the file iterator.
                // This way isSubtree is true and isRecursive works.
                //
                foreach (AbstractTreeIterator t_1 in trees)
                {
                    if (t_1.matches == minRef)
                    {
                        t_1.matches = treeMatch;
                    }
                }
                if (dfConflict == null)
                {
                    dfConflict = treeMatch;
                }
                return(treeMatch);
            }
            return(minRef);
        }
示例#45
0
		private static bool NameEqual(AbstractTreeIterator a, AbstractTreeIterator b)
		{
			return a.PathCompare(b, TREE_MODE) == 0;
		}
示例#46
0
		/// <summary>Create a new iterator with no parent.</summary>
		/// <remarks>Create a new iterator with no parent.</remarks>
		public AbstractTreeIterator()
		{
			parent = null;
			path = new byte[DEFAULT_PATH_SIZE];
			pathOffset = 0;
		}
示例#47
0
		private static bool IsTree(AbstractTreeIterator p)
		{
			return FileMode.TREE.Equals(p.mode);
		}
示例#48
0
		/// <summary>Create a new iterator with no parent and a prefix.</summary>
		/// <remarks>
		/// Create a new iterator with no parent and a prefix.
		/// <p>
		/// The prefix path supplied is inserted in front of all paths generated by
		/// this iterator. It is intended to be used when an iterator is being
		/// created for a subsection of an overall repository and needs to be
		/// combined with other iterators that are created to run over the entire
		/// repository namespace.
		/// </remarks>
		/// <param name="prefix">
		/// position of this iterator in the repository tree. The value
		/// may be null or the empty array to indicate the prefix is the
		/// root of the repository. A trailing slash ('/') is
		/// automatically appended if the prefix does not end in '/'.
		/// </param>
		protected internal AbstractTreeIterator(byte[] prefix)
		{
			parent = null;
			if (prefix != null && prefix.Length > 0)
			{
				pathLen = prefix.Length;
				path = new byte[Math.Max(DEFAULT_PATH_SIZE, pathLen + 1)];
				System.Array.Copy(prefix, 0, path, 0, pathLen);
				if (path[pathLen - 1] != '/')
				{
					path[pathLen++] = (byte)('/');
				}
				pathOffset = pathLen;
			}
			else
			{
				path = new byte[DEFAULT_PATH_SIZE];
				pathOffset = 0;
			}
		}
示例#49
0
		/// <exception cref="NGit.Errors.CorruptObjectException"></exception>
		private bool SkipEntry(AbstractTreeIterator minRef)
		{
			// A tree D/F may have been handled earlier. We need to
			// not report this path if it has already been reported.
			//
			foreach (AbstractTreeIterator t in trees)
			{
				if (t.matches == minRef || t.First)
				{
					continue;
				}
				int stepsBack = 0;
				for (; ; )
				{
					stepsBack++;
					t.Back(1);
					int cmp = t.PathCompare(minRef, 0);
					if (cmp == 0)
					{
						// We have already seen this "$path" before. Skip it.
						//
						t.Next(stepsBack);
						return true;
					}
					else
					{
						if (cmp < 0 || t.First)
						{
							// We cannot find "$path" in t; it will never appear.
							//
							t.Next(stepsBack);
							break;
						}
					}
				}
			}
			// We have never seen the current path before.
			//
			return false;
		}
示例#50
0
		/// <summary>Create an iterator for a subtree of an existing iterator.</summary>
		/// <remarks>
		/// Create an iterator for a subtree of an existing iterator.
		/// <p>
		/// The caller is responsible for setting up the path of the child iterator.
		/// </remarks>
		/// <param name="p">parent tree iterator.</param>
		/// <param name="childPath">
		/// path array to be used by the child iterator. This path must
		/// contain the path from the top of the walk to the first child
		/// and must end with a '/'.
		/// </param>
		/// <param name="childPathOffset">
		/// position within <code>childPath</code> where the child can
		/// insert its data. The value at
		/// <code>childPath[childPathOffset-1]</code> must be '/'.
		/// </param>
		protected internal AbstractTreeIterator(NGit.Treewalk.AbstractTreeIterator p, byte
			[] childPath, int childPathOffset)
		{
			parent = p;
			path = childPath;
			pathOffset = childPathOffset;
		}
示例#51
0
		/// <summary>
		/// Create a generator and advance it to the submodule entry at the given
		/// path
		/// </summary>
		/// <param name="repository"></param>
		/// <param name="iterator">
		/// the root of a tree containing both a submodule at the given path
		/// and .gitmodules at the root.
		/// </param>
		/// <param name="path"></param>
		/// <returns>generator at given path, null if no submodule at given path</returns>
		/// <exception cref="System.IO.IOException">System.IO.IOException</exception>
		public static NGit.Submodule.SubmoduleWalk ForPath(Repository repository, AbstractTreeIterator
			 iterator, string path)
		{
			NGit.Submodule.SubmoduleWalk generator = new NGit.Submodule.SubmoduleWalk(repository
				);
			try
			{
				generator.SetTree(iterator);
				PathFilter filter = PathFilter.Create(path);
				generator.SetFilter(filter);
				generator.SetRootTree(iterator);
				while (generator.Next())
				{
					if (filter.IsDone(generator.walk))
					{
						return generator;
					}
				}
			}
			catch (IOException e)
			{
				generator.Release();
				throw;
			}
			generator.Release();
			return null;
		}