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 package org.eclipse.jgit.revwalk;
45
46 import static java.nio.charset.StandardCharsets.UTF_8;
47 import static org.junit.Assert.assertEquals;
48 import static org.junit.Assert.assertNotNull;
49 import static org.junit.Assert.assertNull;
50 import static org.junit.Assert.assertSame;
51 import static org.junit.Assert.assertTrue;
52 import static org.junit.Assert.fail;
53
54 import java.io.ByteArrayOutputStream;
55 import java.io.UnsupportedEncodingException;
56 import java.nio.charset.IllegalCharsetNameException;
57 import java.nio.charset.UnsupportedCharsetException;
58 import java.util.TimeZone;
59
60 import org.eclipse.jgit.junit.RepositoryTestCase;
61 import org.eclipse.jgit.lib.CommitBuilder;
62 import org.eclipse.jgit.lib.Constants;
63 import org.eclipse.jgit.lib.ObjectId;
64 import org.eclipse.jgit.lib.ObjectInserter;
65 import org.eclipse.jgit.lib.PersonIdent;
66 import org.junit.Test;
67
68 public class RevCommitParseTest extends RepositoryTestCase {
69 @Test
70 public void testParse_NoParents() throws Exception {
71 final ObjectId treeId = id("9788669ad918b6fcce64af8882fc9a81cb6aba67");
72 final String authorName = "A U. Thor";
73 final String authorEmail = "a_u_thor@example.com";
74 final int authorTime = 1218123387;
75 final String authorTimeZone = "+0700";
76
77 final String committerName = "C O. Miter";
78 final String committerEmail = "comiter@example.com";
79 final int committerTime = 1218123390;
80 final String committerTimeZone = "-0500";
81 final StringBuilder body = new StringBuilder();
82
83 body.append("tree ");
84 body.append(treeId.name());
85 body.append("\n");
86
87 body.append("author ");
88 body.append(authorName);
89 body.append(" <");
90 body.append(authorEmail);
91 body.append("> ");
92 body.append(authorTime);
93 body.append(" ");
94 body.append(authorTimeZone);
95 body.append(" \n");
96
97 body.append("committer ");
98 body.append(committerName);
99 body.append(" <");
100 body.append(committerEmail);
101 body.append("> ");
102 body.append(committerTime);
103 body.append(" ");
104 body.append(committerTimeZone);
105 body.append("\n");
106
107 body.append("\n");
108
109 final RevWalk rw = new RevWalk(db);
110 final RevCommit c;
111
112 c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
113 assertNull(c.getTree());
114 assertNull(c.parents);
115
116 c.parseCanonical(rw, body.toString().getBytes("UTF-8"));
117 assertNotNull(c.getTree());
118 assertEquals(treeId, c.getTree().getId());
119 assertSame(rw.lookupTree(treeId), c.getTree());
120
121 assertNotNull(c.parents);
122 assertEquals(0, c.parents.length);
123 assertEquals("", c.getFullMessage());
124
125 final PersonIdent cAuthor = c.getAuthorIdent();
126 assertNotNull(cAuthor);
127 assertEquals(authorName, cAuthor.getName());
128 assertEquals(authorEmail, cAuthor.getEmailAddress());
129 assertEquals((long)authorTime * 1000, cAuthor.getWhen().getTime());
130 assertEquals(TimeZone.getTimeZone("GMT" + authorTimeZone), cAuthor.getTimeZone());
131
132 final PersonIdent cCommitter = c.getCommitterIdent();
133 assertNotNull(cCommitter);
134 assertEquals(committerName, cCommitter.getName());
135 assertEquals(committerEmail, cCommitter.getEmailAddress());
136 assertEquals((long)committerTime * 1000, cCommitter.getWhen().getTime());
137 assertEquals(TimeZone.getTimeZone("GMT" + committerTimeZone), cCommitter.getTimeZone());
138 }
139
140 private RevCommit create(final String msg) throws Exception {
141 final StringBuilder b = new StringBuilder();
142 b.append("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n");
143 b.append("author A U. Thor <a_u_thor@example.com> 1218123387 +0700\n");
144 b.append("committer C O. Miter <c@example.com> 1218123390 -0500\n");
145 b.append("\n");
146 b.append(msg);
147
148 final RevCommit c;
149 c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
150 c.parseCanonical(new RevWalk(db), b.toString().getBytes("UTF-8"));
151 return c;
152 }
153
154 @Test
155 public void testParse_WeirdHeaderOnlyCommit() throws Exception {
156 final StringBuilder b = new StringBuilder();
157 b.append("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n");
158 b.append("author A U. Thor <a_u_thor@example.com> 1218123387 +0700\n");
159 b.append("committer C O. Miter <c@example.com> 1218123390 -0500\n");
160
161 final RevCommit c;
162 c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
163 c.parseCanonical(new RevWalk(db), b.toString().getBytes("UTF-8"));
164
165 assertEquals("", c.getFullMessage());
166 assertEquals("", c.getShortMessage());
167 }
168
169 @Test
170 public void testParse_incompleteAuthorAndCommitter() throws Exception {
171 final StringBuilder b = new StringBuilder();
172 b.append("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n");
173 b.append("author <a_u_thor@example.com> 1218123387 +0700\n");
174 b.append("committer <> 1218123390 -0500\n");
175
176 final RevCommit c;
177 c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
178 c.parseCanonical(new RevWalk(db), b.toString().getBytes("UTF-8"));
179
180 assertEquals(new PersonIdent("", "a_u_thor@example.com", 1218123387000l, 7), c.getAuthorIdent());
181 assertEquals(new PersonIdent("", "", 1218123390000l, -5), c.getCommitterIdent());
182 }
183
184 @Test
185 public void testParse_implicit_UTF8_encoded() throws Exception {
186 final ByteArrayOutputStream b = new ByteArrayOutputStream();
187 b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("UTF-8"));
188 b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("UTF-8"));
189 b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("UTF-8"));
190 b.write("\n".getBytes("UTF-8"));
191 b.write("Sm\u00f6rg\u00e5sbord\n".getBytes("UTF-8"));
192 b.write("\n".getBytes("UTF-8"));
193 b.write("\u304d\u308c\u3044\n".getBytes("UTF-8"));
194 final RevCommit c;
195 c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
196 c.parseCanonical(new RevWalk(db), b.toByteArray());
197
198 assertSame(Constants.CHARSET, c.getEncoding());
199 assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
200 assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage());
201 assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n", c.getFullMessage());
202 }
203
204 @Test
205 public void testParse_implicit_mixed_encoded() throws Exception {
206 final ByteArrayOutputStream b = new ByteArrayOutputStream();
207 b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("UTF-8"));
208 b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("ISO-8859-1"));
209 b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("UTF-8"));
210 b.write("\n".getBytes("UTF-8"));
211 b.write("Sm\u00f6rg\u00e5sbord\n".getBytes("UTF-8"));
212 b.write("\n".getBytes("UTF-8"));
213 b.write("\u304d\u308c\u3044\n".getBytes("UTF-8"));
214 final RevCommit c;
215 c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
216 c.parseCanonical(new RevWalk(db), b.toByteArray());
217
218 assertSame(Constants.CHARSET, c.getEncoding());
219 assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
220 assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage());
221 assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n", c.getFullMessage());
222 }
223
224
225
226
227
228
229 @Test
230 public void testParse_explicit_encoded() throws Exception {
231 final ByteArrayOutputStream b = new ByteArrayOutputStream();
232 b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("EUC-JP"));
233 b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("EUC-JP"));
234 b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("EUC-JP"));
235 b.write("encoding euc_JP\n".getBytes("EUC-JP"));
236 b.write("\n".getBytes("EUC-JP"));
237 b.write("\u304d\u308c\u3044\n".getBytes("EUC-JP"));
238 b.write("\n".getBytes("EUC-JP"));
239 b.write("Hi\n".getBytes("EUC-JP"));
240 final RevCommit c;
241 c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
242 c.parseCanonical(new RevWalk(db), b.toByteArray());
243
244 assertEquals("EUC-JP", c.getEncoding().name());
245 assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
246 assertEquals("\u304d\u308c\u3044", c.getShortMessage());
247 assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage());
248 }
249
250
251
252
253
254
255
256
257
258
259 @Test
260 public void testParse_explicit_bad_encoded() throws Exception {
261 final ByteArrayOutputStream b = new ByteArrayOutputStream();
262 b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("UTF-8"));
263 b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("ISO-8859-1"));
264 b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("UTF-8"));
265 b.write("encoding EUC-JP\n".getBytes("UTF-8"));
266 b.write("\n".getBytes("UTF-8"));
267 b.write("\u304d\u308c\u3044\n".getBytes("UTF-8"));
268 b.write("\n".getBytes("UTF-8"));
269 b.write("Hi\n".getBytes("UTF-8"));
270 final RevCommit c;
271 c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
272 c.parseCanonical(new RevWalk(db), b.toByteArray());
273
274 assertEquals("EUC-JP", c.getEncoding().name());
275 assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
276 assertEquals("\u304d\u308c\u3044", c.getShortMessage());
277 assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage());
278 }
279
280
281
282
283
284
285
286
287
288
289
290 @Test
291 public void testParse_explicit_bad_encoded2() throws Exception {
292 final ByteArrayOutputStream b = new ByteArrayOutputStream();
293 b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("UTF-8"));
294 b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("UTF-8"));
295 b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("UTF-8"));
296 b.write("encoding ISO-8859-1\n".getBytes("UTF-8"));
297 b.write("\n".getBytes("UTF-8"));
298 b.write("\u304d\u308c\u3044\n".getBytes("UTF-8"));
299 b.write("\n".getBytes("UTF-8"));
300 b.write("Hi\n".getBytes("UTF-8"));
301 final RevCommit c;
302 c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
303 c.parseCanonical(new RevWalk(db), b.toByteArray());
304
305 assertEquals("ISO-8859-1", c.getEncoding().name());
306 assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
307 assertEquals("\u304d\u308c\u3044", c.getShortMessage());
308 assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage());
309 }
310
311 @Test
312 public void testParse_incorrectUtf8Name() throws Exception {
313 ByteArrayOutputStream b = new ByteArrayOutputStream();
314 b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
315 .getBytes(UTF_8));
316 b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8));
317 b.write("committer co <c@example.com> 1218123390 -0500\n"
318 .getBytes(UTF_8));
319 b.write("encoding 'utf8'\n".getBytes(UTF_8));
320 b.write("\n".getBytes(UTF_8));
321 b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8));
322
323 RevCommit c = new RevCommit(
324 id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
325 c.parseCanonical(new RevWalk(db), b.toByteArray());
326 assertEquals("'utf8'", c.getEncodingName());
327 assertEquals("Sm\u00f6rg\u00e5sbord\n", c.getFullMessage());
328
329 try {
330 c.getEncoding();
331 fail("Expected " + IllegalCharsetNameException.class);
332 } catch (IllegalCharsetNameException badName) {
333 assertEquals("'utf8'", badName.getMessage());
334 }
335 }
336
337 @Test
338 public void testParse_illegalEncoding() throws Exception {
339 ByteArrayOutputStream b = new ByteArrayOutputStream();
340 b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8));
341 b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8));
342 b.write("committer co <c@example.com> 1218123390 -0500\n".getBytes(UTF_8));
343 b.write("encoding utf-8logoutputencoding=gbk\n".getBytes(UTF_8));
344 b.write("\n".getBytes(UTF_8));
345 b.write("message\n".getBytes(UTF_8));
346
347 RevCommit c = new RevCommit(
348 id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
349 c.parseCanonical(new RevWalk(db), b.toByteArray());
350 assertEquals("utf-8logoutputencoding=gbk", c.getEncodingName());
351 assertEquals("message\n", c.getFullMessage());
352 assertEquals("message", c.getShortMessage());
353 assertTrue(c.getFooterLines().isEmpty());
354 assertEquals("au", c.getAuthorIdent().getName());
355
356 try {
357 c.getEncoding();
358 fail("Expected " + IllegalCharsetNameException.class);
359 } catch (IllegalCharsetNameException badName) {
360 assertEquals("utf-8logoutputencoding=gbk", badName.getMessage());
361 }
362 }
363
364 @Test
365 public void testParse_unsupportedEncoding() throws Exception {
366 ByteArrayOutputStream b = new ByteArrayOutputStream();
367 b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8));
368 b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8));
369 b.write("committer co <c@example.com> 1218123390 -0500\n".getBytes(UTF_8));
370 b.write("encoding it_IT.UTF8\n".getBytes(UTF_8));
371 b.write("\n".getBytes(UTF_8));
372 b.write("message\n".getBytes(UTF_8));
373
374 RevCommit c = new RevCommit(
375 id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
376 c.parseCanonical(new RevWalk(db), b.toByteArray());
377 assertEquals("it_IT.UTF8", c.getEncodingName());
378 assertEquals("message\n", c.getFullMessage());
379 assertEquals("message", c.getShortMessage());
380 assertTrue(c.getFooterLines().isEmpty());
381 assertEquals("au", c.getAuthorIdent().getName());
382
383 try {
384 c.getEncoding();
385 fail("Expected " + UnsupportedCharsetException.class);
386 } catch (UnsupportedCharsetException badName) {
387 assertEquals("it_IT.UTF8", badName.getMessage());
388 }
389 }
390
391 @Test
392 public void testParse_NoMessage() throws Exception {
393 final String msg = "";
394 final RevCommit c = create(msg);
395 assertEquals(msg, c.getFullMessage());
396 assertEquals(msg, c.getShortMessage());
397 }
398
399 @Test
400 public void testParse_OnlyLFMessage() throws Exception {
401 final RevCommit c = create("\n");
402 assertEquals("\n", c.getFullMessage());
403 assertEquals("", c.getShortMessage());
404 }
405
406 @Test
407 public void testParse_ShortLineOnlyNoLF() throws Exception {
408 final String shortMsg = "This is a short message.";
409 final RevCommit c = create(shortMsg);
410 assertEquals(shortMsg, c.getFullMessage());
411 assertEquals(shortMsg, c.getShortMessage());
412 }
413
414 @Test
415 public void testParse_ShortLineOnlyEndLF() throws Exception {
416 final String shortMsg = "This is a short message.";
417 final String fullMsg = shortMsg + "\n";
418 final RevCommit c = create(fullMsg);
419 assertEquals(fullMsg, c.getFullMessage());
420 assertEquals(shortMsg, c.getShortMessage());
421 }
422
423 @Test
424 public void testParse_ShortLineOnlyEmbeddedLF() throws Exception {
425 final String fullMsg = "This is a\nshort message.";
426 final String shortMsg = fullMsg.replace('\n', ' ');
427 final RevCommit c = create(fullMsg);
428 assertEquals(fullMsg, c.getFullMessage());
429 assertEquals(shortMsg, c.getShortMessage());
430 }
431
432 @Test
433 public void testParse_ShortLineOnlyEmbeddedAndEndingLF() throws Exception {
434 final String fullMsg = "This is a\nshort message.\n";
435 final String shortMsg = "This is a short message.";
436 final RevCommit c = create(fullMsg);
437 assertEquals(fullMsg, c.getFullMessage());
438 assertEquals(shortMsg, c.getShortMessage());
439 }
440
441 @Test
442 public void testParse_GitStyleMessage() throws Exception {
443 final String shortMsg = "This fixes a bug.";
444 final String body = "We do it with magic and pixie dust and stuff.\n"
445 + "\n" + "Signed-off-by: A U. Thor <author@example.com>\n";
446 final String fullMsg = shortMsg + "\n" + "\n" + body;
447 final RevCommit c = create(fullMsg);
448 assertEquals(fullMsg, c.getFullMessage());
449 assertEquals(shortMsg, c.getShortMessage());
450 }
451
452 @Test
453 public void testParse_PublicParseMethod()
454 throws UnsupportedEncodingException {
455 CommitBuilder src = new CommitBuilder();
456 try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) {
457 src.setTreeId(fmt.idFor(Constants.OBJ_TREE, new byte[] {}));
458 }
459 src.setAuthor(author);
460 src.setCommitter(committer);
461 src.setMessage("Test commit\n\nThis is a test.\n");
462
463 RevCommit p = RevCommit.parse(src.build());
464 assertEquals(src.getTreeId(), p.getTree());
465 assertEquals(0, p.getParentCount());
466 assertEquals(author, p.getAuthorIdent());
467 assertEquals(committer, p.getCommitterIdent());
468 assertEquals("Test commit", p.getShortMessage());
469 assertEquals(src.getMessage(), p.getFullMessage());
470 }
471
472 @Test
473 public void testParse_GitStyleMessageWithCRLF() throws Exception {
474 final String shortMsgIn = "This fixes a\r\nbug.\r\n\r\n";
475 final String shortMsg = "This fixes a bug.";
476 final String body = "We do it with magic and pixie dust\r\nand stuff.\r\n"
477 + "\r\n\r\n"
478 + "Signed-off-by: A U. Thor <author@example.com>\r\n";
479 final String fullMsg = shortMsgIn + "\r\n" + "\r\n" + body;
480 final RevCommit c = create(fullMsg);
481 assertEquals(fullMsg, c.getFullMessage());
482 assertEquals(shortMsg, c.getShortMessage());
483 }
484
485 private static ObjectId id(final String str) {
486 return ObjectId.fromString(str);
487 }
488 }