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
44
45
46 package org.eclipse.jgit.pgm;
47
48 import java.io.BufferedOutputStream;
49 import java.io.IOException;
50 import java.text.DateFormat;
51 import java.text.MessageFormat;
52 import java.text.SimpleDateFormat;
53 import java.util.Locale;
54 import java.util.TimeZone;
55
56 import org.eclipse.jgit.diff.DiffFormatter;
57 import org.eclipse.jgit.diff.RawTextComparator;
58 import org.eclipse.jgit.diff.RenameDetector;
59 import org.eclipse.jgit.errors.CorruptObjectException;
60 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
61 import org.eclipse.jgit.errors.MissingObjectException;
62 import org.eclipse.jgit.errors.RevisionSyntaxException;
63 import org.eclipse.jgit.lib.Constants;
64 import org.eclipse.jgit.lib.FileMode;
65 import org.eclipse.jgit.lib.ObjectId;
66 import org.eclipse.jgit.lib.PersonIdent;
67 import org.eclipse.jgit.lib.Repository;
68 import org.eclipse.jgit.pgm.internal.CLIText;
69 import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
70 import org.eclipse.jgit.revwalk.RevCommit;
71 import org.eclipse.jgit.revwalk.RevObject;
72 import org.eclipse.jgit.revwalk.RevTag;
73 import org.eclipse.jgit.revwalk.RevTree;
74 import org.eclipse.jgit.revwalk.RevWalk;
75 import org.eclipse.jgit.treewalk.TreeWalk;
76 import org.eclipse.jgit.treewalk.filter.TreeFilter;
77 import org.kohsuke.args4j.Argument;
78 import org.kohsuke.args4j.Option;
79
80 @Command(common = true, usage = "usage_show")
81 class Show extends TextBuiltin {
82 private final TimeZone myTZ = TimeZone.getDefault();
83
84 private final DateFormat fmt;
85
86 private DiffFormatter diffFmt;
87
88 @Argument(index = 0, metaVar = "metaVar_object")
89 private String objectName;
90
91 @Option(name = "--", metaVar = "metaVar_path", handler = PathTreeFilterHandler.class)
92 protected TreeFilter pathFilter = TreeFilter.ALL;
93
94
95 @Option(name = "-p", usage = "usage_showPatch")
96 boolean showPatch;
97
98 @Option(name = "-M", usage = "usage_detectRenames")
99 private Boolean detectRenames;
100
101 @Option(name = "--no-renames", usage = "usage_noRenames")
102 void noRenames(@SuppressWarnings("unused") boolean on) {
103 detectRenames = Boolean.FALSE;
104 }
105
106 @Option(name = "-l", usage = "usage_renameLimit")
107 private Integer renameLimit;
108
109 @Option(name = "--name-status", usage = "usage_nameStatus")
110 private boolean showNameAndStatusOnly;
111
112 @Option(name = "--ignore-space-at-eol")
113 void ignoreSpaceAtEol(@SuppressWarnings("unused") boolean on) {
114 diffFmt.setDiffComparator(RawTextComparator.WS_IGNORE_TRAILING);
115 }
116
117 @Option(name = "--ignore-leading-space")
118 void ignoreLeadingSpace(@SuppressWarnings("unused") boolean on) {
119 diffFmt.setDiffComparator(RawTextComparator.WS_IGNORE_LEADING);
120 }
121
122 @Option(name = "-b", aliases = { "--ignore-space-change" })
123 void ignoreSpaceChange(@SuppressWarnings("unused") boolean on) {
124 diffFmt.setDiffComparator(RawTextComparator.WS_IGNORE_CHANGE);
125 }
126
127 @Option(name = "-w", aliases = { "--ignore-all-space" })
128 void ignoreAllSpace(@SuppressWarnings("unused") boolean on) {
129 diffFmt.setDiffComparator(RawTextComparator.WS_IGNORE_ALL);
130 }
131
132 @Option(name = "-U", aliases = { "--unified" }, metaVar = "metaVar_linesOfContext")
133 void unified(int lines) {
134 diffFmt.setContext(lines);
135 }
136
137 @Option(name = "--abbrev", metaVar = "metaVar_n")
138 void abbrev(int lines) {
139 diffFmt.setAbbreviationLength(lines);
140 }
141
142 @Option(name = "--full-index")
143 void abbrev(@SuppressWarnings("unused") boolean on) {
144 diffFmt.setAbbreviationLength(Constants.OBJECT_ID_STRING_LENGTH);
145 }
146
147 @Option(name = "--src-prefix", usage = "usage_srcPrefix")
148 void sourcePrefix(String path) {
149 diffFmt.setOldPrefix(path);
150 }
151
152 @Option(name = "--dst-prefix", usage = "usage_dstPrefix")
153 void dstPrefix(String path) {
154 diffFmt.setNewPrefix(path);
155 }
156
157 @Option(name = "--no-prefix", usage = "usage_noPrefix")
158 void noPrefix(@SuppressWarnings("unused") boolean on) {
159 diffFmt.setOldPrefix("");
160 diffFmt.setNewPrefix("");
161 }
162
163
164
165 Show() {
166 fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy ZZZZZ", Locale.US);
167 }
168
169
170 @Override
171 protected void init(Repository repository, String gitDir) {
172 super.init(repository, gitDir);
173 diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
174 }
175
176
177 @SuppressWarnings("boxing")
178 @Override
179 protected void run() {
180 diffFmt.setRepository(db);
181 try {
182 diffFmt.setPathFilter(pathFilter);
183 if (detectRenames != null) {
184 diffFmt.setDetectRenames(detectRenames.booleanValue());
185 }
186 if (renameLimit != null && diffFmt.isDetectRenames()) {
187 RenameDetector rd = diffFmt.getRenameDetector();
188 rd.setRenameLimit(renameLimit.intValue());
189 }
190
191 ObjectId objectId;
192 if (objectName == null) {
193 objectId = db.resolve(Constants.HEAD);
194 } else {
195 objectId = db.resolve(objectName);
196 }
197
198 try (RevWalkRevWalk.html#RevWalk">RevWalk rw = new RevWalk(db)) {
199 RevObject obj = rw.parseAny(objectId);
200 while (obj instanceof RevTag) {
201 show((RevTag) obj);
202 obj = ((RevTag) obj).getObject();
203 rw.parseBody(obj);
204 }
205
206 switch (obj.getType()) {
207 case Constants.OBJ_COMMIT:
208 show(rw, (RevCommit) obj);
209 break;
210
211 case Constants.OBJ_TREE:
212 outw.print("tree ");
213 outw.print(objectName);
214 outw.println();
215 outw.println();
216 show((RevTree) obj);
217 break;
218
219 case Constants.OBJ_BLOB:
220 db.open(obj, obj.getType()).copyTo(System.out);
221 outw.flush();
222 break;
223
224 default:
225 throw die(MessageFormat.format(
226 CLIText.get().cannotReadBecause, obj.name(),
227 obj.getType()));
228 }
229 }
230 } catch (RevisionSyntaxException | IOException e) {
231 throw die(e.getMessage(), e);
232 } finally {
233 diffFmt.close();
234 }
235 }
236
237 private void show(RevTag tag) throws IOException {
238 outw.print(CLIText.get().tagLabel);
239 outw.print(" ");
240 outw.print(tag.getTagName());
241 outw.println();
242
243 final PersonIdent tagger = tag.getTaggerIdent();
244 if (tagger != null) {
245 outw.println(MessageFormat.format(CLIText.get().taggerInfo,
246 tagger.getName(), tagger.getEmailAddress()));
247
248 final TimeZone taggerTZ = tagger.getTimeZone();
249 fmt.setTimeZone(taggerTZ != null ? taggerTZ : myTZ);
250 outw.println(MessageFormat.format(CLIText.get().dateInfo,
251 fmt.format(tagger.getWhen())));
252 }
253
254 outw.println();
255 final String[] lines = tag.getFullMessage().split("\n");
256 for (String s : lines) {
257 outw.print(" ");
258 outw.print(s);
259 outw.println();
260 }
261
262 outw.println();
263 }
264
265 private void show(RevTree obj) throws MissingObjectException,
266 IncorrectObjectTypeException, CorruptObjectException, IOException {
267 try (TreeWalkeeWalk.html#TreeWalk">TreeWalk walk = new TreeWalk(db)) {
268 walk.reset();
269 walk.addTree(obj);
270
271 while (walk.next()) {
272 outw.print(walk.getPathString());
273 final FileMode mode = walk.getFileMode(0);
274 if (mode == FileMode.TREE)
275 outw.print("/");
276 outw.println();
277 }
278 }
279 }
280
281 private void show(RevWalk rw, RevCommit c) throws IOException {
282 char[] outbuffer = new char[Constants.OBJECT_ID_LENGTH * 2];
283
284 outw.print(CLIText.get().commitLabel);
285 outw.print(" ");
286 c.getId().copyTo(outbuffer, outw);
287 outw.println();
288
289 final PersonIdent author = c.getAuthorIdent();
290 outw.println(MessageFormat.format(CLIText.get().authorInfo,
291 author.getName(), author.getEmailAddress()));
292
293 final TimeZone authorTZ = author.getTimeZone();
294 fmt.setTimeZone(authorTZ != null ? authorTZ : myTZ);
295 outw.println(MessageFormat.format(CLIText.get().dateInfo,
296 fmt.format(author.getWhen())));
297
298 outw.println();
299 final String[] lines = c.getFullMessage().split("\n");
300 for (String s : lines) {
301 outw.print(" ");
302 outw.print(s);
303 outw.println();
304 }
305
306 outw.println();
307 if (c.getParentCount() == 1) {
308 rw.parseHeaders(c.getParent(0));
309 showDiff(c);
310 }
311 outw.flush();
312 }
313
314 private void showDiff(RevCommit c) throws IOException {
315 final RevTree a = c.getParent(0).getTree();
316 final RevTree b = c.getTree();
317
318 if (showNameAndStatusOnly)
319 Diff.nameStatus(outw, diffFmt.scan(a, b));
320 else {
321 outw.flush();
322 diffFmt.format(a, b);
323 diffFmt.flush();
324 }
325 outw.println();
326 }
327 }