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.api;
44
45 import static org.eclipse.jgit.lib.Constants.HEAD;
46
47 import java.io.BufferedOutputStream;
48 import java.io.IOException;
49 import java.io.OutputStream;
50 import java.util.List;
51
52 import org.eclipse.jgit.api.errors.GitAPIException;
53 import org.eclipse.jgit.api.errors.JGitInternalException;
54 import org.eclipse.jgit.api.errors.NoHeadException;
55 import org.eclipse.jgit.diff.DiffEntry;
56 import org.eclipse.jgit.diff.DiffFormatter;
57 import org.eclipse.jgit.dircache.DirCacheIterator;
58 import org.eclipse.jgit.internal.JGitText;
59 import org.eclipse.jgit.lib.NullProgressMonitor;
60 import org.eclipse.jgit.lib.ObjectId;
61 import org.eclipse.jgit.lib.ObjectReader;
62 import org.eclipse.jgit.lib.ProgressMonitor;
63 import org.eclipse.jgit.lib.Repository;
64 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
65 import org.eclipse.jgit.treewalk.CanonicalTreeParser;
66 import org.eclipse.jgit.treewalk.FileTreeIterator;
67 import org.eclipse.jgit.treewalk.filter.TreeFilter;
68 import org.eclipse.jgit.util.io.NullOutputStream;
69
70
71
72
73
74
75
76 public class DiffCommand extends GitCommand<List<DiffEntry>> {
77 private AbstractTreeIterator oldTree;
78
79 private AbstractTreeIterator newTree;
80
81 private boolean cached;
82
83 private TreeFilter pathFilter = TreeFilter.ALL;
84
85 private boolean showNameAndStatusOnly;
86
87 private OutputStream out;
88
89 private int contextLines = -1;
90
91 private String sourcePrefix;
92
93 private String destinationPrefix;
94
95 private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
96
97
98
99
100
101
102
103 protected DiffCommand(Repository repo) {
104 super(repo);
105 }
106
107
108
109
110
111
112
113
114
115 @Override
116 public List<DiffEntry> call() throws GitAPIException {
117 final DiffFormatter diffFmt;
118 if (out != null && !showNameAndStatusOnly)
119 diffFmt = new DiffFormatter(new BufferedOutputStream(out));
120 else
121 diffFmt = new DiffFormatter(NullOutputStream.INSTANCE);
122 diffFmt.setRepository(repo);
123 diffFmt.setProgressMonitor(monitor);
124 try {
125 if (cached) {
126 if (oldTree == null) {
127 ObjectId head = repo.resolve(HEAD + "^{tree}");
128 if (head == null)
129 throw new NoHeadException(JGitText.get().cannotReadTree);
130 CanonicalTreeParser p = new CanonicalTreeParser();
131 try (ObjectReader reader = repo.newObjectReader()) {
132 p.reset(reader, head);
133 }
134 oldTree = p;
135 }
136 newTree = new DirCacheIterator(repo.readDirCache());
137 } else {
138 if (oldTree == null)
139 oldTree = new DirCacheIterator(repo.readDirCache());
140 if (newTree == null)
141 newTree = new FileTreeIterator(repo);
142 }
143
144 diffFmt.setPathFilter(pathFilter);
145
146 List<DiffEntry> result = diffFmt.scan(oldTree, newTree);
147 if (showNameAndStatusOnly)
148 return result;
149 else {
150 if (contextLines >= 0)
151 diffFmt.setContext(contextLines);
152 if (destinationPrefix != null)
153 diffFmt.setNewPrefix(destinationPrefix);
154 if (sourcePrefix != null)
155 diffFmt.setOldPrefix(sourcePrefix);
156 diffFmt.format(result);
157 diffFmt.flush();
158 return result;
159 }
160 } catch (IOException e) {
161 throw new JGitInternalException(e.getMessage(), e);
162 } finally {
163 diffFmt.close();
164 }
165 }
166
167
168
169
170
171
172
173
174 public DiffCommand setCached(boolean cached) {
175 this.cached = cached;
176 return this;
177 }
178
179
180
181
182
183
184
185
186 public DiffCommand setPathFilter(TreeFilter pathFilter) {
187 this.pathFilter = pathFilter;
188 return this;
189 }
190
191
192
193
194
195
196
197
198 public DiffCommand setOldTree(AbstractTreeIterator oldTree) {
199 this.oldTree = oldTree;
200 return this;
201 }
202
203
204
205
206
207
208
209
210 public DiffCommand setNewTree(AbstractTreeIterator newTree) {
211 this.newTree = newTree;
212 return this;
213 }
214
215
216
217
218
219
220
221
222 public DiffCommand setShowNameAndStatusOnly(boolean showNameAndStatusOnly) {
223 this.showNameAndStatusOnly = showNameAndStatusOnly;
224 return this;
225 }
226
227
228
229
230
231
232
233
234 public DiffCommand setOutputStream(OutputStream out) {
235 this.out = out;
236 return this;
237 }
238
239
240
241
242
243
244
245
246 public DiffCommand setContextLines(int contextLines) {
247 this.contextLines = contextLines;
248 return this;
249 }
250
251
252
253
254
255
256
257
258 public DiffCommand setSourcePrefix(String sourcePrefix) {
259 this.sourcePrefix = sourcePrefix;
260 return this;
261 }
262
263
264
265
266
267
268
269
270 public DiffCommand setDestinationPrefix(String destinationPrefix) {
271 this.destinationPrefix = destinationPrefix;
272 return this;
273 }
274
275
276
277
278
279
280
281
282
283
284 public DiffCommand setProgressMonitor(ProgressMonitor monitor) {
285 if (monitor == null) {
286 monitor = NullProgressMonitor.INSTANCE;
287 }
288 this.monitor = monitor;
289 return this;
290 }
291 }