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