You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractTreeIterator.java 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  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. }