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