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.diff;
45
46 import java.io.IOException;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.List;
50
51 import org.eclipse.jgit.attributes.Attribute;
52 import org.eclipse.jgit.internal.JGitText;
53 import org.eclipse.jgit.lib.AbbreviatedObjectId;
54 import org.eclipse.jgit.lib.AnyObjectId;
55 import org.eclipse.jgit.lib.Constants;
56 import org.eclipse.jgit.lib.FileMode;
57 import org.eclipse.jgit.lib.MutableObjectId;
58 import org.eclipse.jgit.lib.ObjectId;
59 import org.eclipse.jgit.treewalk.TreeWalk;
60 import org.eclipse.jgit.treewalk.filter.TreeFilter;
61 import org.eclipse.jgit.treewalk.filter.TreeFilterMarker;
62
63
64
65
66 public class DiffEntry {
67
68 static final AbbreviatedObjectIdorg/eclipse/jgit/lib/AbbreviatedObjectId.html#AbbreviatedObjectId">AbbreviatedObjectId A_ZERO = AbbreviatedObjectId
69 .fromObjectId(ObjectId.zeroId());
70
71
72 public static final String DEV_NULL = "/dev/null";
73
74
75 public static enum ChangeType {
76
77 ADD,
78
79
80 MODIFY,
81
82
83 DELETE,
84
85
86 RENAME,
87
88
89 COPY;
90 }
91
92
93 public static enum Side {
94
95 OLD,
96
97
98 NEW;
99 }
100
101
102
103
104 protected DiffEntry(){
105
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119 public static List<DiffEntry> scan(TreeWalk walk) throws IOException {
120 return scan(walk, false);
121 }
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 public static List<DiffEntry> scan(TreeWalk walk, boolean includeTrees)
142 throws IOException {
143 return scan(walk, includeTrees, null);
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 public static List<DiffEntry> scan(TreeWalk walk, boolean includeTrees,
171 TreeFilter[] markTreeFilters)
172 throws IOException {
173 if (walk.getTreeCount() != 2)
174 throw new IllegalArgumentException(
175 JGitText.get().treeWalkMustHaveExactlyTwoTrees);
176 if (includeTrees && walk.isRecursive())
177 throw new IllegalArgumentException(
178 JGitText.get().cannotBeRecursiveWhenTreesAreIncluded);
179
180 TreeFilterMarker treeFilterMarker;
181 if (markTreeFilters != null && markTreeFilters.length > 0)
182 treeFilterMarker = new TreeFilterMarker(markTreeFilters);
183 else
184 treeFilterMarker = null;
185
186 List<DiffEntry> r = new ArrayList<>();
187 MutableObjectId idBuf = new MutableObjectId();
188 while (walk.next()) {
189 DiffEntry entry = new DiffEntry();
190
191 walk.getObjectId(idBuf, 0);
192 entry.oldId = AbbreviatedObjectId.fromObjectId(idBuf);
193
194 walk.getObjectId(idBuf, 1);
195 entry.newId = AbbreviatedObjectId.fromObjectId(idBuf);
196
197 entry.oldMode = walk.getFileMode(0);
198 entry.newMode = walk.getFileMode(1);
199 entry.newPath = entry.oldPath = walk.getPathString();
200
201 if (walk.getAttributesNodeProvider() != null) {
202 entry.diffAttribute = walk.getAttributes()
203 .get(Constants.ATTR_DIFF);
204 }
205
206 if (treeFilterMarker != null)
207 entry.treeFilterMarks = treeFilterMarker.getMarks(walk);
208
209 if (entry.oldMode == FileMode.MISSING) {
210 entry.oldPath = DiffEntry.DEV_NULL;
211 entry.changeType = ChangeType.ADD;
212 r.add(entry);
213
214 } else if (entry.newMode == FileMode.MISSING) {
215 entry.newPath = DiffEntry.DEV_NULL;
216 entry.changeType = ChangeType.DELETE;
217 r.add(entry);
218
219 } else if (!entry.oldId.equals(entry.newId)) {
220 entry.changeType = ChangeType.MODIFY;
221 if (RenameDetector.sameType(entry.oldMode, entry.newMode))
222 r.add(entry);
223 else
224 r.addAll(breakModify(entry));
225 } else if (entry.oldMode != entry.newMode) {
226 entry.changeType = ChangeType.MODIFY;
227 r.add(entry);
228 }
229
230 if (includeTrees && walk.isSubtree())
231 walk.enterSubtree();
232 }
233 return r;
234 }
235
236 static DiffEntry add(String path, AnyObjectId id) {
237 DiffEntry e = new DiffEntry();
238 e.oldId = A_ZERO;
239 e.oldMode = FileMode.MISSING;
240 e.oldPath = DEV_NULL;
241
242 e.newId = AbbreviatedObjectId.fromObjectId(id);
243 e.newMode = FileMode.REGULAR_FILE;
244 e.newPath = path;
245 e.changeType = ChangeType.ADD;
246 return e;
247 }
248
249 static DiffEntry delete(String path, AnyObjectId id) {
250 DiffEntry e = new DiffEntry();
251 e.oldId = AbbreviatedObjectId.fromObjectId(id);
252 e.oldMode = FileMode.REGULAR_FILE;
253 e.oldPath = path;
254
255 e.newId = A_ZERO;
256 e.newMode = FileMode.MISSING;
257 e.newPath = DEV_NULL;
258 e.changeType = ChangeType.DELETE;
259 return e;
260 }
261
262 static DiffEntry modify(String path) {
263 DiffEntry e = new DiffEntry();
264 e.oldMode = FileMode.REGULAR_FILE;
265 e.oldPath = path;
266
267 e.newMode = FileMode.REGULAR_FILE;
268 e.newPath = path;
269 e.changeType = ChangeType.MODIFY;
270 return e;
271 }
272
273
274
275
276
277
278
279
280
281
282 static List<DiffEntry> breakModify(DiffEntry entry) {
283 DiffEntry del = new DiffEntry();
284 del.oldId = entry.getOldId();
285 del.oldMode = entry.getOldMode();
286 del.oldPath = entry.getOldPath();
287
288 del.newId = A_ZERO;
289 del.newMode = FileMode.MISSING;
290 del.newPath = DiffEntry.DEV_NULL;
291 del.changeType = ChangeType.DELETE;
292 del.diffAttribute = entry.diffAttribute;
293
294 DiffEntry add = new DiffEntry();
295 add.oldId = A_ZERO;
296 add.oldMode = FileMode.MISSING;
297 add.oldPath = DiffEntry.DEV_NULL;
298
299 add.newId = entry.getNewId();
300 add.newMode = entry.getNewMode();
301 add.newPath = entry.getNewPath();
302 add.changeType = ChangeType.ADD;
303 add.diffAttribute = entry.diffAttribute;
304 return Arrays.asList(del, add);
305 }
306
307 static DiffEntry="../../../../org/eclipse/jgit/diff/DiffEntry.html#DiffEntry">DiffEntryse/jgit/diff/DiffEntry.html#DiffEntry">DiffEntry pair(ChangeType changeType, DiffEntry="../../../../org/eclipse/jgit/diff/DiffEntry.html#DiffEntry">DiffEntry src, DiffEntry dst,
308 int score) {
309 DiffEntry r = new DiffEntry();
310
311 r.oldId = src.oldId;
312 r.oldMode = src.oldMode;
313 r.oldPath = src.oldPath;
314
315 r.newId = dst.newId;
316 r.newMode = dst.newMode;
317 r.newPath = dst.newPath;
318 r.diffAttribute = dst.diffAttribute;
319
320 r.changeType = changeType;
321 r.score = score;
322
323 r.treeFilterMarks = src.treeFilterMarks | dst.treeFilterMarks;
324
325 return r;
326 }
327
328
329 protected String oldPath;
330
331
332 protected String newPath;
333
334
335
336
337
338
339 protected Attribute diffAttribute;
340
341
342 protected FileMode oldMode;
343
344
345 protected FileMode newMode;
346
347
348 protected ChangeType changeType;
349
350
351 protected int score;
352
353
354 protected AbbreviatedObjectId oldId;
355
356
357 protected AbbreviatedObjectId newId;
358
359
360
361
362
363 private int treeFilterMarks = 0;
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380 public String getOldPath() {
381 return oldPath;
382 }
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399 public String getNewPath() {
400 return newPath;
401 }
402
403
404
405
406
407
408
409
410 public String getPath(Side side) {
411 return side == Side.OLD ? getOldPath() : getNewPath();
412 }
413
414
415
416
417
418 public Attribute getDiffAttribute() {
419 return diffAttribute;
420 }
421
422
423
424
425
426
427 public FileMode getOldMode() {
428 return oldMode;
429 }
430
431
432
433
434
435
436 public FileMode getNewMode() {
437 return newMode;
438 }
439
440
441
442
443
444
445
446
447 public FileMode getMode(Side side) {
448 return side == Side.OLD ? getOldMode() : getNewMode();
449 }
450
451
452
453
454
455
456 public ChangeType getChangeType() {
457 return changeType;
458 }
459
460
461
462
463
464
465
466
467
468 public int getScore() {
469 return score;
470 }
471
472
473
474
475
476
477 public AbbreviatedObjectId getOldId() {
478 return oldId;
479 }
480
481
482
483
484
485
486 public AbbreviatedObjectId getNewId() {
487 return newId;
488 }
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 public boolean isMarked(int index) {
516 return (treeFilterMarks & (1L << index)) != 0;
517 }
518
519
520
521
522
523
524
525
526
527 public int getTreeFilterMarks() {
528 return treeFilterMarks;
529 }
530
531
532
533
534
535
536
537
538 public AbbreviatedObjectId getId(Side side) {
539 return side == Side.OLD ? getOldId() : getNewId();
540 }
541
542
543 @SuppressWarnings("nls")
544 @Override
545 public String toString() {
546 StringBuilder buf = new StringBuilder();
547 buf.append("DiffEntry[");
548 buf.append(changeType);
549 buf.append(" ");
550 switch (changeType) {
551 case ADD:
552 buf.append(newPath);
553 break;
554 case COPY:
555 buf.append(oldPath + "->" + newPath);
556 break;
557 case DELETE:
558 buf.append(oldPath);
559 break;
560 case MODIFY:
561 buf.append(oldPath);
562 break;
563 case RENAME:
564 buf.append(oldPath + "->" + newPath);
565 break;
566 }
567 buf.append("]");
568 return buf.toString();
569 }
570 }