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 package org.eclipse.jgit.diff;
44
45 import static org.eclipse.jgit.diff.DiffEntry.DEV_NULL;
46 import static org.eclipse.jgit.util.FileUtils.delete;
47 import static org.hamcrest.CoreMatchers.is;
48 import static org.hamcrest.CoreMatchers.notNullValue;
49 import static org.junit.Assert.assertEquals;
50 import static org.junit.Assert.assertFalse;
51 import static org.junit.Assert.assertThat;
52 import static org.junit.Assert.assertTrue;
53
54 import java.io.File;
55 import java.util.List;
56
57 import org.eclipse.jgit.api.Git;
58 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
59 import org.eclipse.jgit.dircache.DirCache;
60 import org.eclipse.jgit.dircache.DirCacheEditor;
61 import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
62 import org.eclipse.jgit.dircache.DirCacheEntry;
63 import org.eclipse.jgit.junit.RepositoryTestCase;
64 import org.eclipse.jgit.lib.FileMode;
65 import org.eclipse.jgit.revwalk.RevCommit;
66 import org.eclipse.jgit.treewalk.EmptyTreeIterator;
67 import org.eclipse.jgit.treewalk.FileTreeIterator;
68 import org.eclipse.jgit.treewalk.TreeWalk;
69 import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
70 import org.eclipse.jgit.treewalk.filter.TreeFilter;
71 import org.eclipse.jgit.util.FileUtils;
72 import org.junit.Test;
73
74 public class DiffEntryTest extends RepositoryTestCase {
75
76 @Test
77 public void shouldListAddedFileInInitialCommit() throws Exception {
78
79 writeTrashFile("a.txt", "content");
80 Git git = new Git(db);
81 git.add().addFilepattern("a.txt").call();
82 RevCommit c = git.commit().setMessage("initial commit").call();
83
84
85 TreeWalk walk = new TreeWalk(db);
86 walk.addTree(new EmptyTreeIterator());
87 walk.addTree(c.getTree());
88 List<DiffEntry> result = DiffEntry.scan(walk);
89
90
91 assertThat(result, notNullValue());
92 assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
93
94 DiffEntry entry = result.get(0);
95 assertThat(entry.getChangeType(), is(ChangeType.ADD));
96 assertThat(entry.getNewPath(), is("a.txt"));
97 assertThat(entry.getOldPath(), is(DEV_NULL));
98 }
99
100 @Test
101 public void shouldListAddedFileBetweenTwoCommits() throws Exception {
102
103 Git git = new Git(db);
104 RevCommit c1 = git.commit().setMessage("initial commit").call();
105 writeTrashFile("a.txt", "content");
106 git.add().addFilepattern("a.txt").call();
107 RevCommit c2 = git.commit().setMessage("second commit").call();
108
109
110 TreeWalk walk = new TreeWalk(db);
111 walk.addTree(c1.getTree());
112 walk.addTree(c2.getTree());
113 List<DiffEntry> result = DiffEntry.scan(walk);
114
115
116 assertThat(result, notNullValue());
117 assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
118
119 DiffEntry entry = result.get(0);
120 assertThat(entry.getChangeType(), is(ChangeType.ADD));
121 assertThat(entry.getNewPath(), is("a.txt"));
122 assertThat(entry.getOldPath(), is(DEV_NULL));
123 }
124
125 @Test
126 public void shouldListModificationBetweenTwoCommits() throws Exception {
127
128 Git git = new Git(db);
129 File file = writeTrashFile("a.txt", "content");
130 git.add().addFilepattern("a.txt").call();
131 RevCommit c1 = git.commit().setMessage("initial commit").call();
132 write(file, "new content");
133 RevCommit c2 = git.commit().setAll(true).setMessage("second commit")
134 .call();
135
136
137 TreeWalk walk = new TreeWalk(db);
138 walk.addTree(c1.getTree());
139 walk.addTree(c2.getTree());
140 List<DiffEntry> result = DiffEntry.scan(walk);
141
142
143 assertThat(result, notNullValue());
144 assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
145
146 DiffEntry entry = result.get(0);
147 assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
148 assertThat(entry.getNewPath(), is("a.txt"));
149 }
150
151 @Test
152 public void shouldListDeletionBetweenTwoCommits() throws Exception {
153
154 Git git = new Git(db);
155 File file = writeTrashFile("a.txt", "content");
156 git.add().addFilepattern("a.txt").call();
157 RevCommit c1 = git.commit().setMessage("initial commit").call();
158 delete(file);
159 RevCommit c2 = git.commit().setAll(true).setMessage("delete a.txt")
160 .call();
161
162
163 TreeWalk walk = new TreeWalk(db);
164 walk.addTree(c1.getTree());
165 walk.addTree(c2.getTree());
166 List<DiffEntry> result = DiffEntry.scan(walk);
167
168
169 assertThat(result, notNullValue());
170 assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
171
172 DiffEntry entry = result.get(0);
173 assertThat(entry.getOldPath(), is("a.txt"));
174 assertThat(entry.getNewPath(), is(DEV_NULL));
175 assertThat(entry.getChangeType(), is(ChangeType.DELETE));
176 }
177
178 @Test
179 public void shouldListModificationInDirWithoutModifiedTrees()
180 throws Exception {
181
182 Git git = new Git(db);
183 File tree = new File(new File(db.getWorkTree(), "a"), "b");
184 FileUtils.mkdirs(tree);
185 File file = new File(tree, "c.txt");
186 FileUtils.createNewFile(file);
187 write(file, "content");
188 git.add().addFilepattern("a").call();
189 RevCommit c1 = git.commit().setMessage("initial commit").call();
190 write(file, "new line");
191 RevCommit c2 = git.commit().setAll(true).setMessage("second commit")
192 .call();
193
194
195 TreeWalk walk = new TreeWalk(db);
196 walk.addTree(c1.getTree());
197 walk.addTree(c2.getTree());
198 walk.setRecursive(true);
199 List<DiffEntry> result = DiffEntry.scan(walk);
200
201
202 assertThat(result, notNullValue());
203 assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
204
205 DiffEntry entry = result.get(0);
206 assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
207 assertThat(entry.getNewPath(), is("a/b/c.txt"));
208 }
209
210 @Test
211 public void shouldListModificationInDirWithModifiedTrees() throws Exception {
212
213 Git git = new Git(db);
214 File tree = new File(new File(db.getWorkTree(), "a"), "b");
215 FileUtils.mkdirs(tree);
216 File file = new File(tree, "c.txt");
217 FileUtils.createNewFile(file);
218 write(file, "content");
219 git.add().addFilepattern("a").call();
220 RevCommit c1 = git.commit().setMessage("initial commit").call();
221 write(file, "new line");
222 RevCommit c2 = git.commit().setAll(true).setMessage("second commit")
223 .call();
224
225
226 TreeWalk walk = new TreeWalk(db);
227 walk.addTree(c1.getTree());
228 walk.addTree(c2.getTree());
229 List<DiffEntry> result = DiffEntry.scan(walk, true);
230
231
232 assertThat(result, notNullValue());
233 assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(3)));
234
235 DiffEntry entry = result.get(0);
236 assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
237 assertThat(entry.getNewPath(), is("a"));
238
239 entry = result.get(1);
240 assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
241 assertThat(entry.getNewPath(), is("a/b"));
242
243 entry = result.get(2);
244 assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
245 assertThat(entry.getNewPath(), is("a/b/c.txt"));
246 }
247
248 @Test
249 public void shouldListChangesInWorkingTree() throws Exception {
250
251 writeTrashFile("a.txt", "content");
252 Git git = new Git(db);
253 git.add().addFilepattern("a.txt").call();
254 RevCommit c = git.commit().setMessage("initial commit").call();
255 writeTrashFile("b.txt", "new line");
256
257
258 TreeWalk walk = new TreeWalk(db);
259 walk.addTree(c.getTree());
260 walk.addTree(new FileTreeIterator(db));
261 List<DiffEntry> result = DiffEntry.scan(walk, true);
262
263
264 assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
265 DiffEntry entry = result.get(0);
266
267 assertThat(entry.getChangeType(), is(ChangeType.ADD));
268 assertThat(entry.getNewPath(), is("b.txt"));
269 }
270
271 @Test
272 public void shouldMarkEntriesWhenGivenMarkTreeFilter() throws Exception {
273
274 Git git = new Git(db);
275 RevCommit c1 = git.commit().setMessage("initial commit").call();
276 FileUtils.mkdir(new File(db.getWorkTree(), "b"));
277 writeTrashFile("a.txt", "a");
278 writeTrashFile("b/1.txt", "b1");
279 writeTrashFile("b/2.txt", "b2");
280 writeTrashFile("c.txt", "c");
281 git.add().addFilepattern("a.txt").addFilepattern("b")
282 .addFilepattern("c.txt").call();
283 RevCommit c2 = git.commit().setMessage("second commit").call();
284 TreeFilter filterA = PathFilterGroup.createFromStrings("a.txt");
285 TreeFilter filterB = PathFilterGroup.createFromStrings("b");
286 TreeFilter filterB2 = PathFilterGroup.createFromStrings("b/2.txt");
287
288
289 TreeWalk walk = new TreeWalk(db);
290 walk.addTree(c1.getTree());
291 walk.addTree(c2.getTree());
292 List<DiffEntry> result = DiffEntry.scan(walk, true, new TreeFilter[] {
293 filterA, filterB, filterB2 });
294
295
296 assertThat(result, notNullValue());
297 assertEquals(5, result.size());
298
299 DiffEntry entryA = result.get(0);
300 DiffEntry entryB = result.get(1);
301 DiffEntry entryB1 = result.get(2);
302 DiffEntry entryB2 = result.get(3);
303 DiffEntry entryC = result.get(4);
304
305 assertThat(entryA.getNewPath(), is("a.txt"));
306 assertTrue(entryA.isMarked(0));
307 assertFalse(entryA.isMarked(1));
308 assertFalse(entryA.isMarked(2));
309 assertEquals(1, entryA.getTreeFilterMarks());
310
311 assertThat(entryB.getNewPath(), is("b"));
312 assertFalse(entryB.isMarked(0));
313 assertTrue(entryB.isMarked(1));
314 assertTrue(entryB.isMarked(2));
315 assertEquals(6, entryB.getTreeFilterMarks());
316
317 assertThat(entryB1.getNewPath(), is("b/1.txt"));
318 assertFalse(entryB1.isMarked(0));
319 assertTrue(entryB1.isMarked(1));
320 assertFalse(entryB1.isMarked(2));
321 assertEquals(2, entryB1.getTreeFilterMarks());
322
323 assertThat(entryB2.getNewPath(), is("b/2.txt"));
324 assertFalse(entryB2.isMarked(0));
325 assertTrue(entryB2.isMarked(1));
326 assertTrue(entryB2.isMarked(2));
327 assertEquals(6, entryB2.getTreeFilterMarks());
328
329 assertThat(entryC.getNewPath(), is("c.txt"));
330 assertFalse(entryC.isMarked(0));
331 assertFalse(entryC.isMarked(1));
332 assertFalse(entryC.isMarked(2));
333 assertEquals(0, entryC.getTreeFilterMarks());
334 }
335
336 @Test(expected = IllegalArgumentException.class)
337 public void shouldThrowIAEWhenTreeWalkHasLessThanTwoTrees()
338 throws Exception {
339
340
341
342 TreeWalk walk = new TreeWalk(db);
343 walk.addTree(new EmptyTreeIterator());
344 DiffEntry.scan(walk);
345 }
346
347 @Test(expected = IllegalArgumentException.class)
348 public void shouldThrowIAEWhenTreeWalkHasMoreThanTwoTrees()
349 throws Exception {
350
351
352
353 TreeWalk walk = new TreeWalk(db);
354 walk.addTree(new EmptyTreeIterator());
355 walk.addTree(new EmptyTreeIterator());
356 walk.addTree(new EmptyTreeIterator());
357 DiffEntry.scan(walk);
358 }
359
360 @Test(expected = IllegalArgumentException.class)
361 public void shouldThrowIAEWhenScanShouldIncludeTreesAndWalkIsRecursive()
362 throws Exception {
363
364
365
366 TreeWalk walk = new TreeWalk(db);
367 walk.addTree(new EmptyTreeIterator());
368 walk.addTree(new EmptyTreeIterator());
369 walk.setRecursive(true);
370 DiffEntry.scan(walk, true);
371 }
372
373 @Test
374 public void shouldReportFileModeChange() throws Exception {
375 writeTrashFile("a.txt", "content");
376 Git git = new Git(db);
377 git.add().addFilepattern("a.txt").call();
378 RevCommit c1 = git.commit().setMessage("initial commit").call();
379 DirCache cache = db.lockDirCache();
380 DirCacheEditor editor = cache.editor();
381 final TreeWalk walk = new TreeWalk(db);
382 walk.addTree(c1.getTree());
383 walk.setRecursive(true);
384 assertTrue(walk.next());
385
386 editor.add(new PathEdit("a.txt") {
387
388 public void apply(DirCacheEntry ent) {
389 ent.setFileMode(FileMode.EXECUTABLE_FILE);
390 ent.setObjectId(walk.getObjectId(0));
391 }
392 });
393 assertTrue(editor.commit());
394 RevCommit c2 = git.commit().setMessage("second commit").call();
395 walk.reset();
396 walk.addTree(c1.getTree());
397 walk.addTree(c2.getTree());
398 List<DiffEntry> diffs = DiffEntry.scan(walk, false);
399 assertEquals(1, diffs.size());
400 DiffEntry diff = diffs.get(0);
401 assertEquals(ChangeType.MODIFY,diff.getChangeType());
402 assertEquals(diff.getOldId(), diff.getNewId());
403 assertEquals("a.txt", diff.getOldPath());
404 assertEquals(diff.getOldPath(), diff.getNewPath());
405 assertEquals(FileMode.EXECUTABLE_FILE, diff.getNewMode());
406 assertEquals(FileMode.REGULAR_FILE, diff.getOldMode());
407 }
408 }