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