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