AbstractTreeIterator.java

  1. /*
  2.  * Copyright (C) 2008-2009, Google Inc.
  3.  * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
  4.  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
  5.  *
  6.  * This program and the accompanying materials are made available under the
  7.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  8.  * https://www.eclipse.org/org/documents/edl-v10.php.
  9.  *
  10.  * SPDX-License-Identifier: BSD-3-Clause
  11.  */

  12. package org.eclipse.jgit.treewalk;

  13. import static java.nio.charset.StandardCharsets.UTF_8;

  14. import java.io.IOException;
  15. import java.nio.ByteBuffer;
  16. import java.nio.CharBuffer;

  17. import org.eclipse.jgit.attributes.AttributesHandler;
  18. import org.eclipse.jgit.attributes.AttributesNode;
  19. import org.eclipse.jgit.errors.CorruptObjectException;
  20. import org.eclipse.jgit.errors.IncorrectObjectTypeException;
  21. import org.eclipse.jgit.lib.Constants;
  22. import org.eclipse.jgit.lib.FileMode;
  23. import org.eclipse.jgit.lib.MutableObjectId;
  24. import org.eclipse.jgit.lib.ObjectId;
  25. import org.eclipse.jgit.lib.ObjectReader;
  26. import org.eclipse.jgit.util.Paths;

  27. /**
  28.  * Walks a Git tree (directory) in Git sort order.
  29.  * <p>
  30.  * A new iterator instance should be positioned on the first entry, or at eof.
  31.  * Data for the first entry (if not at eof) should be available immediately.
  32.  * <p>
  33.  * Implementors must walk a tree in the Git sort order, which has the following
  34.  * odd sorting:
  35.  * <ol>
  36.  * <li>A.c</li>
  37.  * <li>A/c</li>
  38.  * <li>A0c</li>
  39.  * </ol>
  40.  * <p>
  41.  * In the second item, <code>A</code> is the name of a subtree and
  42.  * <code>c</code> is a file within that subtree. The other two items are files
  43.  * in the root level tree.
  44.  *
  45.  * @see CanonicalTreeParser
  46.  */
  47. public abstract class AbstractTreeIterator {
  48.     /** Default size for the {@link #path} buffer. */
  49.     protected static final int DEFAULT_PATH_SIZE = 128;

  50.     /** A dummy object id buffer that matches the zero ObjectId. */
  51.     protected static final byte[] zeroid = new byte[Constants.OBJECT_ID_LENGTH];

  52.     /**
  53.      * Iterator for the parent tree; null if we are the root iterator.
  54.      * <p>
  55.      * Used by {@link TreeWalk} and {@link AttributesHandler}
  56.      *
  57.      * @since 4.3
  58.      */
  59.     public final AbstractTreeIterator parent;

  60.     /** The iterator this current entry is path equal to. */
  61.     AbstractTreeIterator matches;

  62.     /**
  63.      * Parsed rules of .gitattributes file if it exists.
  64.      *
  65.      * @since 4.2
  66.      */
  67.     protected AttributesNode attributesNode;

  68.     /**
  69.      * Number of entries we moved forward to force a D/F conflict match.
  70.      *
  71.      * @see NameConflictTreeWalk
  72.      */
  73.     int matchShift;

  74.     /**
  75.      * Mode bits for the current entry.
  76.      * <p>
  77.      * A numerical value from FileMode is usually faster for an iterator to
  78.      * obtain from its data source so this is the preferred representation.
  79.      *
  80.      * @see org.eclipse.jgit.lib.FileMode
  81.      */
  82.     protected int mode;

  83.     /**
  84.      * Path buffer for the current entry.
  85.      * <p>
  86.      * This buffer is pre-allocated at the start of walking and is shared from
  87.      * parent iterators down into their subtree iterators. The sharing allows
  88.      * the current entry to always be a full path from the root, while each
  89.      * subtree only needs to populate the part that is under their control.
  90.      */
  91.     protected byte[] path;

  92.     /**
  93.      * Position within {@link #path} this iterator starts writing at.
  94.      * <p>
  95.      * This is the first offset in {@link #path} that this iterator must
  96.      * populate during {@link #next}. At the root level (when {@link #parent}
  97.      * is null) this is 0. For a subtree iterator the index before this position
  98.      * should have the value '/'.
  99.      */
  100.     protected final int pathOffset;

  101.     /**
  102.      * Total length of the current entry's complete path from the root.
  103.      * <p>
  104.      * This is the number of bytes within {@link #path} that pertain to the
  105.      * current entry. Values at this index through the end of the array are
  106.      * garbage and may be randomly populated from prior entries.
  107.      */
  108.     protected int pathLen;

  109.     /**
  110.      * Create a new iterator with no parent.
  111.      */
  112.     protected AbstractTreeIterator() {
  113.         parent = null;
  114.         path = new byte[DEFAULT_PATH_SIZE];
  115.         pathOffset = 0;
  116.     }

  117.     /**
  118.      * Create a new iterator with no parent and a prefix.
  119.      * <p>
  120.      * The prefix path supplied is inserted in front of all paths generated by
  121.      * this iterator. It is intended to be used when an iterator is being
  122.      * created for a subsection of an overall repository and needs to be
  123.      * combined with other iterators that are created to run over the entire
  124.      * repository namespace.
  125.      *
  126.      * @param prefix
  127.      *            position of this iterator in the repository tree. The value
  128.      *            may be null or the empty string to indicate the prefix is the
  129.      *            root of the repository. A trailing slash ('/') is
  130.      *            automatically appended if the prefix does not end in '/'.
  131.      */
  132.     protected AbstractTreeIterator(String prefix) {
  133.         parent = null;

  134.         if (prefix != null && prefix.length() > 0) {
  135.             final ByteBuffer b;

  136.             b = UTF_8.encode(CharBuffer.wrap(prefix));
  137.             pathLen = b.limit();
  138.             path = new byte[Math.max(DEFAULT_PATH_SIZE, pathLen + 1)];
  139.             b.get(path, 0, pathLen);
  140.             if (path[pathLen - 1] != '/')
  141.                 path[pathLen++] = '/';
  142.             pathOffset = pathLen;
  143.         } else {
  144.             path = new byte[DEFAULT_PATH_SIZE];
  145.             pathOffset = 0;
  146.         }
  147.     }

  148.     /**
  149.      * Create a new iterator with no parent and a prefix.
  150.      * <p>
  151.      * The prefix path supplied is inserted in front of all paths generated by
  152.      * this iterator. It is intended to be used when an iterator is being
  153.      * created for a subsection of an overall repository and needs to be
  154.      * combined with other iterators that are created to run over the entire
  155.      * repository namespace.
  156.      *
  157.      * @param prefix
  158.      *            position of this iterator in the repository tree. The value
  159.      *            may be null or the empty array to indicate the prefix is the
  160.      *            root of the repository. A trailing slash ('/') is
  161.      *            automatically appended if the prefix does not end in '/'.
  162.      */
  163.     protected AbstractTreeIterator(byte[] prefix) {
  164.         parent = null;

  165.         if (prefix != null && prefix.length > 0) {
  166.             pathLen = prefix.length;
  167.             path = new byte[Math.max(DEFAULT_PATH_SIZE, pathLen + 1)];
  168.             System.arraycopy(prefix, 0, path, 0, pathLen);
  169.             if (path[pathLen - 1] != '/')
  170.                 path[pathLen++] = '/';
  171.             pathOffset = pathLen;
  172.         } else {
  173.             path = new byte[DEFAULT_PATH_SIZE];
  174.             pathOffset = 0;
  175.         }
  176.     }

  177.     /**
  178.      * Create an iterator for a subtree of an existing iterator.
  179.      *
  180.      * @param p
  181.      *            parent tree iterator.
  182.      */
  183.     protected AbstractTreeIterator(AbstractTreeIterator p) {
  184.         parent = p;
  185.         path = p.path;
  186.         pathOffset = p.pathLen + 1;

  187.         if (pathOffset > path.length) {
  188.             growPath(p.pathLen);
  189.         }
  190.         path[pathOffset - 1] = '/';
  191.     }

  192.     /**
  193.      * Create an iterator for a subtree of an existing iterator.
  194.      * <p>
  195.      * The caller is responsible for setting up the path of the child iterator.
  196.      *
  197.      * @param p
  198.      *            parent tree iterator.
  199.      * @param childPath
  200.      *            path array to be used by the child iterator. This path must
  201.      *            contain the path from the top of the walk to the first child
  202.      *            and must end with a '/'.
  203.      * @param childPathOffset
  204.      *            position within <code>childPath</code> where the child can
  205.      *            insert its data. The value at
  206.      *            <code>childPath[childPathOffset-1]</code> must be '/'.
  207.      */
  208.     protected AbstractTreeIterator(final AbstractTreeIterator p,
  209.             final byte[] childPath, final int childPathOffset) {
  210.         parent = p;
  211.         path = childPath;
  212.         pathOffset = childPathOffset;
  213.     }

  214.     /**
  215.      * Grow the path buffer larger.
  216.      *
  217.      * @param len
  218.      *            number of live bytes in the path buffer. This many bytes will
  219.      *            be moved into the larger buffer.
  220.      */
  221.     protected void growPath(int len) {
  222.         setPathCapacity(path.length << 1, len);
  223.     }

  224.     /**
  225.      * Ensure that path is capable to hold at least {@code capacity} bytes
  226.      *
  227.      * @param capacity
  228.      *            the amount of bytes to hold
  229.      * @param len
  230.      *            the amount of live bytes in path buffer
  231.      */
  232.     protected void ensurePathCapacity(int capacity, int len) {
  233.         if (path.length >= capacity)
  234.             return;
  235.         final byte[] o = path;
  236.         int current = o.length;
  237.         int newCapacity = current;
  238.         while (newCapacity < capacity && newCapacity > 0)
  239.             newCapacity <<= 1;
  240.         setPathCapacity(newCapacity, len);
  241.     }

  242.     /**
  243.      * Set path buffer capacity to the specified size
  244.      *
  245.      * @param capacity
  246.      *            the new size
  247.      * @param len
  248.      *            the amount of bytes to copy
  249.      */
  250.     private void setPathCapacity(int capacity, int len) {
  251.         final byte[] o = path;
  252.         final byte[] n = new byte[capacity];
  253.         System.arraycopy(o, 0, n, 0, len);
  254.         for (AbstractTreeIterator p = this; p != null && p.path == o; p = p.parent)
  255.             p.path = n;
  256.     }

  257.     /**
  258.      * Compare the path of this current entry to another iterator's entry.
  259.      *
  260.      * @param p
  261.      *            the other iterator to compare the path against.
  262.      * @return -1 if this entry sorts first; 0 if the entries are equal; 1 if
  263.      *         p's entry sorts first.
  264.      */
  265.     public int pathCompare(AbstractTreeIterator p) {
  266.         return pathCompare(p, p.mode);
  267.     }

  268.     int pathCompare(AbstractTreeIterator p, int pMode) {
  269.         // Its common when we are a subtree for both parents to match;
  270.         // when this happens everything in path[0..cPos] is known to
  271.         // be equal and does not require evaluation again.
  272.         //
  273.         int cPos = alreadyMatch(this, p);
  274.         return pathCompare(p.path, cPos, p.pathLen, pMode, cPos);
  275.     }

  276.     /**
  277.      * Seek the iterator on a file, if present.
  278.      *
  279.      * @param name
  280.      *            file name to find (will not find a directory).
  281.      * @return true if the file exists in this tree; false otherwise.
  282.      * @throws org.eclipse.jgit.errors.CorruptObjectException
  283.      *             tree is invalid.
  284.      * @since 4.2
  285.      */
  286.     public boolean findFile(String name) throws CorruptObjectException {
  287.         return findFile(Constants.encode(name));
  288.     }

  289.     /**
  290.      * Seek the iterator on a file, if present.
  291.      *
  292.      * @param name
  293.      *            file name to find (will not find a directory).
  294.      * @return true if the file exists in this tree; false otherwise.
  295.      * @throws org.eclipse.jgit.errors.CorruptObjectException
  296.      *             tree is invalid.
  297.      * @since 4.2
  298.      */
  299.     public boolean findFile(byte[] name) throws CorruptObjectException {
  300.         for (; !eof(); next(1)) {
  301.             int cmp = pathCompare(name, 0, name.length, 0, pathOffset);
  302.             if (cmp == 0) {
  303.                 return true;
  304.             } else if (cmp > 0) {
  305.                 return false;
  306.             }
  307.         }
  308.         return false;
  309.     }

  310.     /**
  311.      * Compare the path of this current entry to a raw buffer.
  312.      *
  313.      * @param buf
  314.      *            the raw path buffer.
  315.      * @param pos
  316.      *            position to start reading the raw buffer.
  317.      * @param end
  318.      *            one past the end of the raw buffer (length is end - pos).
  319.      * @param pathMode
  320.      *            the mode of the path.
  321.      * @return -1 if this entry sorts first; 0 if the entries are equal; 1 if
  322.      *         p's entry sorts first.
  323.      */
  324.     public int pathCompare(byte[] buf, int pos, int end, int pathMode) {
  325.         return pathCompare(buf, pos, end, pathMode, 0);
  326.     }

  327.     private int pathCompare(byte[] b, int bPos, int bEnd, int bMode, int aPos) {
  328.         return Paths.compare(
  329.                 path, aPos, pathLen, mode,
  330.                 b, bPos, bEnd, bMode);
  331.     }

  332.     private static int alreadyMatch(AbstractTreeIterator a,
  333.             AbstractTreeIterator b) {
  334.         for (;;) {
  335.             final AbstractTreeIterator ap = a.parent;
  336.             final AbstractTreeIterator bp = b.parent;
  337.             if (ap == null || bp == null)
  338.                 return 0;
  339.             if (ap.matches == bp.matches)
  340.                 return a.pathOffset;
  341.             a = ap;
  342.             b = bp;
  343.         }
  344.     }

  345.     /**
  346.      * Check if the current entry of both iterators has the same id.
  347.      * <p>
  348.      * This method is faster than {@link #getEntryObjectId()} as it does not
  349.      * require copying the bytes out of the buffers. A direct {@link #idBuffer}
  350.      * compare operation is performed.
  351.      *
  352.      * @param otherIterator
  353.      *            the other iterator to test against.
  354.      * @return true if both iterators have the same object id; false otherwise.
  355.      */
  356.     public boolean idEqual(AbstractTreeIterator otherIterator) {
  357.         return ObjectId.equals(idBuffer(), idOffset(),
  358.                 otherIterator.idBuffer(), otherIterator.idOffset());
  359.     }

  360.     /**
  361.      * Whether the entry has a valid ObjectId.
  362.      *
  363.      * @return {@code true} if the entry has a valid ObjectId.
  364.      */
  365.     public abstract boolean hasId();

  366.     /**
  367.      * Get the object id of the current entry.
  368.      *
  369.      * @return an object id for the current entry.
  370.      */
  371.     public ObjectId getEntryObjectId() {
  372.         return ObjectId.fromRaw(idBuffer(), idOffset());
  373.     }

  374.     /**
  375.      * Obtain the ObjectId for the current entry.
  376.      *
  377.      * @param out
  378.      *            buffer to copy the object id into.
  379.      */
  380.     public void getEntryObjectId(MutableObjectId out) {
  381.         out.fromRaw(idBuffer(), idOffset());
  382.     }

  383.     /**
  384.      * Get the file mode of the current entry.
  385.      *
  386.      * @return the file mode of the current entry.
  387.      */
  388.     public FileMode getEntryFileMode() {
  389.         return FileMode.fromBits(mode);
  390.     }

  391.     /**
  392.      * Get the file mode of the current entry as bits.
  393.      *
  394.      * @return the file mode of the current entry as bits.
  395.      */
  396.     public int getEntryRawMode() {
  397.         return mode;
  398.     }

  399.     /**
  400.      * Get path of the current entry, as a string.
  401.      *
  402.      * @return path of the current entry, as a string.
  403.      */
  404.     public String getEntryPathString() {
  405.         return TreeWalk.pathOf(this);
  406.     }

  407.     /**
  408.      * Get the current entry path buffer.
  409.      * <p>
  410.      * Note that the returned byte[] has to be used together with
  411.      * {@link #getEntryPathLength()} (only use bytes up to this length).
  412.      *
  413.      * @return the internal buffer holding the current path.
  414.      */
  415.     public byte[] getEntryPathBuffer() {
  416.         return path;
  417.     }

  418.     /**
  419.      * Get length of the path in {@link #getEntryPathBuffer()}.
  420.      *
  421.      * @return length of the path in {@link #getEntryPathBuffer()}.
  422.      */
  423.     public int getEntryPathLength() {
  424.         return pathLen;
  425.     }

  426.     /**
  427.      * Get the current entry's path hash code.
  428.      * <p>
  429.      * This method computes a hash code on the fly for this path, the hash is
  430.      * suitable to cluster objects that may have similar paths together.
  431.      *
  432.      * @return path hash code; any integer may be returned.
  433.      */
  434.     public int getEntryPathHashCode() {
  435.         int hash = 0;
  436.         for (int i = Math.max(0, pathLen - 16); i < pathLen; i++) {
  437.             byte c = path[i];
  438.             if (c != ' ')
  439.                 hash = (hash >>> 2) + (c << 24);
  440.         }
  441.         return hash;
  442.     }

  443.     /**
  444.      * Get the byte array buffer object IDs must be copied out of.
  445.      * <p>
  446.      * The id buffer contains the bytes necessary to construct an ObjectId for
  447.      * the current entry of this iterator. The buffer can be the same buffer for
  448.      * all entries, or it can be a unique buffer per-entry. Implementations are
  449.      * encouraged to expose their private buffer whenever possible to reduce
  450.      * garbage generation and copying costs.
  451.      *
  452.      * @return byte array the implementation stores object IDs within.
  453.      * @see #getEntryObjectId()
  454.      */
  455.     public abstract byte[] idBuffer();

  456.     /**
  457.      * Get the position within {@link #idBuffer()} of this entry's ObjectId.
  458.      *
  459.      * @return offset into the array returned by {@link #idBuffer()} where the
  460.      *         ObjectId must be copied out of.
  461.      */
  462.     public abstract int idOffset();

  463.     /**
  464.      * Create a new iterator for the current entry's subtree.
  465.      * <p>
  466.      * The parent reference of the iterator must be <code>this</code>,
  467.      * otherwise the caller would not be able to exit out of the subtree
  468.      * iterator correctly and return to continue walking <code>this</code>.
  469.      *
  470.      * @param reader
  471.      *            reader to load the tree data from.
  472.      * @return a new parser that walks over the current subtree.
  473.      * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
  474.      *             the current entry is not actually a tree and cannot be parsed
  475.      *             as though it were a tree.
  476.      * @throws java.io.IOException
  477.      *             a loose object or pack file could not be read.
  478.      */
  479.     public abstract AbstractTreeIterator createSubtreeIterator(
  480.             ObjectReader reader) throws IncorrectObjectTypeException,
  481.             IOException;

  482.     /**
  483.      * Create a new iterator as though the current entry were a subtree.
  484.      *
  485.      * @return a new empty tree iterator.
  486.      */
  487.     public EmptyTreeIterator createEmptyTreeIterator() {
  488.         return new EmptyTreeIterator(this);
  489.     }

  490.     /**
  491.      * Create a new iterator for the current entry's subtree.
  492.      * <p>
  493.      * The parent reference of the iterator must be <code>this</code>, otherwise
  494.      * the caller would not be able to exit out of the subtree iterator
  495.      * correctly and return to continue walking <code>this</code>.
  496.      *
  497.      * @param reader
  498.      *            reader to load the tree data from.
  499.      * @param idBuffer
  500.      *            temporary ObjectId buffer for use by this method.
  501.      * @return a new parser that walks over the current subtree.
  502.      * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
  503.      *             the current entry is not actually a tree and cannot be parsed
  504.      *             as though it were a tree.
  505.      * @throws java.io.IOException
  506.      *             a loose object or pack file could not be read.
  507.      */
  508.     public AbstractTreeIterator createSubtreeIterator(
  509.             final ObjectReader reader, final MutableObjectId idBuffer)
  510.             throws IncorrectObjectTypeException, IOException {
  511.         return createSubtreeIterator(reader);
  512.     }

  513.     /**
  514.      * Position this iterator on the first entry.
  515.      *
  516.      * The default implementation of this method uses {@code back(1)} until
  517.      * {@code first()} is true. This is most likely not the most efficient
  518.      * method of repositioning the iterator to its first entry, so subclasses
  519.      * are strongly encouraged to override the method.
  520.      *
  521.      * @throws org.eclipse.jgit.errors.CorruptObjectException
  522.      *             the tree is invalid.
  523.      */
  524.     public void reset() throws CorruptObjectException {
  525.         while (!first())
  526.             back(1);
  527.     }

  528.     /**
  529.      * Is this tree iterator positioned on its first entry?
  530.      * <p>
  531.      * An iterator is positioned on the first entry if <code>back(1)</code>
  532.      * would be an invalid request as there is no entry before the current one.
  533.      * <p>
  534.      * An empty iterator (one with no entries) will be
  535.      * <code>first() &amp;&amp; eof()</code>.
  536.      *
  537.      * @return true if the iterator is positioned on the first entry.
  538.      */
  539.     public abstract boolean first();

  540.     /**
  541.      * Is this tree iterator at its EOF point (no more entries)?
  542.      * <p>
  543.      * An iterator is at EOF if there is no current entry.
  544.      *
  545.      * @return true if we have walked all entries and have none left.
  546.      */
  547.     public abstract boolean eof();

  548.     /**
  549.      * Move to next entry, populating this iterator with the entry data.
  550.      * <p>
  551.      * The delta indicates how many moves forward should occur. The most common
  552.      * delta is 1 to move to the next entry.
  553.      * <p>
  554.      * Implementations must populate the following members:
  555.      * <ul>
  556.      * <li>{@link #mode}</li>
  557.      * <li>{@link #path} (from {@link #pathOffset} to {@link #pathLen})</li>
  558.      * <li>{@link #pathLen}</li>
  559.      * </ul>
  560.      * as well as any implementation dependent information necessary to
  561.      * accurately return data from {@link #idBuffer()} and {@link #idOffset()}
  562.      * when demanded.
  563.      *
  564.      * @param delta
  565.      *            number of entries to move the iterator by. Must be a positive,
  566.      *            non-zero integer.
  567.      * @throws org.eclipse.jgit.errors.CorruptObjectException
  568.      *             the tree is invalid.
  569.      */
  570.     public abstract void next(int delta) throws CorruptObjectException;

  571.     /**
  572.      * Move to prior entry, populating this iterator with the entry data.
  573.      * <p>
  574.      * The delta indicates how many moves backward should occur.The most common
  575.      * delta is 1 to move to the prior entry.
  576.      * <p>
  577.      * Implementations must populate the following members:
  578.      * <ul>
  579.      * <li>{@link #mode}</li>
  580.      * <li>{@link #path} (from {@link #pathOffset} to {@link #pathLen})</li>
  581.      * <li>{@link #pathLen}</li>
  582.      * </ul>
  583.      * as well as any implementation dependent information necessary to
  584.      * accurately return data from {@link #idBuffer()} and {@link #idOffset()}
  585.      * when demanded.
  586.      *
  587.      * @param delta
  588.      *            number of entries to move the iterator by. Must be a positive,
  589.      *            non-zero integer.
  590.      * @throws org.eclipse.jgit.errors.CorruptObjectException
  591.      *             the tree is invalid.
  592.      */
  593.     public abstract void back(int delta) throws CorruptObjectException;

  594.     /**
  595.      * Advance to the next tree entry, populating this iterator with its data.
  596.      * <p>
  597.      * This method behaves like <code>seek(1)</code> but is called by
  598.      * {@link org.eclipse.jgit.treewalk.TreeWalk} only if a
  599.      * {@link org.eclipse.jgit.treewalk.filter.TreeFilter} was used and ruled
  600.      * out the current entry from the results. In such cases this tree iterator
  601.      * may perform special behavior.
  602.      *
  603.      * @throws org.eclipse.jgit.errors.CorruptObjectException
  604.      *             the tree is invalid.
  605.      */
  606.     public void skip() throws CorruptObjectException {
  607.         next(1);
  608.     }

  609.     /**
  610.      * Indicates to the iterator that no more entries will be read.
  611.      * <p>
  612.      * This is only invoked by TreeWalk when the iteration is aborted early due
  613.      * to a {@link org.eclipse.jgit.errors.StopWalkException} being thrown from
  614.      * within a TreeFilter.
  615.      */
  616.     public void stopWalk() {
  617.         // Do nothing by default.  Most iterators do not care.
  618.     }

  619.     /**
  620.      * Whether the iterator implements {@link #stopWalk()}.
  621.      *
  622.      * @return {@code true} if the iterator implements {@link #stopWalk()}.
  623.      * @since 4.2
  624.      */
  625.     protected boolean needsStopWalk() {
  626.         return false;
  627.     }

  628.     /**
  629.      * Get the length of the name component of the path for the current entry.
  630.      *
  631.      * @return the length of the name component of the path for the current
  632.      *         entry.
  633.      */
  634.     public int getNameLength() {
  635.         return pathLen - pathOffset;
  636.     }

  637.     /**
  638.      * JGit internal API for use by
  639.      * {@link org.eclipse.jgit.dircache.DirCacheCheckout}
  640.      *
  641.      * @return start of name component part within {@link #getEntryPathBuffer()}
  642.      * @since 2.0
  643.      */
  644.     public int getNameOffset() {
  645.         return pathOffset;
  646.     }

  647.     /**
  648.      * Get the name component of the current entry path into the provided
  649.      * buffer.
  650.      *
  651.      * @param buffer
  652.      *            the buffer to get the name into, it is assumed that buffer can
  653.      *            hold the name
  654.      * @param offset
  655.      *            the offset of the name in the buffer
  656.      * @see #getNameLength()
  657.      */
  658.     public void getName(byte[] buffer, int offset) {
  659.         System.arraycopy(path, pathOffset, buffer, offset, pathLen - pathOffset);
  660.     }

  661.     /** {@inheritDoc} */
  662.     @SuppressWarnings("nls")
  663.     @Override
  664.     public String toString() {
  665.         return getClass().getSimpleName() + "[" + getEntryPathString() + "]"; //$NON-NLS-1$
  666.     }

  667.     /**
  668.      * Whether or not this Iterator is iterating through the working tree.
  669.      *
  670.      * @return whether or not this Iterator is iterating through the working
  671.      *         tree
  672.      * @since 4.3
  673.      */
  674.     public boolean isWorkTree() {
  675.         return false;
  676.     }
  677. }