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 private DiffFormatter getDiffFormatter() {
108 return out != null && !showNameAndStatusOnly
109 ? new DiffFormatter(new BufferedOutputStream(out))
110 : new DiffFormatter(NullOutputStream.INSTANCE);
111 }
112
113
114
115
116
117
118
119
120
121 @Override
122 public List<DiffEntry> call() throws GitAPIException {
123 try (DiffFormatter diffFmt = getDiffFormatter()) {
124 diffFmt.setRepository(repo);
125 diffFmt.setProgressMonitor(monitor);
126 if (cached) {
127 if (oldTree == null) {
128 ObjectId head = repo.resolve(HEAD + "^{tree}");
129 if (head == null)
130 throw new NoHeadException(JGitText.get().cannotReadTree);
131 CanonicalTreeParser p = new CanonicalTreeParser();
132 try (ObjectReader reader = repo.newObjectReader()) {
133 p.reset(reader, head);
134 }
135 oldTree = p;
136 }
137 newTree = new DirCacheIterator(repo.readDirCache());
138 } else {
139 if (oldTree == null)
140 oldTree = new DirCacheIterator(repo.readDirCache());
141 if (newTree == null)
142 newTree = new FileTreeIterator(repo);
143 }
144
145 diffFmt.setPathFilter(pathFilter);
146
147 List<DiffEntry> result = diffFmt.scan(oldTree, newTree);
148 if (showNameAndStatusOnly)
149 return result;
150 else {
151 if (contextLines >= 0)
152 diffFmt.setContext(contextLines);
153 if (destinationPrefix != null)
154 diffFmt.setNewPrefix(destinationPrefix);
155 if (sourcePrefix != null)
156 diffFmt.setOldPrefix(sourcePrefix);
157 diffFmt.format(result);
158 diffFmt.flush();
159 return result;
160 }
161 } catch (IOException e) {
162 throw new JGitInternalException(e.getMessage(), e);
163 }
164 }
165
166
167
168
169
170
171
172
173 public DiffCommand setCached(boolean cached) {
174 this.cached = cached;
175 return this;
176 }
177
178
179
180
181
182
183
184
185 public DiffCommand setPathFilter(TreeFilter pathFilter) {
186 this.pathFilter = pathFilter;
187 return this;
188 }
189
190
191
192
193
194
195
196
197 public DiffCommand setOldTree(AbstractTreeIterator oldTree) {
198 this.oldTree = oldTree;
199 return this;
200 }
201
202
203
204
205
206
207
208
209 public DiffCommand setNewTree(AbstractTreeIterator newTree) {
210 this.newTree = newTree;
211 return this;
212 }
213
214
215
216
217
218
219
220
221 public DiffCommand setShowNameAndStatusOnly(boolean showNameAndStatusOnly) {
222 this.showNameAndStatusOnly = showNameAndStatusOnly;
223 return this;
224 }
225
226
227
228
229
230
231
232
233 public DiffCommand setOutputStream(OutputStream out) {
234 this.out = out;
235 return this;
236 }
237
238
239
240
241
242
243
244
245 public DiffCommand setContextLines(int contextLines) {
246 this.contextLines = contextLines;
247 return this;
248 }
249
250
251
252
253
254
255
256
257 public DiffCommand setSourcePrefix(String sourcePrefix) {
258 this.sourcePrefix = sourcePrefix;
259 return this;
260 }
261
262
263
264
265
266
267
268
269 public DiffCommand setDestinationPrefix(String destinationPrefix) {
270 this.destinationPrefix = destinationPrefix;
271 return this;
272 }
273
274
275
276
277
278
279
280
281
282
283 public DiffCommand setProgressMonitor(ProgressMonitor monitor) {
284 if (monitor == null) {
285 monitor = NullProgressMonitor.INSTANCE;
286 }
287 this.monitor = monitor;
288 return this;
289 }
290 }