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