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 (int i = 0; i < ents.length; i++)
98 b.add(ents[i]);
99 b.finish();
100
101 final DirCacheIterator i = new DirCacheIterator(dc);
102 int pathIdx = 0;
103 for (; !i.eof(); i.next(1)) {
104 assertEquals(pathIdx, i.ptr);
105 assertSame(ents[pathIdx], i.getDirCacheEntry());
106 pathIdx++;
107 }
108 assertEquals(paths.length, pathIdx);
109 }
110
111 @Test
112 public void testNoSubtree_WithTreeWalk() throws Exception {
113 final DirCache dc = DirCache.newInCore();
114
115 final String[] paths = { "a-", "a0b" };
116 final FileMode[] modes = { FileMode.EXECUTABLE_FILE, FileMode.GITLINK };
117 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
118 for (int i = 0; i < paths.length; i++) {
119 ents[i] = new DirCacheEntry(paths[i]);
120 ents[i].setFileMode(modes[i]);
121 }
122
123 final DirCacheBuilder b = dc.builder();
124 for (int i = 0; i < ents.length; i++)
125 b.add(ents[i]);
126 b.finish();
127
128 final DirCacheIterator i = new DirCacheIterator(dc);
129 try (TreeWalk tw = new TreeWalk(db)) {
130 tw.addTree(i);
131 int pathIdx = 0;
132 while (tw.next()) {
133 assertSame(i, tw.getTree(0, DirCacheIterator.class));
134 assertEquals(pathIdx, i.ptr);
135 assertSame(ents[pathIdx], i.getDirCacheEntry());
136 assertEquals(paths[pathIdx], tw.getPathString());
137 assertEquals(modes[pathIdx].getBits(), tw.getRawMode(0));
138 assertSame(modes[pathIdx], tw.getFileMode(0));
139 pathIdx++;
140 }
141 assertEquals(paths.length, pathIdx);
142 }
143 }
144
145 @Test
146 public void testSingleSubtree_NoRecursion() throws Exception {
147 final DirCache dc = DirCache.newInCore();
148
149 final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" };
150 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
151 for (int i = 0; i < paths.length; i++) {
152 ents[i] = new DirCacheEntry(paths[i]);
153 ents[i].setFileMode(FileMode.REGULAR_FILE);
154 }
155
156 final DirCacheBuilder b = dc.builder();
157 for (int i = 0; i < ents.length; i++)
158 b.add(ents[i]);
159 b.finish();
160
161 final String[] expPaths = { "a-", "a", "a0b" };
162 final FileMode[] expModes = { FileMode.REGULAR_FILE, FileMode.TREE,
163 FileMode.REGULAR_FILE };
164 final int expPos[] = { 0, -1, 4 };
165
166 final DirCacheIterator i = new DirCacheIterator(dc);
167 try (TreeWalk tw = new TreeWalk(db)) {
168 tw.addTree(i);
169 tw.setRecursive(false);
170 int pathIdx = 0;
171 while (tw.next()) {
172 assertSame(i, tw.getTree(0, DirCacheIterator.class));
173 assertEquals(expModes[pathIdx].getBits(), tw.getRawMode(0));
174 assertSame(expModes[pathIdx], tw.getFileMode(0));
175 assertEquals(expPaths[pathIdx], tw.getPathString());
176
177 if (expPos[pathIdx] >= 0) {
178 assertEquals(expPos[pathIdx], i.ptr);
179 assertSame(ents[expPos[pathIdx]], i.getDirCacheEntry());
180 } else {
181 assertSame(FileMode.TREE, tw.getFileMode(0));
182 }
183
184 pathIdx++;
185 }
186 assertEquals(expPaths.length, pathIdx);
187 }
188 }
189
190 @Test
191 public void testSingleSubtree_Recursive() throws Exception {
192 final DirCache dc = DirCache.newInCore();
193
194 final FileMode mode = FileMode.REGULAR_FILE;
195 final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" };
196 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
197 for (int i = 0; i < paths.length; i++) {
198 ents[i] = new DirCacheEntry(paths[i]);
199 ents[i].setFileMode(mode);
200 }
201
202 final DirCacheBuilder b = dc.builder();
203 for (int i = 0; i < ents.length; i++)
204 b.add(ents[i]);
205 b.finish();
206
207 final DirCacheIterator i = new DirCacheIterator(dc);
208 try (TreeWalk tw = new TreeWalk(db)) {
209 tw.addTree(i);
210 tw.setRecursive(true);
211 int pathIdx = 0;
212 while (tw.next()) {
213 final DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
214 assertNotNull(c);
215 assertEquals(pathIdx, c.ptr);
216 assertSame(ents[pathIdx], c.getDirCacheEntry());
217 assertEquals(paths[pathIdx], tw.getPathString());
218 assertEquals(mode.getBits(), tw.getRawMode(0));
219 assertSame(mode, tw.getFileMode(0));
220 pathIdx++;
221 }
222 assertEquals(paths.length, pathIdx);
223 }
224 }
225
226 @Test
227 public void testTwoLevelSubtree_Recursive() throws Exception {
228 final DirCache dc = DirCache.newInCore();
229
230 final FileMode mode = FileMode.REGULAR_FILE;
231 final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
232 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
233 for (int i = 0; i < paths.length; i++) {
234 ents[i] = new DirCacheEntry(paths[i]);
235 ents[i].setFileMode(mode);
236 }
237
238 final DirCacheBuilder b = dc.builder();
239 for (int i = 0; i < ents.length; i++)
240 b.add(ents[i]);
241 b.finish();
242
243 try (TreeWalk tw = new TreeWalk(db)) {
244 tw.addTree(new DirCacheIterator(dc));
245 tw.setRecursive(true);
246 int pathIdx = 0;
247 while (tw.next()) {
248 final DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
249 assertNotNull(c);
250 assertEquals(pathIdx, c.ptr);
251 assertSame(ents[pathIdx], c.getDirCacheEntry());
252 assertEquals(paths[pathIdx], tw.getPathString());
253 assertEquals(mode.getBits(), tw.getRawMode(0));
254 assertSame(mode, tw.getFileMode(0));
255 pathIdx++;
256 }
257 assertEquals(paths.length, pathIdx);
258 }
259 }
260
261 @Test
262 public void testReset() throws Exception {
263 final DirCache dc = DirCache.newInCore();
264
265 final FileMode mode = FileMode.REGULAR_FILE;
266 final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
267 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
268 for (int i = 0; i < paths.length; i++) {
269 ents[i] = new DirCacheEntry(paths[i]);
270 ents[i].setFileMode(mode);
271 }
272
273 final DirCacheBuilder b = dc.builder();
274 for (int i = 0; i < ents.length; i++)
275 b.add(ents[i]);
276 b.finish();
277
278 DirCacheIterator dci = new DirCacheIterator(dc);
279 assertFalse(dci.eof());
280 assertEquals("a-", dci.getEntryPathString());
281 dci.next(1);
282 assertFalse(dci.eof());
283 assertEquals("a", dci.getEntryPathString());
284 dci.next(1);
285 assertFalse(dci.eof());
286 assertEquals("a0b", dci.getEntryPathString());
287 dci.next(1);
288 assertTrue(dci.eof());
289
290
291 dci.reset();
292 assertFalse(dci.eof());
293 assertEquals("a-", dci.getEntryPathString());
294 dci.next(1);
295 assertFalse(dci.eof());
296 assertEquals("a", dci.getEntryPathString());
297 dci.next(1);
298 assertFalse(dci.eof());
299 assertEquals("a0b", dci.getEntryPathString());
300 dci.next(1);
301 assertTrue(dci.eof());
302
303
304 dci.back(1);
305 assertFalse(dci.eof());
306 assertEquals("a0b", dci.getEntryPathString());
307 dci.back(1);
308 assertFalse(dci.eof());
309 assertEquals("a", dci.getEntryPathString());
310 dci.back(1);
311 assertFalse(dci.eof());
312 assertEquals("a-", dci.getEntryPathString());
313 assertTrue(dci.first());
314
315
316 assertFalse(dci.eof());
317 assertEquals("a-", dci.getEntryPathString());
318 dci.next(1);
319 assertFalse(dci.eof());
320 assertEquals("a", dci.getEntryPathString());
321 dci.next(1);
322 assertFalse(dci.eof());
323 assertEquals("a0b", dci.getEntryPathString());
324 dci.next(1);
325 assertTrue(dci.eof());
326
327
328 dci.back(1);
329 assertFalse(dci.eof());
330 assertEquals("a0b", dci.getEntryPathString());
331 dci.back(1);
332 assertFalse(dci.eof());
333 assertEquals("a", dci.getEntryPathString());
334
335 dci.next(1);
336 assertFalse(dci.eof());
337 assertEquals("a0b", dci.getEntryPathString());
338 dci.next(1);
339 assertTrue(dci.eof());
340
341 dci.reset();
342 dci.next(1);
343 AbstractTreeIterator sti = dci.createSubtreeIterator(null);
344 assertEquals("a/b", sti.getEntryPathString());
345 sti.next(1);
346 assertEquals("a/c", sti.getEntryPathString());
347 sti.next(1);
348 assertEquals("a/d", sti.getEntryPathString());
349 sti.back(2);
350 assertEquals("a/b", sti.getEntryPathString());
351
352 }
353
354 @Test
355 public void testBackBug396127() throws Exception {
356 final DirCache dc = DirCache.newInCore();
357
358 final FileMode mode = FileMode.REGULAR_FILE;
359 final String[] paths = { "git-gui/po/fr.po",
360 "git_remote_helpers/git/repo.py" };
361 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
362 for (int i = 0; i < paths.length; i++) {
363 ents[i] = new DirCacheEntry(paths[i]);
364 ents[i].setFileMode(mode);
365 }
366
367 final DirCacheBuilder b = dc.builder();
368 for (int i = 0; i < ents.length; i++)
369 b.add(ents[i]);
370 b.finish();
371
372 DirCacheIterator dci = new DirCacheIterator(dc);
373 assertFalse(dci.eof());
374 assertEquals("git-gui", dci.getEntryPathString());
375 dci.next(1);
376 assertFalse(dci.eof());
377 assertEquals("git_remote_helpers", dci.getEntryPathString());
378 dci.back(1);
379 assertFalse(dci.eof());
380 assertEquals("git-gui", dci.getEntryPathString());
381 dci.next(1);
382 assertEquals("git_remote_helpers", dci.getEntryPathString());
383 dci.next(1);
384 assertTrue(dci.eof());
385
386 }
387
388 @Test
389 public void testTwoLevelSubtree_FilterPath() throws Exception {
390 final DirCache dc = DirCache.newInCore();
391
392 final FileMode mode = FileMode.REGULAR_FILE;
393 final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" };
394 final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
395 for (int i = 0; i < paths.length; i++) {
396 ents[i] = new DirCacheEntry(paths[i]);
397 ents[i].setFileMode(mode);
398 }
399
400 final DirCacheBuilder b = dc.builder();
401 for (int i = 0; i < ents.length; i++)
402 b.add(ents[i]);
403 b.finish();
404
405 try (TreeWalk tw = new TreeWalk(db)) {
406 for (int victimIdx = 0; victimIdx < paths.length; victimIdx++) {
407 tw.reset();
408 tw.addTree(new DirCacheIterator(dc));
409 tw.setFilter(PathFilterGroup.createFromStrings(Collections
410 .singleton(paths[victimIdx])));
411 tw.setRecursive(tw.getFilter().shouldBeRecursive());
412 assertTrue(tw.next());
413 final DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
414 assertNotNull(c);
415 assertEquals(victimIdx, c.ptr);
416 assertSame(ents[victimIdx], c.getDirCacheEntry());
417 assertEquals(paths[victimIdx], tw.getPathString());
418 assertEquals(mode.getBits(), tw.getRawMode(0));
419 assertSame(mode, tw.getFileMode(0));
420 assertFalse(tw.next());
421 }
422 }
423 }
424
425 @Test
426 public void testRemovedSubtree() throws Exception {
427 final File path = JGitTestUtil
428 .getTestResourceFile("dircache.testRemovedSubtree");
429
430 final DirCache dc = DirCache.read(path, FS.DETECTED);
431 assertEquals(2, dc.getEntryCount());
432
433 try (TreeWalk tw = new TreeWalk(db)) {
434 tw.setRecursive(true);
435 tw.addTree(new DirCacheIterator(dc));
436
437 assertTrue(tw.next());
438 assertEquals("a/a", tw.getPathString());
439 assertSame(FileMode.REGULAR_FILE, tw.getFileMode(0));
440
441 assertTrue(tw.next());
442 assertEquals("q", tw.getPathString());
443 assertSame(FileMode.REGULAR_FILE, tw.getFileMode(0));
444
445 assertFalse(tw.next());
446 }
447 }
448 }