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.

DirCacheIteratorTest.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /*
  2. * Copyright (C) 2008-2009, Google Inc. and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.dircache;
  11. import static org.junit.Assert.assertEquals;
  12. import static org.junit.Assert.assertFalse;
  13. import static org.junit.Assert.assertNotNull;
  14. import static org.junit.Assert.assertSame;
  15. import static org.junit.Assert.assertTrue;
  16. import java.io.File;
  17. import java.util.Collections;
  18. import org.eclipse.jgit.junit.JGitTestUtil;
  19. import org.eclipse.jgit.junit.RepositoryTestCase;
  20. import org.eclipse.jgit.lib.FileMode;
  21. import org.eclipse.jgit.treewalk.AbstractTreeIterator;
  22. import org.eclipse.jgit.treewalk.TreeWalk;
  23. import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
  24. import org.eclipse.jgit.util.FS;
  25. import org.junit.Test;
  26. public class DirCacheIteratorTest extends RepositoryTestCase {
  27. @Test
  28. public void testEmptyTree_NoTreeWalk() throws Exception {
  29. final DirCache dc = DirCache.newInCore();
  30. assertEquals(0, dc.getEntryCount());
  31. final DirCacheIterator i = new DirCacheIterator(dc);
  32. assertTrue(i.eof());
  33. }
  34. @Test
  35. public void testEmptyTree_WithTreeWalk() throws Exception {
  36. final DirCache dc = DirCache.newInCore();
  37. assertEquals(0, dc.getEntryCount());
  38. try (TreeWalk tw = new TreeWalk(db)) {
  39. tw.addTree(new DirCacheIterator(dc));
  40. assertFalse(tw.next());
  41. }
  42. }
  43. @Test
  44. public void testNoSubtree_NoTreeWalk() throws Exception {
  45. final DirCache dc = DirCache.newInCore();
  46. final String[] paths = { "a-", "a0b" };
  47. final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
  48. for (int i = 0; i < paths.length; i++) {
  49. ents[i] = new DirCacheEntry(paths[i]);
  50. ents[i].setFileMode(FileMode.REGULAR_FILE);
  51. }
  52. final DirCacheBuilder b = dc.builder();
  53. for (DirCacheEntry ent : ents) {
  54. b.add(ent);
  55. }
  56. b.finish();
  57. final DirCacheIterator i = new DirCacheIterator(dc);
  58. int pathIdx = 0;
  59. for (; !i.eof(); i.next(1)) {
  60. assertEquals(pathIdx, i.ptr);
  61. assertSame(ents[pathIdx], i.getDirCacheEntry());
  62. pathIdx++;
  63. }
  64. assertEquals(paths.length, pathIdx);
  65. }
  66. @Test
  67. public void testNoSubtree_WithTreeWalk() throws Exception {
  68. final DirCache dc = DirCache.newInCore();
  69. final String[] paths = { "a-", "a0b" };
  70. final FileMode[] modes = { FileMode.EXECUTABLE_FILE, FileMode.GITLINK };
  71. final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
  72. for (int i = 0; i < paths.length; i++) {
  73. ents[i] = new DirCacheEntry(paths[i]);
  74. ents[i].setFileMode(modes[i]);
  75. }
  76. final DirCacheBuilder b = dc.builder();
  77. for (DirCacheEntry ent : ents) {
  78. b.add(ent);
  79. }
  80. b.finish();
  81. final DirCacheIterator i = new DirCacheIterator(dc);
  82. try (TreeWalk tw = new TreeWalk(db)) {
  83. tw.addTree(i);
  84. int pathIdx = 0;
  85. while (tw.next()) {
  86. assertSame(i, tw.getTree(0, DirCacheIterator.class));
  87. assertEquals(pathIdx, i.ptr);
  88. assertSame(ents[pathIdx], i.getDirCacheEntry());
  89. assertEquals(paths[pathIdx], tw.getPathString());
  90. assertEquals(modes[pathIdx].getBits(), tw.getRawMode(0));
  91. assertSame(modes[pathIdx], tw.getFileMode(0));
  92. pathIdx++;
  93. }
  94. assertEquals(paths.length, pathIdx);
  95. }
  96. }
  97. @Test
  98. public void testSingleSubtree_NoRecursion() throws Exception {
  99. final DirCache dc = DirCache.newInCore();
  100. final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" };
  101. final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
  102. for (int i = 0; i < paths.length; i++) {
  103. ents[i] = new DirCacheEntry(paths[i]);
  104. ents[i].setFileMode(FileMode.REGULAR_FILE);
  105. }
  106. final DirCacheBuilder b = dc.builder();
  107. for (DirCacheEntry ent : ents) {
  108. b.add(ent);
  109. }
  110. b.finish();
  111. final String[] expPaths = { "a-", "a", "a0b" };
  112. final FileMode[] expModes = { FileMode.REGULAR_FILE, FileMode.TREE,
  113. FileMode.REGULAR_FILE };
  114. final int expPos[] = { 0, -1, 4 };
  115. final DirCacheIterator i = new DirCacheIterator(dc);
  116. try (TreeWalk tw = new TreeWalk(db)) {
  117. tw.addTree(i);
  118. tw.setRecursive(false);
  119. int pathIdx = 0;
  120. while (tw.next()) {
  121. assertSame(i, tw.getTree(0, DirCacheIterator.class));
  122. assertEquals(expModes[pathIdx].getBits(), tw.getRawMode(0));
  123. assertSame(expModes[pathIdx], tw.getFileMode(0));
  124. assertEquals(expPaths[pathIdx], tw.getPathString());
  125. if (expPos[pathIdx] >= 0) {
  126. assertEquals(expPos[pathIdx], i.ptr);
  127. assertSame(ents[expPos[pathIdx]], i.getDirCacheEntry());
  128. } else {
  129. assertSame(FileMode.TREE, tw.getFileMode(0));
  130. }
  131. pathIdx++;
  132. }
  133. assertEquals(expPaths.length, pathIdx);
  134. }
  135. }
  136. @Test
  137. public void testSingleSubtree_Recursive() throws Exception {
  138. final DirCache dc = DirCache.newInCore();
  139. final FileMode mode = FileMode.REGULAR_FILE;
  140. final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" };
  141. final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
  142. for (int i = 0; i < paths.length; i++) {
  143. ents[i] = new DirCacheEntry(paths[i]);
  144. ents[i].setFileMode(mode);
  145. }
  146. final DirCacheBuilder b = dc.builder();
  147. for (DirCacheEntry ent : ents) {
  148. b.add(ent);
  149. }
  150. b.finish();
  151. final DirCacheIterator i = new DirCacheIterator(dc);
  152. try (TreeWalk tw = new TreeWalk(db)) {
  153. tw.addTree(i);
  154. tw.setRecursive(true);
  155. int pathIdx = 0;
  156. while (tw.next()) {
  157. final DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
  158. assertNotNull(c);
  159. assertEquals(pathIdx, c.ptr);
  160. assertSame(ents[pathIdx], c.getDirCacheEntry());
  161. assertEquals(paths[pathIdx], tw.getPathString());
  162. assertEquals(mode.getBits(), tw.getRawMode(0));
  163. assertSame(mode, tw.getFileMode(0));
  164. pathIdx++;
  165. }
  166. assertEquals(paths.length, pathIdx);
  167. }
  168. }
  169. @Test
  170. public void testTwoLevelSubtree_Recursive() throws Exception {
  171. final DirCache dc = DirCache.newInCore();
  172. final FileMode mode = FileMode.REGULAR_FILE;
  173. final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
  174. final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
  175. for (int i = 0; i < paths.length; i++) {
  176. ents[i] = new DirCacheEntry(paths[i]);
  177. ents[i].setFileMode(mode);
  178. }
  179. final DirCacheBuilder b = dc.builder();
  180. for (DirCacheEntry ent : ents) {
  181. b.add(ent);
  182. }
  183. b.finish();
  184. try (TreeWalk tw = new TreeWalk(db)) {
  185. tw.addTree(new DirCacheIterator(dc));
  186. tw.setRecursive(true);
  187. int pathIdx = 0;
  188. while (tw.next()) {
  189. final DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
  190. assertNotNull(c);
  191. assertEquals(pathIdx, c.ptr);
  192. assertSame(ents[pathIdx], c.getDirCacheEntry());
  193. assertEquals(paths[pathIdx], tw.getPathString());
  194. assertEquals(mode.getBits(), tw.getRawMode(0));
  195. assertSame(mode, tw.getFileMode(0));
  196. pathIdx++;
  197. }
  198. assertEquals(paths.length, pathIdx);
  199. }
  200. }
  201. @Test
  202. public void testReset() throws Exception {
  203. final DirCache dc = DirCache.newInCore();
  204. final FileMode mode = FileMode.REGULAR_FILE;
  205. final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
  206. final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
  207. for (int i = 0; i < paths.length; i++) {
  208. ents[i] = new DirCacheEntry(paths[i]);
  209. ents[i].setFileMode(mode);
  210. }
  211. final DirCacheBuilder b = dc.builder();
  212. for (DirCacheEntry ent : ents) {
  213. b.add(ent);
  214. }
  215. b.finish();
  216. DirCacheIterator dci = new DirCacheIterator(dc);
  217. assertFalse(dci.eof());
  218. assertEquals("a-", dci.getEntryPathString());
  219. dci.next(1);
  220. assertFalse(dci.eof());
  221. assertEquals("a", dci.getEntryPathString());
  222. dci.next(1);
  223. assertFalse(dci.eof());
  224. assertEquals("a0b", dci.getEntryPathString());
  225. dci.next(1);
  226. assertTrue(dci.eof());
  227. // same entries the second time
  228. dci.reset();
  229. assertFalse(dci.eof());
  230. assertEquals("a-", dci.getEntryPathString());
  231. dci.next(1);
  232. assertFalse(dci.eof());
  233. assertEquals("a", dci.getEntryPathString());
  234. dci.next(1);
  235. assertFalse(dci.eof());
  236. assertEquals("a0b", dci.getEntryPathString());
  237. dci.next(1);
  238. assertTrue(dci.eof());
  239. // Step backwards
  240. dci.back(1);
  241. assertFalse(dci.eof());
  242. assertEquals("a0b", dci.getEntryPathString());
  243. dci.back(1);
  244. assertFalse(dci.eof());
  245. assertEquals("a", dci.getEntryPathString());
  246. dci.back(1);
  247. assertFalse(dci.eof());
  248. assertEquals("a-", dci.getEntryPathString());
  249. assertTrue(dci.first());
  250. // forward
  251. assertFalse(dci.eof());
  252. assertEquals("a-", dci.getEntryPathString());
  253. dci.next(1);
  254. assertFalse(dci.eof());
  255. assertEquals("a", dci.getEntryPathString());
  256. dci.next(1);
  257. assertFalse(dci.eof());
  258. assertEquals("a0b", dci.getEntryPathString());
  259. dci.next(1);
  260. assertTrue(dci.eof());
  261. // backwqrd halways, and forward again
  262. dci.back(1);
  263. assertFalse(dci.eof());
  264. assertEquals("a0b", dci.getEntryPathString());
  265. dci.back(1);
  266. assertFalse(dci.eof());
  267. assertEquals("a", dci.getEntryPathString());
  268. dci.next(1);
  269. assertFalse(dci.eof());
  270. assertEquals("a0b", dci.getEntryPathString());
  271. dci.next(1);
  272. assertTrue(dci.eof());
  273. dci.reset(); // a.
  274. dci.next(1); // a
  275. AbstractTreeIterator sti = dci.createSubtreeIterator(null);
  276. assertEquals("a/b", sti.getEntryPathString());
  277. sti.next(1);
  278. assertEquals("a/c", sti.getEntryPathString());
  279. sti.next(1);
  280. assertEquals("a/d", sti.getEntryPathString());
  281. sti.back(2);
  282. assertEquals("a/b", sti.getEntryPathString());
  283. }
  284. @Test
  285. public void testBackBug396127() throws Exception {
  286. final DirCache dc = DirCache.newInCore();
  287. final FileMode mode = FileMode.REGULAR_FILE;
  288. final String[] paths = { "git-gui/po/fr.po",
  289. "git_remote_helpers/git/repo.py" };
  290. final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
  291. for (int i = 0; i < paths.length; i++) {
  292. ents[i] = new DirCacheEntry(paths[i]);
  293. ents[i].setFileMode(mode);
  294. }
  295. final DirCacheBuilder b = dc.builder();
  296. for (DirCacheEntry ent : ents) {
  297. b.add(ent);
  298. }
  299. b.finish();
  300. DirCacheIterator dci = new DirCacheIterator(dc);
  301. assertFalse(dci.eof());
  302. assertEquals("git-gui", dci.getEntryPathString());
  303. dci.next(1);
  304. assertFalse(dci.eof());
  305. assertEquals("git_remote_helpers", dci.getEntryPathString());
  306. dci.back(1);
  307. assertFalse(dci.eof());
  308. assertEquals("git-gui", dci.getEntryPathString());
  309. dci.next(1);
  310. assertEquals("git_remote_helpers", dci.getEntryPathString());
  311. dci.next(1);
  312. assertTrue(dci.eof());
  313. }
  314. @Test
  315. public void testTwoLevelSubtree_FilterPath() throws Exception {
  316. final DirCache dc = DirCache.newInCore();
  317. final FileMode mode = FileMode.REGULAR_FILE;
  318. final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
  319. final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
  320. for (int i = 0; i < paths.length; i++) {
  321. ents[i] = new DirCacheEntry(paths[i]);
  322. ents[i].setFileMode(mode);
  323. }
  324. final DirCacheBuilder b = dc.builder();
  325. for (DirCacheEntry ent : ents) {
  326. b.add(ent);
  327. }
  328. b.finish();
  329. try (TreeWalk tw = new TreeWalk(db)) {
  330. for (int victimIdx = 0; victimIdx < paths.length; victimIdx++) {
  331. tw.reset();
  332. tw.addTree(new DirCacheIterator(dc));
  333. tw.setFilter(PathFilterGroup.createFromStrings(Collections
  334. .singleton(paths[victimIdx])));
  335. tw.setRecursive(tw.getFilter().shouldBeRecursive());
  336. assertTrue(tw.next());
  337. final DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
  338. assertNotNull(c);
  339. assertEquals(victimIdx, c.ptr);
  340. assertSame(ents[victimIdx], c.getDirCacheEntry());
  341. assertEquals(paths[victimIdx], tw.getPathString());
  342. assertEquals(mode.getBits(), tw.getRawMode(0));
  343. assertSame(mode, tw.getFileMode(0));
  344. assertFalse(tw.next());
  345. }
  346. }
  347. }
  348. @Test
  349. public void testRemovedSubtree() throws Exception {
  350. final File path = JGitTestUtil
  351. .getTestResourceFile("dircache.testRemovedSubtree");
  352. final DirCache dc = DirCache.read(path, FS.DETECTED);
  353. assertEquals(2, dc.getEntryCount());
  354. try (TreeWalk tw = new TreeWalk(db)) {
  355. tw.setRecursive(true);
  356. tw.addTree(new DirCacheIterator(dc));
  357. assertTrue(tw.next());
  358. assertEquals("a/a", tw.getPathString());
  359. assertSame(FileMode.REGULAR_FILE, tw.getFileMode(0));
  360. assertTrue(tw.next());
  361. assertEquals("q", tw.getPathString());
  362. assertSame(FileMode.REGULAR_FILE, tw.getFileMode(0));
  363. assertFalse(tw.next());
  364. }
  365. }
  366. }