View Javadoc
1   /*
2    * Copyright (C) 2008, Google Inc.
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  
44  package org.eclipse.jgit.treewalk;
45  
46  import static org.junit.Assert.assertEquals;
47  import static org.junit.Assert.assertFalse;
48  import static org.junit.Assert.assertTrue;
49  
50  import org.eclipse.jgit.dircache.DirCache;
51  import org.eclipse.jgit.dircache.DirCacheBuilder;
52  import org.eclipse.jgit.dircache.DirCacheIterator;
53  import org.eclipse.jgit.junit.RepositoryTestCase;
54  import org.eclipse.jgit.lib.FileMode;
55  import org.junit.Test;
56  
57  public class NameConflictTreeWalkTest extends RepositoryTestCase {
58  	private static final FileMode TREE = FileMode.TREE;
59  
60  	private static final FileMode SYMLINK = FileMode.SYMLINK;
61  
62  	private static final FileMode MISSING = FileMode.MISSING;
63  
64  	private static final FileMode REGULAR_FILE = FileMode.REGULAR_FILE;
65  
66  	private static final FileMode EXECUTABLE_FILE = FileMode.EXECUTABLE_FILE;
67  
68  	@Test
69  	public void testNoDF_NoGap() throws Exception {
70  		final DirCache tree0 = db.readDirCache();
71  		final DirCache tree1 = db.readDirCache();
72  		{
73  			final DirCacheBuilder b0 = tree0.builder();
74  			final DirCacheBuilder b1 = tree1.builder();
75  
76  			b0.add(createEntry("a", REGULAR_FILE));
77  			b0.add(createEntry("a.b", EXECUTABLE_FILE));
78  			b1.add(createEntry("a/b", REGULAR_FILE));
79  			b0.add(createEntry("a0b", SYMLINK));
80  
81  			b0.finish();
82  			b1.finish();
83  			assertEquals(3, tree0.getEntryCount());
84  			assertEquals(1, tree1.getEntryCount());
85  		}
86  
87  		final TreeWalk tw = new TreeWalk(db);
88  		tw.addTree(new DirCacheIterator(tree0));
89  		tw.addTree(new DirCacheIterator(tree1));
90  
91  		assertModes("a", REGULAR_FILE, MISSING, tw);
92  		assertModes("a.b", EXECUTABLE_FILE, MISSING, tw);
93  		assertModes("a", MISSING, TREE, tw);
94  		tw.enterSubtree();
95  		assertModes("a/b", MISSING, REGULAR_FILE, tw);
96  		assertModes("a0b", SYMLINK, MISSING, tw);
97  	}
98  
99  	@Test
100 	public void testDF_NoGap() throws Exception {
101 		final DirCache tree0 = db.readDirCache();
102 		final DirCache tree1 = db.readDirCache();
103 		{
104 			final DirCacheBuilder b0 = tree0.builder();
105 			final DirCacheBuilder b1 = tree1.builder();
106 
107 			b0.add(createEntry("a", REGULAR_FILE));
108 			b0.add(createEntry("a.b", EXECUTABLE_FILE));
109 			b1.add(createEntry("a/b", REGULAR_FILE));
110 			b0.add(createEntry("a0b", SYMLINK));
111 
112 			b0.finish();
113 			b1.finish();
114 			assertEquals(3, tree0.getEntryCount());
115 			assertEquals(1, tree1.getEntryCount());
116 		}
117 
118 		final NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
119 		tw.addTree(new DirCacheIterator(tree0));
120 		tw.addTree(new DirCacheIterator(tree1));
121 
122 		assertModes("a", REGULAR_FILE, TREE, tw);
123 		assertTrue(tw.isDirectoryFileConflict());
124 		assertTrue(tw.isSubtree());
125 		tw.enterSubtree();
126 		assertModes("a/b", MISSING, REGULAR_FILE, tw);
127 		assertTrue(tw.isDirectoryFileConflict());
128 		assertModes("a.b", EXECUTABLE_FILE, MISSING, tw);
129 		assertFalse(tw.isDirectoryFileConflict());
130 		assertModes("a0b", SYMLINK, MISSING, tw);
131 		assertFalse(tw.isDirectoryFileConflict());
132 	}
133 
134 	@Test
135 	public void testDF_GapByOne() throws Exception {
136 		final DirCache tree0 = db.readDirCache();
137 		final DirCache tree1 = db.readDirCache();
138 		{
139 			final DirCacheBuilder b0 = tree0.builder();
140 			final DirCacheBuilder b1 = tree1.builder();
141 
142 			b0.add(createEntry("a", REGULAR_FILE));
143 			b0.add(createEntry("a.b", EXECUTABLE_FILE));
144 			b1.add(createEntry("a.b", EXECUTABLE_FILE));
145 			b1.add(createEntry("a/b", REGULAR_FILE));
146 			b0.add(createEntry("a0b", SYMLINK));
147 
148 			b0.finish();
149 			b1.finish();
150 			assertEquals(3, tree0.getEntryCount());
151 			assertEquals(2, tree1.getEntryCount());
152 		}
153 
154 		final NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
155 		tw.addTree(new DirCacheIterator(tree0));
156 		tw.addTree(new DirCacheIterator(tree1));
157 
158 		assertModes("a", REGULAR_FILE, TREE, tw);
159 		assertTrue(tw.isSubtree());
160 		assertTrue(tw.isDirectoryFileConflict());
161 		tw.enterSubtree();
162 		assertModes("a/b", MISSING, REGULAR_FILE, tw);
163 		assertTrue(tw.isDirectoryFileConflict());
164 		assertModes("a.b", EXECUTABLE_FILE, EXECUTABLE_FILE, tw);
165 		assertFalse(tw.isDirectoryFileConflict());
166 		assertModes("a0b", SYMLINK, MISSING, tw);
167 		assertFalse(tw.isDirectoryFileConflict());
168 	}
169 
170 	@Test
171 	public void testDF_SkipsSeenSubtree() throws Exception {
172 		final DirCache tree0 = db.readDirCache();
173 		final DirCache tree1 = db.readDirCache();
174 		{
175 			final DirCacheBuilder b0 = tree0.builder();
176 			final DirCacheBuilder b1 = tree1.builder();
177 
178 			b0.add(createEntry("a", REGULAR_FILE));
179 			b1.add(createEntry("a.b", EXECUTABLE_FILE));
180 			b1.add(createEntry("a/b", REGULAR_FILE));
181 			b0.add(createEntry("a0b", SYMLINK));
182 			b1.add(createEntry("a0b", SYMLINK));
183 
184 			b0.finish();
185 			b1.finish();
186 			assertEquals(2, tree0.getEntryCount());
187 			assertEquals(3, tree1.getEntryCount());
188 		}
189 
190 		final NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
191 		tw.addTree(new DirCacheIterator(tree0));
192 		tw.addTree(new DirCacheIterator(tree1));
193 
194 		assertModes("a", REGULAR_FILE, TREE, tw);
195 		assertTrue(tw.isSubtree());
196 		assertTrue(tw.isDirectoryFileConflict());
197 		tw.enterSubtree();
198 		assertModes("a/b", MISSING, REGULAR_FILE, tw);
199 		assertTrue(tw.isDirectoryFileConflict());
200 		assertModes("a.b", MISSING, EXECUTABLE_FILE, tw);
201 		assertFalse(tw.isDirectoryFileConflict());
202 		assertModes("a0b", SYMLINK, SYMLINK, tw);
203 		assertFalse(tw.isDirectoryFileConflict());
204 	}
205 
206 	@Test
207 	public void testDF_DetectConflict() throws Exception {
208 		final DirCache tree0 = db.readDirCache();
209 		final DirCache tree1 = db.readDirCache();
210 		{
211 			final DirCacheBuilder b0 = tree0.builder();
212 			final DirCacheBuilder b1 = tree1.builder();
213 
214 			b0.add(createEntry("0", REGULAR_FILE));
215 			b0.add(createEntry("a", REGULAR_FILE));
216 			b1.add(createEntry("0", REGULAR_FILE));
217 			b1.add(createEntry("a.b", REGULAR_FILE));
218 			b1.add(createEntry("a/b", REGULAR_FILE));
219 			b1.add(createEntry("a/c/e", REGULAR_FILE));
220 
221 			b0.finish();
222 			b1.finish();
223 			assertEquals(2, tree0.getEntryCount());
224 			assertEquals(4, tree1.getEntryCount());
225 		}
226 
227 		final NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
228 		tw.addTree(new DirCacheIterator(tree0));
229 		tw.addTree(new DirCacheIterator(tree1));
230 
231 		assertModes("0", REGULAR_FILE, REGULAR_FILE, tw);
232 		assertFalse(tw.isDirectoryFileConflict());
233 		assertModes("a", REGULAR_FILE, TREE, tw);
234 		assertTrue(tw.isSubtree());
235 		assertTrue(tw.isDirectoryFileConflict());
236 		tw.enterSubtree();
237 		assertModes("a/b", MISSING, REGULAR_FILE, tw);
238 		assertTrue(tw.isDirectoryFileConflict());
239 		assertModes("a/c", MISSING, TREE, tw);
240 		assertTrue(tw.isDirectoryFileConflict());
241 		tw.enterSubtree();
242 		assertModes("a/c/e", MISSING, REGULAR_FILE, tw);
243 		assertTrue(tw.isDirectoryFileConflict());
244 
245 		assertModes("a.b", MISSING, REGULAR_FILE, tw);
246 		assertFalse(tw.isDirectoryFileConflict());
247 	}
248 
249 	private static void assertModes(final String path, final FileMode mode0,
250 			final FileMode mode1, final TreeWalk tw) throws Exception {
251 		assertTrue("has " + path, tw.next());
252 		assertEquals(path, tw.getPathString());
253 		assertEquals(mode0, tw.getFileMode(0));
254 		assertEquals(mode1, tw.getFileMode(1));
255 	}
256 }