1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.dircache;
45
46 import static org.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertFalse;
48 import static org.junit.Assert.assertNotNull;
49 import static org.junit.Assert.assertSame;
50 import static org.junit.Assert.assertTrue;
51
52 import java.io.File;
53 import java.util.Collections;
54
55 import org.eclipse.jgit.junit.JGitTestUtil;
56 import org.eclipse.jgit.junit.RepositoryTestCase;
57 import org.eclipse.jgit.lib.FileMode;
58 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
59 import org.eclipse.jgit.treewalk.TreeWalk;
60 import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
61 import org.eclipse.jgit.util.FS;
62 import org.junit.Test;
63
64 public class DirCacheIteratorTest extends RepositoryTestCase {
65 @Test
66 public void testEmptyTree_NoTreeWalk() throws Exception {
67 final DirCache dc = DirCache.newInCore();
68 assertEquals(0, dc.getEntryCount());
69
70 final DirCacheIterator i = new DirCacheIterator(dc);
71 assertTrue(i.eof());
72 }
73
74 @Test
75 public void testEmptyTree_WithTreeWalk() throws Exception {
76 final DirCache dc = DirCache.newInCore();
77 assertEquals(0, dc.getEntryCount());
78
79 try (TreeWalk tw = new TreeWalk(db)) {
80 tw.addTree(new DirCacheIterator(dc));
81 assertFalse(tw.next());
82 }
83 }
84
85 @Test
86 public void testNoSubtree_NoTreeWalk() throws Exception {
87 final DirCache dc = DirCache.newInCore();
88
89 final String[] paths = { "a-", "a0b" };
90 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
91 for (int i = 0; i < paths.length; i++) {
92 ents[i] = new DirCacheEntry(paths[i]);
93 ents[i].setFileMode(FileMode.REGULAR_FILE);
94 }
95
96 final DirCacheBuilder b = dc.builder();
97 for (DirCacheEntry ent : ents) {
98 b.add(ent);
99 }
100 b.finish();
101
102 final DirCacheIterator i = new DirCacheIterator(dc);
103 int pathIdx = 0;
104 for (; !i.eof(); i.next(1)) {
105 assertEquals(pathIdx, i.ptr);
106 assertSame(ents[pathIdx], i.getDirCacheEntry());
107 pathIdx++;
108 }
109 assertEquals(paths.length, pathIdx);
110 }
111
112 @Test
113 public void testNoSubtree_WithTreeWalk() throws Exception {
114 final DirCache dc = DirCache.newInCore();
115
116 final String[] paths = { "a-", "a0b" };
117 final FileMode[] modes = { FileMode.EXECUTABLE_FILE, FileMode.GITLINK };
118 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
119 for (int i = 0; i < paths.length; i++) {
120 ents[i] = new DirCacheEntry(paths[i]);
121 ents[i].setFileMode(modes[i]);
122 }
123
124 final DirCacheBuilder b = dc.builder();
125 for (DirCacheEntry ent : ents) {
126 b.add(ent);
127 }
128 b.finish();
129
130 final DirCacheIterator i = new DirCacheIterator(dc);
131 try (TreeWalk tw = new TreeWalk(db)) {
132 tw.addTree(i);
133 int pathIdx = 0;
134 while (tw.next()) {
135 assertSame(i, tw.getTree(0, DirCacheIterator.class));
136 assertEquals(pathIdx, i.ptr);
137 assertSame(ents[pathIdx], i.getDirCacheEntry());
138 assertEquals(paths[pathIdx], tw.getPathString());
139 assertEquals(modes[pathIdx].getBits(), tw.getRawMode(0));
140 assertSame(modes[pathIdx], tw.getFileMode(0));
141 pathIdx++;
142 }
143 assertEquals(paths.length, pathIdx);
144 }
145 }
146
147 @Test
148 public void testSingleSubtree_NoRecursion() throws Exception {
149 final DirCache dc = DirCache.newInCore();
150
151 final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" };
152 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
153 for (int i = 0; i < paths.length; i++) {
154 ents[i] = new DirCacheEntry(paths[i]);
155 ents[i].setFileMode(FileMode.REGULAR_FILE);
156 }
157
158 final DirCacheBuilder b = dc.builder();
159 for (DirCacheEntry ent : ents) {
160 b.add(ent);
161 }
162 b.finish();
163
164 final String[] expPaths = { "a-", "a", "a0b" };
165 final FileMode[] expModes = { FileMode.REGULAR_FILE, FileMode.TREE,
166 FileMode.REGULAR_FILE };
167 final int expPos[] = { 0, -1, 4 };
168
169 final DirCacheIterator i = new DirCacheIterator(dc);
170 try (TreeWalk tw = new TreeWalk(db)) {
171 tw.addTree(i);
172 tw.setRecursive(false);
173 int pathIdx = 0;
174 while (tw.next()) {
175 assertSame(i, tw.getTree(0, DirCacheIterator.class));
176 assertEquals(expModes[pathIdx].getBits(), tw.getRawMode(0));
177 assertSame(expModes[pathIdx], tw.getFileMode(0));
178 assertEquals(expPaths[pathIdx], tw.getPathString());
179
180 if (expPos[pathIdx] >= 0) {
181 assertEquals(expPos[pathIdx], i.ptr);
182 assertSame(ents[expPos[pathIdx]], i.getDirCacheEntry());
183 } else {
184 assertSame(FileMode.TREE, tw.getFileMode(0));
185 }
186
187 pathIdx++;
188 }
189 assertEquals(expPaths.length, pathIdx);
190 }
191 }
192
193 @Test
194 public void testSingleSubtree_Recursive() throws Exception {
195 final DirCache dc = DirCache.newInCore();
196
197 final FileMode mode = FileMode.REGULAR_FILE;
198 final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" };
199 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
200 for (int i = 0; i < paths.length; i++) {
201 ents[i] = new DirCacheEntry(paths[i]);
202 ents[i].setFileMode(mode);
203 }
204
205 final DirCacheBuilder b = dc.builder();
206 for (DirCacheEntry ent : ents) {
207 b.add(ent);
208 }
209 b.finish();
210
211 final DirCacheIterator i = new DirCacheIterator(dc);
212 try (TreeWalk tw = new TreeWalk(db)) {
213 tw.addTree(i);
214 tw.setRecursive(true);
215 int pathIdx = 0;
216 while (tw.next()) {
217 final DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
218 assertNotNull(c);
219 assertEquals(pathIdx, c.ptr);
220 assertSame(ents[pathIdx], c.getDirCacheEntry());
221 assertEquals(paths[pathIdx], tw.getPathString());
222 assertEquals(mode.getBits(), tw.getRawMode(0));
223 assertSame(mode, tw.getFileMode(0));
224 pathIdx++;
225 }
226 assertEquals(paths.length, pathIdx);
227 }
228 }
229
230 @Test
231 public void testTwoLevelSubtree_Recursive() throws Exception {
232 final DirCache dc = DirCache.newInCore();
233
234 final FileMode mode = FileMode.REGULAR_FILE;
235 final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
236 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
237 for (int i = 0; i < paths.length; i++) {
238 ents[i] = new DirCacheEntry(paths[i]);
239 ents[i].setFileMode(mode);
240 }
241
242 final DirCacheBuilder b = dc.builder();
243 for (DirCacheEntry ent : ents) {
244 b.add(ent);
245 }
246 b.finish();
247
248 try (TreeWalk tw = new TreeWalk(db)) {
249 tw.addTree(new DirCacheIterator(dc));
250 tw.setRecursive(true);
251 int pathIdx = 0;
252 while (tw.next()) {
253 final DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
254 assertNotNull(c);
255 assertEquals(pathIdx, c.ptr);
256 assertSame(ents[pathIdx], c.getDirCacheEntry());
257 assertEquals(paths[pathIdx], tw.getPathString());
258 assertEquals(mode.getBits(), tw.getRawMode(0));
259 assertSame(mode, tw.getFileMode(0));
260 pathIdx++;
261 }
262 assertEquals(paths.length, pathIdx);
263 }
264 }
265
266 @Test
267 public void testReset() throws Exception {
268 final DirCache dc = DirCache.newInCore();
269
270 final FileMode mode = FileMode.REGULAR_FILE;
271 final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
272 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
273 for (int i = 0; i < paths.length; i++) {
274 ents[i] = new DirCacheEntry(paths[i]);
275 ents[i].setFileMode(mode);
276 }
277
278 final DirCacheBuilder b = dc.builder();
279 for (DirCacheEntry ent : ents) {
280 b.add(ent);
281 }
282 b.finish();
283
284 DirCacheIterator dci = new DirCacheIterator(dc);
285 assertFalse(dci.eof());
286 assertEquals("a-", dci.getEntryPathString());
287 dci.next(1);
288 assertFalse(dci.eof());
289 assertEquals("a", dci.getEntryPathString());
290 dci.next(1);
291 assertFalse(dci.eof());
292 assertEquals("a0b", dci.getEntryPathString());
293 dci.next(1);
294 assertTrue(dci.eof());
295
296
297 dci.reset();
298 assertFalse(dci.eof());
299 assertEquals("a-", dci.getEntryPathString());
300 dci.next(1);
301 assertFalse(dci.eof());
302 assertEquals("a", dci.getEntryPathString());
303 dci.next(1);
304 assertFalse(dci.eof());
305 assertEquals("a0b", dci.getEntryPathString());
306 dci.next(1);
307 assertTrue(dci.eof());
308
309
310 dci.back(1);
311 assertFalse(dci.eof());
312 assertEquals("a0b", dci.getEntryPathString());
313 dci.back(1);
314 assertFalse(dci.eof());
315 assertEquals("a", dci.getEntryPathString());
316 dci.back(1);
317 assertFalse(dci.eof());
318 assertEquals("a-", dci.getEntryPathString());
319 assertTrue(dci.first());
320
321
322 assertFalse(dci.eof());
323 assertEquals("a-", dci.getEntryPathString());
324 dci.next(1);
325 assertFalse(dci.eof());
326 assertEquals("a", dci.getEntryPathString());
327 dci.next(1);
328 assertFalse(dci.eof());
329 assertEquals("a0b", dci.getEntryPathString());
330 dci.next(1);
331 assertTrue(dci.eof());
332
333
334 dci.back(1);
335 assertFalse(dci.eof());
336 assertEquals("a0b", dci.getEntryPathString());
337 dci.back(1);
338 assertFalse(dci.eof());
339 assertEquals("a", dci.getEntryPathString());
340
341 dci.next(1);
342 assertFalse(dci.eof());
343 assertEquals("a0b", dci.getEntryPathString());
344 dci.next(1);
345 assertTrue(dci.eof());
346
347 dci.reset();
348 dci.next(1);
349 AbstractTreeIterator sti = dci.createSubtreeIterator(null);
350 assertEquals("a/b", sti.getEntryPathString());
351 sti.next(1);
352 assertEquals("a/c", sti.getEntryPathString());
353 sti.next(1);
354 assertEquals("a/d", sti.getEntryPathString());
355 sti.back(2);
356 assertEquals("a/b", sti.getEntryPathString());
357
358 }
359
360 @Test
361 public void testBackBug396127() throws Exception {
362 final DirCache dc = DirCache.newInCore();
363
364 final FileMode mode = FileMode.REGULAR_FILE;
365 final String[] paths = { "git-gui/po/fr.po",
366 "git_remote_helpers/git/repo.py" };
367 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
368 for (int i = 0; i < paths.length; i++) {
369 ents[i] = new DirCacheEntry(paths[i]);
370 ents[i].setFileMode(mode);
371 }
372
373 final DirCacheBuilder b = dc.builder();
374 for (DirCacheEntry ent : ents) {
375 b.add(ent);
376 }
377 b.finish();
378
379 DirCacheIterator dci = new DirCacheIterator(dc);
380 assertFalse(dci.eof());
381 assertEquals("git-gui", dci.getEntryPathString());
382 dci.next(1);
383 assertFalse(dci.eof());
384 assertEquals("git_remote_helpers", dci.getEntryPathString());
385 dci.back(1);
386 assertFalse(dci.eof());
387 assertEquals("git-gui", dci.getEntryPathString());
388 dci.next(1);
389 assertEquals("git_remote_helpers", dci.getEntryPathString());
390 dci.next(1);
391 assertTrue(dci.eof());
392
393 }
394
395 @Test
396 public void testTwoLevelSubtree_FilterPath() throws Exception {
397 final DirCache dc = DirCache.newInCore();
398
399 final FileMode mode = FileMode.REGULAR_FILE;
400 final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
401 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
402 for (int i = 0; i < paths.length; i++) {
403 ents[i] = new DirCacheEntry(paths[i]);
404 ents[i].setFileMode(mode);
405 }
406
407 final DirCacheBuilder b = dc.builder();
408 for (DirCacheEntry ent : ents) {
409 b.add(ent);
410 }
411 b.finish();
412
413 try (TreeWalk tw = new TreeWalk(db)) {
414 for (int victimIdx = 0; victimIdx < paths.length; victimIdx++) {
415 tw.reset();
416 tw.addTree(new DirCacheIterator(dc));
417 tw.setFilter(PathFilterGroup.createFromStrings(Collections
418 .singleton(paths[victimIdx])));
419 tw.setRecursive(tw.getFilter().shouldBeRecursive());
420 assertTrue(tw.next());
421 final DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
422 assertNotNull(c);
423 assertEquals(victimIdx, c.ptr);
424 assertSame(ents[victimIdx], c.getDirCacheEntry());
425 assertEquals(paths[victimIdx], tw.getPathString());
426 assertEquals(mode.getBits(), tw.getRawMode(0));
427 assertSame(mode, tw.getFileMode(0));
428 assertFalse(tw.next());
429 }
430 }
431 }
432
433 @Test
434 public void testRemovedSubtree() throws Exception {
435 final File path = JGitTestUtil
436 .getTestResourceFile("dircache.testRemovedSubtree");
437
438 final DirCache dc = DirCache.read(path, FS.DETECTED);
439 assertEquals(2, dc.getEntryCount());
440
441 try (TreeWalk tw = new TreeWalk(db)) {
442 tw.setRecursive(true);
443 tw.addTree(new DirCacheIterator(dc));
444
445 assertTrue(tw.next());
446 assertEquals("a/a", tw.getPathString());
447 assertSame(FileMode.REGULAR_FILE, tw.getFileMode(0));
448
449 assertTrue(tw.next());
450 assertEquals("q", tw.getPathString());
451 assertSame(FileMode.REGULAR_FILE, tw.getFileMode(0));
452
453 assertFalse(tw.next());
454 }
455 }
456 }