View Javadoc
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>
5    * and other copyright owners as documented in the project's IP log.
6    *
7    * This program and the accompanying materials are made available
8    * under the terms of the Eclipse Distribution License v1.0 which
9    * accompanies this distribution, is reproduced below, and is
10   * available at http://www.eclipse.org/org/documents/edl-v10.php
11   *
12   * All rights reserved.
13   *
14   * Redistribution and use in source and binary forms, with or
15   * without modification, are permitted provided that the following
16   * conditions are met:
17   *
18   * - Redistributions of source code must retain the above copyright
19   *   notice, this list of conditions and the following disclaimer.
20   *
21   * - Redistributions in binary form must reproduce the above
22   *   copyright notice, this list of conditions and the following
23   *   disclaimer in the documentation and/or other materials provided
24   *   with the distribution.
25   *
26   * - Neither the name of the Eclipse Foundation, Inc. nor the
27   *   names of its contributors may be used to endorse or promote
28   *   products derived from this software without specific prior
29   *   written permission.
30   *
31   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
32   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
33   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
36   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
40   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
43   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44   */
45  
46  package org.eclipse.jgit.treewalk;
47  
48  import static java.nio.charset.StandardCharsets.UTF_8;
49  
50  import java.io.IOException;
51  import java.nio.ByteBuffer;
52  import java.nio.CharBuffer;
53  
54  import org.eclipse.jgit.attributes.AttributesHandler;
55  import org.eclipse.jgit.attributes.AttributesNode;
56  import org.eclipse.jgit.errors.CorruptObjectException;
57  import org.eclipse.jgit.errors.IncorrectObjectTypeException;
58  import org.eclipse.jgit.lib.Constants;
59  import org.eclipse.jgit.lib.FileMode;
60  import org.eclipse.jgit.lib.MutableObjectId;
61  import org.eclipse.jgit.lib.ObjectId;
62  import org.eclipse.jgit.lib.ObjectReader;
63  import org.eclipse.jgit.util.Paths;
64  
65  /**
66   * Walks a Git tree (directory) in Git sort order.
67   * <p>
68   * A new iterator instance should be positioned on the first entry, or at eof.
69   * Data for the first entry (if not at eof) should be available immediately.
70   * <p>
71   * Implementors must walk a tree in the Git sort order, which has the following
72   * odd sorting:
73   * <ol>
74   * <li>A.c</li>
75   * <li>A/c</li>
76   * <li>A0c</li>
77   * </ol>
78   * <p>
79   * In the second item, <code>A</code> is the name of a subtree and
80   * <code>c</code> is a file within that subtree. The other two items are files
81   * in the root level tree.
82   *
83   * @see CanonicalTreeParser
84   */
85  public abstract class AbstractTreeIterator {
86  	/** Default size for the {@link #path} buffer. */
87  	protected static final int DEFAULT_PATH_SIZE = 128;
88  
89  	/** A dummy object id buffer that matches the zero ObjectId. */
90  	protected static final byte[] zeroid = new byte[Constants.OBJECT_ID_LENGTH];
91  
92  	/**
93  	 * Iterator for the parent tree; null if we are the root iterator.
94  	 * <p>
95  	 * Used by {@link TreeWalk} and {@link AttributesHandler}
96  	 *
97  	 * @since 4.3
98  	 */
99  	public final AbstractTreeIterator parent;
100 
101 	/** The iterator this current entry is path equal to. */
102 	AbstractTreeIterator matches;
103 
104 	/**
105 	 * Parsed rules of .gitattributes file if it exists.
106 	 *
107 	 * @since 4.2
108 	 */
109 	protected AttributesNode attributesNode;
110 
111 	/**
112 	 * Number of entries we moved forward to force a D/F conflict match.
113 	 *
114 	 * @see NameConflictTreeWalk
115 	 */
116 	int matchShift;
117 
118 	/**
119 	 * Mode bits for the current entry.
120 	 * <p>
121 	 * A numerical value from FileMode is usually faster for an iterator to
122 	 * obtain from its data source so this is the preferred representation.
123 	 *
124 	 * @see org.eclipse.jgit.lib.FileMode
125 	 */
126 	protected int mode;
127 
128 	/**
129 	 * Path buffer for the current entry.
130 	 * <p>
131 	 * This buffer is pre-allocated at the start of walking and is shared from
132 	 * parent iterators down into their subtree iterators. The sharing allows
133 	 * the current entry to always be a full path from the root, while each
134 	 * subtree only needs to populate the part that is under their control.
135 	 */
136 	protected byte[] path;
137 
138 	/**
139 	 * Position within {@link #path} this iterator starts writing at.
140 	 * <p>
141 	 * This is the first offset in {@link #path} that this iterator must
142 	 * populate during {@link #next}. At the root level (when {@link #parent}
143 	 * is null) this is 0. For a subtree iterator the index before this position
144 	 * should have the value '/'.
145 	 */
146 	protected final int pathOffset;
147 
148 	/**
149 	 * Total length of the current entry's complete path from the root.
150 	 * <p>
151 	 * This is the number of bytes within {@link #path} that pertain to the
152 	 * current entry. Values at this index through the end of the array are
153 	 * garbage and may be randomly populated from prior entries.
154 	 */
155 	protected int pathLen;
156 
157 	/**
158 	 * Create a new iterator with no parent.
159 	 */
160 	protected AbstractTreeIterator() {
161 		parent = null;
162 		path = new byte[DEFAULT_PATH_SIZE];
163 		pathOffset = 0;
164 	}
165 
166 	/**
167 	 * Create a new iterator with no parent and a prefix.
168 	 * <p>
169 	 * The prefix path supplied is inserted in front of all paths generated by
170 	 * this iterator. It is intended to be used when an iterator is being
171 	 * created for a subsection of an overall repository and needs to be
172 	 * combined with other iterators that are created to run over the entire
173 	 * repository namespace.
174 	 *
175 	 * @param prefix
176 	 *            position of this iterator in the repository tree. The value
177 	 *            may be null or the empty string to indicate the prefix is the
178 	 *            root of the repository. A trailing slash ('/') is
179 	 *            automatically appended if the prefix does not end in '/'.
180 	 */
181 	protected AbstractTreeIterator(String prefix) {
182 		parent = null;
183 
184 		if (prefix != null && prefix.length() > 0) {
185 			final ByteBuffer b;
186 
187 			b = UTF_8.encode(CharBuffer.wrap(prefix));
188 			pathLen = b.limit();
189 			path = new byte[Math.max(DEFAULT_PATH_SIZE, pathLen + 1)];
190 			b.get(path, 0, pathLen);
191 			if (path[pathLen - 1] != '/')
192 				path[pathLen++] = '/';
193 			pathOffset = pathLen;
194 		} else {
195 			path = new byte[DEFAULT_PATH_SIZE];
196 			pathOffset = 0;
197 		}
198 	}
199 
200 	/**
201 	 * Create a new iterator with no parent and a prefix.
202 	 * <p>
203 	 * The prefix path supplied is inserted in front of all paths generated by
204 	 * this iterator. It is intended to be used when an iterator is being
205 	 * created for a subsection of an overall repository and needs to be
206 	 * combined with other iterators that are created to run over the entire
207 	 * repository namespace.
208 	 *
209 	 * @param prefix
210 	 *            position of this iterator in the repository tree. The value
211 	 *            may be null or the empty array to indicate the prefix is the
212 	 *            root of the repository. A trailing slash ('/') is
213 	 *            automatically appended if the prefix does not end in '/'.
214 	 */
215 	protected AbstractTreeIterator(byte[] prefix) {
216 		parent = null;
217 
218 		if (prefix != null && prefix.length > 0) {
219 			pathLen = prefix.length;
220 			path = new byte[Math.max(DEFAULT_PATH_SIZE, pathLen + 1)];
221 			System.arraycopy(prefix, 0, path, 0, pathLen);
222 			if (path[pathLen - 1] != '/')
223 				path[pathLen++] = '/';
224 			pathOffset = pathLen;
225 		} else {
226 			path = new byte[DEFAULT_PATH_SIZE];
227 			pathOffset = 0;
228 		}
229 	}
230 
231 	/**
232 	 * Create an iterator for a subtree of an existing iterator.
233 	 *
234 	 * @param p
235 	 *            parent tree iterator.
236 	 */
237 	protected AbstractTreeIterator(AbstractTreeIterator p) {
238 		parent = p;
239 		path = p.path;
240 		pathOffset = p.pathLen + 1;
241 
242 		try {
243 			path[pathOffset - 1] = '/';
244 		} catch (ArrayIndexOutOfBoundsException e) {
245 			growPath(p.pathLen);
246 			path[pathOffset - 1] = '/';
247 		}
248 	}
249 
250 	/**
251 	 * Create an iterator for a subtree of an existing iterator.
252 	 * <p>
253 	 * The caller is responsible for setting up the path of the child iterator.
254 	 *
255 	 * @param p
256 	 *            parent tree iterator.
257 	 * @param childPath
258 	 *            path array to be used by the child iterator. This path must
259 	 *            contain the path from the top of the walk to the first child
260 	 *            and must end with a '/'.
261 	 * @param childPathOffset
262 	 *            position within <code>childPath</code> where the child can
263 	 *            insert its data. The value at
264 	 *            <code>childPath[childPathOffset-1]</code> must be '/'.
265 	 */
266 	protected AbstractTreeIterator(final AbstractTreeIterator p,
267 			final byte[] childPath, final int childPathOffset) {
268 		parent = p;
269 		path = childPath;
270 		pathOffset = childPathOffset;
271 	}
272 
273 	/**
274 	 * Grow the path buffer larger.
275 	 *
276 	 * @param len
277 	 *            number of live bytes in the path buffer. This many bytes will
278 	 *            be moved into the larger buffer.
279 	 */
280 	protected void growPath(int len) {
281 		setPathCapacity(path.length << 1, len);
282 	}
283 
284 	/**
285 	 * Ensure that path is capable to hold at least {@code capacity} bytes
286 	 *
287 	 * @param capacity
288 	 *            the amount of bytes to hold
289 	 * @param len
290 	 *            the amount of live bytes in path buffer
291 	 */
292 	protected void ensurePathCapacity(int capacity, int len) {
293 		if (path.length >= capacity)
294 			return;
295 		final byte[] o = path;
296 		int current = o.length;
297 		int newCapacity = current;
298 		while (newCapacity < capacity && newCapacity > 0)
299 			newCapacity <<= 1;
300 		setPathCapacity(newCapacity, len);
301 	}
302 
303 	/**
304 	 * Set path buffer capacity to the specified size
305 	 *
306 	 * @param capacity
307 	 *            the new size
308 	 * @param len
309 	 *            the amount of bytes to copy
310 	 */
311 	private void setPathCapacity(int capacity, int len) {
312 		final byte[] o = path;
313 		final byte[] n = new byte[capacity];
314 		System.arraycopy(o, 0, n, 0, len);
315 		for (AbstractTreeIterator p = this; p != null && p.path == o; p = p.parent)
316 			p.path = n;
317 	}
318 
319 	/**
320 	 * Compare the path of this current entry to another iterator's entry.
321 	 *
322 	 * @param p
323 	 *            the other iterator to compare the path against.
324 	 * @return -1 if this entry sorts first; 0 if the entries are equal; 1 if
325 	 *         p's entry sorts first.
326 	 */
327 	public int pathCompare(AbstractTreeIterator p) {
328 		return pathCompare(p, p.mode);
329 	}
330 
331 	int pathCompare(AbstractTreeIterator p, int pMode) {
332 		// Its common when we are a subtree for both parents to match;
333 		// when this happens everything in path[0..cPos] is known to
334 		// be equal and does not require evaluation again.
335 		//
336 		int cPos = alreadyMatch(this, p);
337 		return pathCompare(p.path, cPos, p.pathLen, pMode, cPos);
338 	}
339 
340 	/**
341 	 * Seek the iterator on a file, if present.
342 	 *
343 	 * @param name
344 	 *            file name to find (will not find a directory).
345 	 * @return true if the file exists in this tree; false otherwise.
346 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
347 	 *             tree is invalid.
348 	 * @since 4.2
349 	 */
350 	public boolean findFile(String name) throws CorruptObjectException {
351 		return findFile(Constants.encode(name));
352 	}
353 
354 	/**
355 	 * Seek the iterator on a file, if present.
356 	 *
357 	 * @param name
358 	 *            file name to find (will not find a directory).
359 	 * @return true if the file exists in this tree; false otherwise.
360 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
361 	 *             tree is invalid.
362 	 * @since 4.2
363 	 */
364 	public boolean findFile(byte[] name) throws CorruptObjectException {
365 		for (; !eof(); next(1)) {
366 			int cmp = pathCompare(name, 0, name.length, 0, pathOffset);
367 			if (cmp == 0) {
368 				return true;
369 			} else if (cmp > 0) {
370 				return false;
371 			}
372 		}
373 		return false;
374 	}
375 
376 	/**
377 	 * Compare the path of this current entry to a raw buffer.
378 	 *
379 	 * @param buf
380 	 *            the raw path buffer.
381 	 * @param pos
382 	 *            position to start reading the raw buffer.
383 	 * @param end
384 	 *            one past the end of the raw buffer (length is end - pos).
385 	 * @param pathMode
386 	 *            the mode of the path.
387 	 * @return -1 if this entry sorts first; 0 if the entries are equal; 1 if
388 	 *         p's entry sorts first.
389 	 */
390 	public int pathCompare(byte[] buf, int pos, int end, int pathMode) {
391 		return pathCompare(buf, pos, end, pathMode, 0);
392 	}
393 
394 	private int pathCompare(byte[] b, int bPos, int bEnd, int bMode, int aPos) {
395 		return Paths.compare(
396 				path, aPos, pathLen, mode,
397 				b, bPos, bEnd, bMode);
398 	}
399 
400 	private static int alreadyMatch(AbstractTreeIterator a,
401 			AbstractTreeIterator b) {
402 		for (;;) {
403 			final AbstractTreeIterator ap = a.parent;
404 			final AbstractTreeIterator bp = b.parent;
405 			if (ap == null || bp == null)
406 				return 0;
407 			if (ap.matches == bp.matches)
408 				return a.pathOffset;
409 			a = ap;
410 			b = bp;
411 		}
412 	}
413 
414 	/**
415 	 * Check if the current entry of both iterators has the same id.
416 	 * <p>
417 	 * This method is faster than {@link #getEntryObjectId()} as it does not
418 	 * require copying the bytes out of the buffers. A direct {@link #idBuffer}
419 	 * compare operation is performed.
420 	 *
421 	 * @param otherIterator
422 	 *            the other iterator to test against.
423 	 * @return true if both iterators have the same object id; false otherwise.
424 	 */
425 	public boolean idEqual(AbstractTreeIterator otherIterator) {
426 		return ObjectId.equals(idBuffer(), idOffset(),
427 				otherIterator.idBuffer(), otherIterator.idOffset());
428 	}
429 
430 	/**
431 	 * Whether the entry has a valid ObjectId.
432 	 *
433 	 * @return {@code true} if the entry has a valid ObjectId.
434 	 */
435 	public abstract boolean hasId();
436 
437 	/**
438 	 * Get the object id of the current entry.
439 	 *
440 	 * @return an object id for the current entry.
441 	 */
442 	public ObjectId getEntryObjectId() {
443 		return ObjectId.fromRaw(idBuffer(), idOffset());
444 	}
445 
446 	/**
447 	 * Obtain the ObjectId for the current entry.
448 	 *
449 	 * @param out
450 	 *            buffer to copy the object id into.
451 	 */
452 	public void getEntryObjectId(MutableObjectId out) {
453 		out.fromRaw(idBuffer(), idOffset());
454 	}
455 
456 	/**
457 	 * Get the file mode of the current entry.
458 	 *
459 	 * @return the file mode of the current entry.
460 	 */
461 	public FileMode getEntryFileMode() {
462 		return FileMode.fromBits(mode);
463 	}
464 
465 	/**
466 	 * Get the file mode of the current entry as bits.
467 	 *
468 	 * @return the file mode of the current entry as bits.
469 	 */
470 	public int getEntryRawMode() {
471 		return mode;
472 	}
473 
474 	/**
475 	 * Get path of the current entry, as a string.
476 	 *
477 	 * @return path of the current entry, as a string.
478 	 */
479 	public String getEntryPathString() {
480 		return TreeWalk.pathOf(this);
481 	}
482 
483 	/**
484 	 * Get the current entry path buffer.
485 	 * <p>
486 	 * Note that the returned byte[] has to be used together with
487 	 * {@link #getEntryPathLength()} (only use bytes up to this length).
488 	 *
489 	 * @return the internal buffer holding the current path.
490 	 */
491 	public byte[] getEntryPathBuffer() {
492 		return path;
493 	}
494 
495 	/**
496 	 * Get length of the path in {@link #getEntryPathBuffer()}.
497 	 *
498 	 * @return length of the path in {@link #getEntryPathBuffer()}.
499 	 */
500 	public int getEntryPathLength() {
501 		return pathLen;
502 	}
503 
504 	/**
505 	 * Get the current entry's path hash code.
506 	 * <p>
507 	 * This method computes a hash code on the fly for this path, the hash is
508 	 * suitable to cluster objects that may have similar paths together.
509 	 *
510 	 * @return path hash code; any integer may be returned.
511 	 */
512 	public int getEntryPathHashCode() {
513 		int hash = 0;
514 		for (int i = Math.max(0, pathLen - 16); i < pathLen; i++) {
515 			byte c = path[i];
516 			if (c != ' ')
517 				hash = (hash >>> 2) + (c << 24);
518 		}
519 		return hash;
520 	}
521 
522 	/**
523 	 * Get the byte array buffer object IDs must be copied out of.
524 	 * <p>
525 	 * The id buffer contains the bytes necessary to construct an ObjectId for
526 	 * the current entry of this iterator. The buffer can be the same buffer for
527 	 * all entries, or it can be a unique buffer per-entry. Implementations are
528 	 * encouraged to expose their private buffer whenever possible to reduce
529 	 * garbage generation and copying costs.
530 	 *
531 	 * @return byte array the implementation stores object IDs within.
532 	 * @see #getEntryObjectId()
533 	 */
534 	public abstract byte[] idBuffer();
535 
536 	/**
537 	 * Get the position within {@link #idBuffer()} of this entry's ObjectId.
538 	 *
539 	 * @return offset into the array returned by {@link #idBuffer()} where the
540 	 *         ObjectId must be copied out of.
541 	 */
542 	public abstract int idOffset();
543 
544 	/**
545 	 * Create a new iterator for the current entry's subtree.
546 	 * <p>
547 	 * The parent reference of the iterator must be <code>this</code>,
548 	 * otherwise the caller would not be able to exit out of the subtree
549 	 * iterator correctly and return to continue walking <code>this</code>.
550 	 *
551 	 * @param reader
552 	 *            reader to load the tree data from.
553 	 * @return a new parser that walks over the current subtree.
554 	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
555 	 *             the current entry is not actually a tree and cannot be parsed
556 	 *             as though it were a tree.
557 	 * @throws java.io.IOException
558 	 *             a loose object or pack file could not be read.
559 	 */
560 	public abstract AbstractTreeIterator createSubtreeIterator(
561 			ObjectReader reader) throws IncorrectObjectTypeException,
562 			IOException;
563 
564 	/**
565 	 * Create a new iterator as though the current entry were a subtree.
566 	 *
567 	 * @return a new empty tree iterator.
568 	 */
569 	public EmptyTreeIterator createEmptyTreeIterator() {
570 		return new EmptyTreeIterator(this);
571 	}
572 
573 	/**
574 	 * Create a new iterator for the current entry's subtree.
575 	 * <p>
576 	 * The parent reference of the iterator must be <code>this</code>, otherwise
577 	 * the caller would not be able to exit out of the subtree iterator
578 	 * correctly and return to continue walking <code>this</code>.
579 	 *
580 	 * @param reader
581 	 *            reader to load the tree data from.
582 	 * @param idBuffer
583 	 *            temporary ObjectId buffer for use by this method.
584 	 * @return a new parser that walks over the current subtree.
585 	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
586 	 *             the current entry is not actually a tree and cannot be parsed
587 	 *             as though it were a tree.
588 	 * @throws java.io.IOException
589 	 *             a loose object or pack file could not be read.
590 	 */
591 	public AbstractTreeIterator createSubtreeIterator(
592 			final ObjectReader reader, final MutableObjectId idBuffer)
593 			throws IncorrectObjectTypeException, IOException {
594 		return createSubtreeIterator(reader);
595 	}
596 
597 	/**
598 	 * Position this iterator on the first entry.
599 	 *
600 	 * The default implementation of this method uses {@code back(1)} until
601 	 * {@code first()} is true. This is most likely not the most efficient
602 	 * method of repositioning the iterator to its first entry, so subclasses
603 	 * are strongly encouraged to override the method.
604 	 *
605 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
606 	 *             the tree is invalid.
607 	 */
608 	public void reset() throws CorruptObjectException {
609 		while (!first())
610 			back(1);
611 	}
612 
613 	/**
614 	 * Is this tree iterator positioned on its first entry?
615 	 * <p>
616 	 * An iterator is positioned on the first entry if <code>back(1)</code>
617 	 * would be an invalid request as there is no entry before the current one.
618 	 * <p>
619 	 * An empty iterator (one with no entries) will be
620 	 * <code>first() &amp;&amp; eof()</code>.
621 	 *
622 	 * @return true if the iterator is positioned on the first entry.
623 	 */
624 	public abstract boolean first();
625 
626 	/**
627 	 * Is this tree iterator at its EOF point (no more entries)?
628 	 * <p>
629 	 * An iterator is at EOF if there is no current entry.
630 	 *
631 	 * @return true if we have walked all entries and have none left.
632 	 */
633 	public abstract boolean eof();
634 
635 	/**
636 	 * Move to next entry, populating this iterator with the entry data.
637 	 * <p>
638 	 * The delta indicates how many moves forward should occur. The most common
639 	 * delta is 1 to move to the next entry.
640 	 * <p>
641 	 * Implementations must populate the following members:
642 	 * <ul>
643 	 * <li>{@link #mode}</li>
644 	 * <li>{@link #path} (from {@link #pathOffset} to {@link #pathLen})</li>
645 	 * <li>{@link #pathLen}</li>
646 	 * </ul>
647 	 * as well as any implementation dependent information necessary to
648 	 * accurately return data from {@link #idBuffer()} and {@link #idOffset()}
649 	 * when demanded.
650 	 *
651 	 * @param delta
652 	 *            number of entries to move the iterator by. Must be a positive,
653 	 *            non-zero integer.
654 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
655 	 *             the tree is invalid.
656 	 */
657 	public abstract void next(int delta) throws CorruptObjectException;
658 
659 	/**
660 	 * Move to prior entry, populating this iterator with the entry data.
661 	 * <p>
662 	 * The delta indicates how many moves backward should occur.The most common
663 	 * delta is 1 to move to the prior entry.
664 	 * <p>
665 	 * Implementations must populate the following members:
666 	 * <ul>
667 	 * <li>{@link #mode}</li>
668 	 * <li>{@link #path} (from {@link #pathOffset} to {@link #pathLen})</li>
669 	 * <li>{@link #pathLen}</li>
670 	 * </ul>
671 	 * as well as any implementation dependent information necessary to
672 	 * accurately return data from {@link #idBuffer()} and {@link #idOffset()}
673 	 * when demanded.
674 	 *
675 	 * @param delta
676 	 *            number of entries to move the iterator by. Must be a positive,
677 	 *            non-zero integer.
678 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
679 	 *             the tree is invalid.
680 	 */
681 	public abstract void back(int delta) throws CorruptObjectException;
682 
683 	/**
684 	 * Advance to the next tree entry, populating this iterator with its data.
685 	 * <p>
686 	 * This method behaves like <code>seek(1)</code> but is called by
687 	 * {@link org.eclipse.jgit.treewalk.TreeWalk} only if a
688 	 * {@link org.eclipse.jgit.treewalk.filter.TreeFilter} was used and ruled
689 	 * out the current entry from the results. In such cases this tree iterator
690 	 * may perform special behavior.
691 	 *
692 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
693 	 *             the tree is invalid.
694 	 */
695 	public void skip() throws CorruptObjectException {
696 		next(1);
697 	}
698 
699 	/**
700 	 * Indicates to the iterator that no more entries will be read.
701 	 * <p>
702 	 * This is only invoked by TreeWalk when the iteration is aborted early due
703 	 * to a {@link org.eclipse.jgit.errors.StopWalkException} being thrown from
704 	 * within a TreeFilter.
705 	 */
706 	public void stopWalk() {
707 		// Do nothing by default.  Most iterators do not care.
708 	}
709 
710 	/**
711 	 * Whether the iterator implements {@link #stopWalk()}.
712 	 *
713 	 * @return {@code true} if the iterator implements {@link #stopWalk()}.
714 	 * @since 4.2
715 	 */
716 	protected boolean needsStopWalk() {
717 		return false;
718 	}
719 
720 	/**
721 	 * Get the length of the name component of the path for the current entry.
722 	 *
723 	 * @return the length of the name component of the path for the current
724 	 *         entry.
725 	 */
726 	public int getNameLength() {
727 		return pathLen - pathOffset;
728 	}
729 
730 	/**
731 	 * JGit internal API for use by
732 	 * {@link org.eclipse.jgit.dircache.DirCacheCheckout}
733 	 *
734 	 * @return start of name component part within {@link #getEntryPathBuffer()}
735 	 * @since 2.0
736 	 */
737 	public int getNameOffset() {
738 		return pathOffset;
739 	}
740 
741 	/**
742 	 * Get the name component of the current entry path into the provided
743 	 * buffer.
744 	 *
745 	 * @param buffer
746 	 *            the buffer to get the name into, it is assumed that buffer can
747 	 *            hold the name
748 	 * @param offset
749 	 *            the offset of the name in the buffer
750 	 * @see #getNameLength()
751 	 */
752 	public void getName(byte[] buffer, int offset) {
753 		System.arraycopy(path, pathOffset, buffer, offset, pathLen - pathOffset);
754 	}
755 
756 	/** {@inheritDoc} */
757 	@SuppressWarnings("nls")
758 	@Override
759 	public String toString() {
760 		return getClass().getSimpleName() + "[" + getEntryPathString() + "]"; //$NON-NLS-1$
761 	}
762 
763 	/**
764 	 * Whether or not this Iterator is iterating through the working tree.
765 	 *
766 	 * @return whether or not this Iterator is iterating through the working
767 	 *         tree
768 	 * @since 4.3
769 	 */
770 	public boolean isWorkTree() {
771 		return false;
772 	}
773 }