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 public List<DiffEntry> call() throws GitAPIException {
113 final DiffFormatter diffFmt;
114 if (out != null && !showNameAndStatusOnly)
115 diffFmt = new DiffFormatter(new BufferedOutputStream(out));
116 else
117 diffFmt = new DiffFormatter(NullOutputStream.INSTANCE);
118 diffFmt.setRepository(repo);
119 diffFmt.setProgressMonitor(monitor);
120 try {
121 if (cached) {
122 if (oldTree == null) {
123 ObjectId head = repo.resolve(HEAD + "^{tree}");
124 if (head == null)
125 throw new NoHeadException(JGitText.get().cannotReadTree);
126 CanonicalTreeParser p = new CanonicalTreeParser();
127 try (ObjectReader reader = repo.newObjectReader()) {
128 p.reset(reader, head);
129 }
130 oldTree = p;
131 }
132 newTree = new DirCacheIterator(repo.readDirCache());
133 } else {
134 if (oldTree == null)
135 oldTree = new DirCacheIterator(repo.readDirCache());
136 if (newTree == null)
137 newTree = new FileTreeIterator(repo);
138 }
139
140 diffFmt.setPathFilter(pathFilter);
141
142 List<DiffEntry> result = diffFmt.scan(oldTree, newTree);
143 if (showNameAndStatusOnly)
144 return result;
145 else {
146 if (contextLines >= 0)
147 diffFmt.setContext(contextLines);
148 if (destinationPrefix != null)
149 diffFmt.setNewPrefix(destinationPrefix);
150 if (sourcePrefix != null)
151 diffFmt.setOldPrefix(sourcePrefix);
152 diffFmt.format(result);
153 diffFmt.flush();
154 return result;
155 }
156 } catch (IOException e) {
157 throw new JGitInternalException(e.getMessage(), e);
158 } finally {
159 diffFmt.close();
160 }
161 }
162
163
164
165
166
167
168
169 public DiffCommand setCached(boolean cached) {
170 this.cached = cached;
171 return this;
172 }
173
174
175
176
177
178
179 public DiffCommand setPathFilter(TreeFilter pathFilter) {
180 this.pathFilter = pathFilter;
181 return this;
182 }
183
184
185
186
187
188
189 public DiffCommand setOldTree(AbstractTreeIterator oldTree) {
190 this.oldTree = oldTree;
191 return this;
192 }
193
194
195
196
197
198
199 public DiffCommand setNewTree(AbstractTreeIterator newTree) {
200 this.newTree = newTree;
201 return this;
202 }
203
204
205
206
207
208
209 public DiffCommand setShowNameAndStatusOnly(boolean showNameAndStatusOnly) {
210 this.showNameAndStatusOnly = showNameAndStatusOnly;
211 return this;
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
270 public DiffCommand setProgressMonitor(ProgressMonitor monitor) {
271 this.monitor = monitor;
272 return this;
273 }
274 }