View Javadoc
1   /*
2    * Copyright (C) 2008-2009, Google Inc. and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.revwalk;
12  
13  import static java.nio.charset.StandardCharsets.ISO_8859_1;
14  import static java.nio.charset.StandardCharsets.UTF_8;
15  import static org.junit.Assert.assertEquals;
16  import static org.junit.Assert.assertNotNull;
17  import static org.junit.Assert.assertNull;
18  import static org.junit.Assert.assertSame;
19  import static org.junit.Assert.assertTrue;
20  import static org.junit.Assert.fail;
21  
22  import java.io.ByteArrayOutputStream;
23  import java.io.UnsupportedEncodingException;
24  import java.nio.charset.IllegalCharsetNameException;
25  import java.nio.charset.UnsupportedCharsetException;
26  import java.util.TimeZone;
27  
28  import org.eclipse.jgit.junit.RepositoryTestCase;
29  import org.eclipse.jgit.lib.CommitBuilder;
30  import org.eclipse.jgit.lib.Constants;
31  import org.eclipse.jgit.lib.ObjectId;
32  import org.eclipse.jgit.lib.ObjectInserter;
33  import org.eclipse.jgit.lib.PersonIdent;
34  import org.junit.Test;
35  
36  public class RevCommitParseTest extends RepositoryTestCase {
37  	@Test
38  	public void testParse_NoParents() throws Exception {
39  		final ObjectId treeId = id("9788669ad918b6fcce64af8882fc9a81cb6aba67");
40  		final String authorName = "A U. Thor";
41  		final String authorEmail = "a_u_thor@example.com";
42  		final int authorTime = 1218123387;
43  		final String authorTimeZone = "+0700";
44  
45  		final String committerName = "C O. Miter";
46  		final String committerEmail = "comiter@example.com";
47  		final int committerTime = 1218123390;
48  		final String committerTimeZone = "-0500";
49  		final StringBuilder body = new StringBuilder();
50  
51  		body.append("tree ");
52  		body.append(treeId.name());
53  		body.append("\n");
54  
55  		body.append("author ");
56  		body.append(authorName);
57  		body.append(" <");
58  		body.append(authorEmail);
59  		body.append("> ");
60  		body.append(authorTime);
61  		body.append(" ");
62  		body.append(authorTimeZone);
63  		body.append(" \n");
64  
65  		body.append("committer ");
66  		body.append(committerName);
67  		body.append(" <");
68  		body.append(committerEmail);
69  		body.append("> ");
70  		body.append(committerTime);
71  		body.append(" ");
72  		body.append(committerTimeZone);
73  		body.append("\n");
74  
75  		body.append("\n");
76  
77  		final RevCommit c;
78  
79  		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
80  		assertNull(c.getTree());
81  		assertNull(c.getParents());
82  
83  		try (RevWalk rw = new RevWalk(db)) {
84  			c.parseCanonical(rw, body.toString().getBytes(UTF_8));
85  			assertNotNull(c.getTree());
86  			assertEquals(treeId, c.getTree().getId());
87  			assertSame(rw.lookupTree(treeId), c.getTree());
88  		}
89  		assertNotNull(c.getParents());
90  		assertEquals(0, c.getParentCount());
91  		assertEquals("", c.getFullMessage());
92  
93  		final PersonIdent cAuthor = c.getAuthorIdent();
94  		assertNotNull(cAuthor);
95  		assertEquals(authorName, cAuthor.getName());
96  		assertEquals(authorEmail, cAuthor.getEmailAddress());
97  		assertEquals((long) authorTime * 1000, cAuthor.getWhen().getTime());
98  		assertEquals(TimeZone.getTimeZone("GMT" + authorTimeZone),
99  				cAuthor.getTimeZone());
100 
101 		final PersonIdent cCommitter = c.getCommitterIdent();
102 		assertNotNull(cCommitter);
103 		assertEquals(committerName, cCommitter.getName());
104 		assertEquals(committerEmail, cCommitter.getEmailAddress());
105 		assertEquals((long) committerTime * 1000,
106 				cCommitter.getWhen().getTime());
107 		assertEquals(TimeZone.getTimeZone("GMT" + committerTimeZone),
108 				cCommitter.getTimeZone());
109 	}
110 
111 	private RevCommit create(String msg) throws Exception {
112 		final StringBuilder b = new StringBuilder();
113 		b.append("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n");
114 		b.append("author A U. Thor <a_u_thor@example.com> 1218123387 +0700\n");
115 		b.append("committer C O. Miter <c@example.com> 1218123390 -0500\n");
116 		b.append("\n");
117 		b.append(msg);
118 
119 		final RevCommit c;
120 		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
121 		try (RevWalk rw = new RevWalk(db)) {
122 			c.parseCanonical(rw, b.toString().getBytes(UTF_8));
123 			return c;
124 		}
125 	}
126 
127 	@Test
128 	public void testParse_WeirdHeaderOnlyCommit() throws Exception {
129 		final StringBuilder b = new StringBuilder();
130 		b.append("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n");
131 		b.append("author A U. Thor <a_u_thor@example.com> 1218123387 +0700\n");
132 		b.append("committer C O. Miter <c@example.com> 1218123390 -0500\n");
133 
134 		final RevCommit c;
135 		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
136 		try (RevWalk rw = new RevWalk(db)) {
137 			c.parseCanonical(rw, b.toString().getBytes(UTF_8));
138 		}
139 		assertEquals("", c.getFullMessage());
140 		assertEquals("", c.getShortMessage());
141 	}
142 
143 	@Test
144 	public void testParse_incompleteAuthorAndCommitter() throws Exception {
145 		final StringBuilder b = new StringBuilder();
146 		b.append("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n");
147 		b.append("author <a_u_thor@example.com> 1218123387 +0700\n");
148 		b.append("committer <> 1218123390 -0500\n");
149 
150 		final RevCommit c;
151 		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
152 		try (RevWalk rw = new RevWalk(db)) {
153 			c.parseCanonical(rw, b.toString().getBytes(UTF_8));
154 		}
155 		assertEquals(
156 				new PersonIdent("", "a_u_thor@example.com", 1218123387000l, 7),
157 				c.getAuthorIdent());
158 		assertEquals(new PersonIdent("", "", 1218123390000l, -5),
159 				c.getCommitterIdent());
160 	}
161 
162 	@Test
163 	public void testParse_implicit_UTF8_encoded() throws Exception {
164 		final ByteArrayOutputStream b = new ByteArrayOutputStream();
165 		b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
166 				.getBytes(UTF_8));
167 		b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n"
168 				.getBytes(UTF_8));
169 		b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n"
170 				.getBytes(UTF_8));
171 		b.write("\n".getBytes(UTF_8));
172 		b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8));
173 		b.write("\n".getBytes(UTF_8));
174 		b.write("\u304d\u308c\u3044\n".getBytes(UTF_8));
175 		final RevCommit c;
176 		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
177 		try (RevWalk rw = new RevWalk(db)) {
178 			c.parseCanonical(rw, b.toByteArray());
179 		}
180 		assertSame(UTF_8, c.getEncoding());
181 		assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
182 		assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage());
183 		assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n",
184 				c.getFullMessage());
185 	}
186 
187 	@Test
188 	public void testParse_implicit_mixed_encoded() throws Exception {
189 		final ByteArrayOutputStream b = new ByteArrayOutputStream();
190 		b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
191 				.getBytes(UTF_8));
192 		b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n"
193 				.getBytes(ISO_8859_1));
194 		b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n"
195 				.getBytes(UTF_8));
196 		b.write("\n".getBytes(UTF_8));
197 		b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8));
198 		b.write("\n".getBytes(UTF_8));
199 		b.write("\u304d\u308c\u3044\n".getBytes(UTF_8));
200 		final RevCommit c;
201 		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
202 		try (RevWalk rw = new RevWalk(db)) {
203 			c.parseCanonical(rw, b.toByteArray());
204 		}
205 		assertSame(UTF_8, c.getEncoding());
206 		assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
207 		assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage());
208 		assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n",
209 				c.getFullMessage());
210 	}
211 
212 	/**
213 	 * Test parsing of a commit whose encoding is given and works.
214 	 *
215 	 * @throws Exception
216 	 */
217 	@Test
218 	public void testParse_explicit_encoded() throws Exception {
219 		final ByteArrayOutputStream b = new ByteArrayOutputStream();
220 		b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
221 				.getBytes("EUC-JP"));
222 		b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n"
223 				.getBytes("EUC-JP"));
224 		b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n"
225 				.getBytes("EUC-JP"));
226 		b.write("encoding euc_JP\n".getBytes("EUC-JP"));
227 		b.write("\n".getBytes("EUC-JP"));
228 		b.write("\u304d\u308c\u3044\n".getBytes("EUC-JP"));
229 		b.write("\n".getBytes("EUC-JP"));
230 		b.write("Hi\n".getBytes("EUC-JP"));
231 		final RevCommit c;
232 		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
233 		try (RevWalk rw = new RevWalk(db)) {
234 			c.parseCanonical(rw, b.toByteArray());
235 		}
236 
237 		assertEquals("EUC-JP", c.getEncoding().name());
238 		assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
239 		assertEquals("\u304d\u308c\u3044", c.getShortMessage());
240 		assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage());
241 	}
242 
243 	/**
244 	 * This is a twisted case, but show what we expect here. We can revise the
245 	 * expectations provided this case is updated.
246 	 *
247 	 * What happens here is that an encoding us given, but data is not encoded
248 	 * that way (and we can detect it), so we try other encodings.
249 	 *
250 	 * @throws Exception
251 	 */
252 	@Test
253 	public void testParse_explicit_bad_encoded() throws Exception {
254 		final ByteArrayOutputStream b = new ByteArrayOutputStream();
255 		b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
256 				.getBytes(UTF_8));
257 		b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n"
258 				.getBytes(ISO_8859_1));
259 		b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n"
260 				.getBytes(UTF_8));
261 		b.write("encoding EUC-JP\n".getBytes(UTF_8));
262 		b.write("\n".getBytes(UTF_8));
263 		b.write("\u304d\u308c\u3044\n".getBytes(UTF_8));
264 		b.write("\n".getBytes(UTF_8));
265 		b.write("Hi\n".getBytes(UTF_8));
266 		final RevCommit c;
267 		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
268 		try (RevWalk rw = new RevWalk(db)) {
269 			c.parseCanonical(rw, b.toByteArray());
270 		}
271 
272 		assertEquals("EUC-JP", c.getEncoding().name());
273 		assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
274 		assertEquals("\u304d\u308c\u3044", c.getShortMessage());
275 		assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage());
276 	}
277 
278 	/**
279 	 * This is a twisted case too, but show what we expect here. We can revise
280 	 * the expectations provided this case is updated.
281 	 *
282 	 * What happens here is that an encoding us given, but data is not encoded
283 	 * that way (and we can detect it), so we try other encodings. Here data
284 	 * could actually be decoded in the stated encoding, but we override using
285 	 * UTF-8.
286 	 *
287 	 * @throws Exception
288 	 */
289 	@Test
290 	public void testParse_explicit_bad_encoded2() throws Exception {
291 		final ByteArrayOutputStream b = new ByteArrayOutputStream();
292 		b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
293 				.getBytes(UTF_8));
294 		b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n"
295 				.getBytes(UTF_8));
296 		b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n"
297 				.getBytes(UTF_8));
298 		b.write("encoding ISO-8859-1\n".getBytes(UTF_8));
299 		b.write("\n".getBytes(UTF_8));
300 		b.write("\u304d\u308c\u3044\n".getBytes(UTF_8));
301 		b.write("\n".getBytes(UTF_8));
302 		b.write("Hi\n".getBytes(UTF_8));
303 		final RevCommit c;
304 		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
305 		try (RevWalk rw = new RevWalk(db)) {
306 			c.parseCanonical(rw, b.toByteArray());
307 		}
308 
309 		assertEquals("ISO-8859-1", c.getEncoding().name());
310 		assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
311 		assertEquals("\u304d\u308c\u3044", c.getShortMessage());
312 		assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage());
313 	}
314 
315 	@Test
316 	public void testParse_incorrectUtf8Name() throws Exception {
317 		ByteArrayOutputStream b = new ByteArrayOutputStream();
318 		b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
319 				.getBytes(UTF_8));
320 		b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8));
321 		b.write("committer co <c@example.com> 1218123390 -0500\n"
322 				.getBytes(UTF_8));
323 		b.write("encoding 'utf8'\n".getBytes(UTF_8));
324 		b.write("\n".getBytes(UTF_8));
325 		b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8));
326 
327 		RevCommit c = new RevCommit(
328 				id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
329 		try (RevWalk rw = new RevWalk(db)) {
330 			c.parseCanonical(rw, b.toByteArray());
331 		}
332 		assertEquals("'utf8'", c.getEncodingName());
333 		assertEquals("Sm\u00f6rg\u00e5sbord\n", c.getFullMessage());
334 
335 		try {
336 			c.getEncoding();
337 			fail("Expected " + IllegalCharsetNameException.class);
338 		} catch (IllegalCharsetNameException badName) {
339 			assertEquals("'utf8'", badName.getMessage());
340 		}
341 	}
342 
343 	@Test
344 	public void testParse_illegalEncoding() throws Exception {
345 		ByteArrayOutputStream b = new ByteArrayOutputStream();
346 		b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
347 				.getBytes(UTF_8));
348 		b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8));
349 		b.write("committer co <c@example.com> 1218123390 -0500\n"
350 				.getBytes(UTF_8));
351 		b.write("encoding utf-8logoutputencoding=gbk\n".getBytes(UTF_8));
352 		b.write("\n".getBytes(UTF_8));
353 		b.write("message\n".getBytes(UTF_8));
354 
355 		RevCommit c = new RevCommit(
356 				id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
357 		try (RevWalk rw = new RevWalk(db)) {
358 			c.parseCanonical(rw, b.toByteArray());
359 		}
360 		assertEquals("utf-8logoutputencoding=gbk", c.getEncodingName());
361 		assertEquals("message\n", c.getFullMessage());
362 		assertEquals("message", c.getShortMessage());
363 		assertTrue(c.getFooterLines().isEmpty());
364 		assertEquals("au", c.getAuthorIdent().getName());
365 
366 		try {
367 			c.getEncoding();
368 			fail("Expected " + IllegalCharsetNameException.class);
369 		} catch (IllegalCharsetNameException badName) {
370 			assertEquals("utf-8logoutputencoding=gbk", badName.getMessage());
371 		}
372 	}
373 
374 	@Test
375 	public void testParse_unsupportedEncoding() throws Exception {
376 		ByteArrayOutputStream b = new ByteArrayOutputStream();
377 		b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
378 				.getBytes(UTF_8));
379 		b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8));
380 		b.write("committer co <c@example.com> 1218123390 -0500\n"
381 				.getBytes(UTF_8));
382 		b.write("encoding it_IT.UTF8\n".getBytes(UTF_8));
383 		b.write("\n".getBytes(UTF_8));
384 		b.write("message\n".getBytes(UTF_8));
385 
386 		RevCommit c = new RevCommit(
387 				id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
388 		try (RevWalk rw = new RevWalk(db)) {
389 			c.parseCanonical(rw, b.toByteArray());
390 		}
391 		assertEquals("it_IT.UTF8", c.getEncodingName());
392 		assertEquals("message\n", c.getFullMessage());
393 		assertEquals("message", c.getShortMessage());
394 		assertTrue(c.getFooterLines().isEmpty());
395 		assertEquals("au", c.getAuthorIdent().getName());
396 
397 		try {
398 			c.getEncoding();
399 			fail("Expected " + UnsupportedCharsetException.class);
400 		} catch (UnsupportedCharsetException badName) {
401 			assertEquals("it_IT.UTF8", badName.getMessage());
402 		}
403 	}
404 
405 	@Test
406 	public void testParse_NoMessage() throws Exception {
407 		final String msg = "";
408 		final RevCommit c = create(msg);
409 		assertEquals(msg, c.getFullMessage());
410 		assertEquals(msg, c.getShortMessage());
411 	}
412 
413 	@Test
414 	public void testParse_OnlyLFMessage() throws Exception {
415 		final RevCommit c = create("\n");
416 		assertEquals("\n", c.getFullMessage());
417 		assertEquals("", c.getShortMessage());
418 	}
419 
420 	@Test
421 	public void testParse_ShortLineOnlyNoLF() throws Exception {
422 		final String shortMsg = "This is a short message.";
423 		final RevCommit c = create(shortMsg);
424 		assertEquals(shortMsg, c.getFullMessage());
425 		assertEquals(shortMsg, c.getShortMessage());
426 	}
427 
428 	@Test
429 	public void testParse_ShortLineOnlyEndLF() throws Exception {
430 		final String shortMsg = "This is a short message.";
431 		final String fullMsg = shortMsg + "\n";
432 		final RevCommit c = create(fullMsg);
433 		assertEquals(fullMsg, c.getFullMessage());
434 		assertEquals(shortMsg, c.getShortMessage());
435 	}
436 
437 	@Test
438 	public void testParse_ShortLineOnlyEmbeddedLF() throws Exception {
439 		final String fullMsg = "This is a\nshort message.";
440 		final String shortMsg = fullMsg.replace('\n', ' ');
441 		final RevCommit c = create(fullMsg);
442 		assertEquals(fullMsg, c.getFullMessage());
443 		assertEquals(shortMsg, c.getShortMessage());
444 	}
445 
446 	@Test
447 	public void testParse_ShortLineOnlyEmbeddedAndEndingLF() throws Exception {
448 		final String fullMsg = "This is a\nshort message.\n";
449 		final String shortMsg = "This is a short message.";
450 		final RevCommit c = create(fullMsg);
451 		assertEquals(fullMsg, c.getFullMessage());
452 		assertEquals(shortMsg, c.getShortMessage());
453 	}
454 
455 	@Test
456 	public void testParse_GitStyleMessage() throws Exception {
457 		final String shortMsg = "This fixes a bug.";
458 		final String body = "We do it with magic and pixie dust and stuff.\n"
459 				+ "\n" + "Signed-off-by: A U. Thor <author@example.com>\n";
460 		final String fullMsg = shortMsg + "\n" + "\n" + body;
461 		final RevCommit c = create(fullMsg);
462 		assertEquals(fullMsg, c.getFullMessage());
463 		assertEquals(shortMsg, c.getShortMessage());
464 	}
465 
466 	@Test
467 	public void testParse_PublicParseMethod()
468 			throws UnsupportedEncodingException {
469 		CommitBuilder src = new CommitBuilder();
470 		try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) {
471 			src.setTreeId(fmt.idFor(Constants.OBJ_TREE, new byte[] {}));
472 		}
473 		src.setAuthor(author);
474 		src.setCommitter(committer);
475 		src.setMessage("Test commit\n\nThis is a test.\n");
476 
477 		RevCommit p = RevCommit.parse(src.build());
478 		assertEquals(src.getTreeId(), p.getTree());
479 		assertEquals(0, p.getParentCount());
480 		assertEquals(author, p.getAuthorIdent());
481 		assertEquals(committer, p.getCommitterIdent());
482 		assertEquals("Test commit", p.getShortMessage());
483 		assertEquals(src.getMessage(), p.getFullMessage());
484 	}
485 
486 	@Test
487 	public void testParse_GitStyleMessageWithCRLF() throws Exception {
488 		final String shortMsgIn = "This fixes a\r\nbug.\r\n\r\n";
489 		final String shortMsg = "This fixes a bug.";
490 		final String body = "We do it with magic and pixie dust\r\nand stuff.\r\n"
491 				+ "\r\n\r\n"
492 				+ "Signed-off-by: A U. Thor <author@example.com>\r\n";
493 		final String fullMsg = shortMsgIn + "\r\n" + "\r\n" + body;
494 		final RevCommit c = create(fullMsg);
495 		assertEquals(fullMsg, c.getFullMessage());
496 		assertEquals(shortMsg, c.getShortMessage());
497 	}
498 
499 	private static ObjectId id(String str) {
500 		return ObjectId.fromString(str);
501 	}
502 
503 	@Test
504 	public void testParse_gpgSig() throws Exception {
505 		String commit = "tree e3a1035abd2b319bb01e57d69b0ba6cab289297e\n"
506 				+ "parent 54e895b87c0768d2317a2b17062e3ad9f76a8105\n"
507 				+ "committer A U Thor <author@xample.com 1528968566 +0200\n"
508 				+ "gpgsig -----BEGIN PGP SIGNATURE-----\n" + " \n"
509 				+ " wsBcBAABCAAQBQJbGB4pCRBK7hj4Ov3rIwAAdHIIAENrvz23867ZgqrmyPemBEZP\n"
510 				+ " U24B1Tlq/DWvce2buaxmbNQngKZ0pv2s8VMc11916WfTIC9EKvioatmpjduWvhqj\n"
511 				+ " znQTFyiMor30pyYsfrqFuQZvqBW01o8GEWqLg8zjf9Rf0R3LlOEw86aT8CdHRlm6\n"
512 				+ " wlb22xb8qoX4RB+LYfz7MhK5F+yLOPXZdJnAVbuyoMGRnDpwdzjL5Hj671+XJxN5\n"
513 				+ " SasRdhxkkfw/ZnHxaKEc4juMz8Nziz27elRwhOQqlTYoXNJnsV//wy5Losd7aKi1\n"
514 				+ " xXXyUpndEOmT0CIcKHrN/kbYoVL28OJaxoBuva3WYQaRrzEe3X02NMxZe9gkSqA=\n"
515 				+ " =TClh\n" + " -----END PGP SIGNATURE-----\n"
516 				+ "some other header\n\n" + "commit message";
517 
518 		final RevCommit c;
519 		c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
520 		try (RevWalk rw = new RevWalk(db)) {
521 			c.parseCanonical(rw, commit.getBytes(UTF_8));
522 		}
523 		String gpgSig = new String(c.getRawGpgSignature(), UTF_8);
524 		assertTrue(gpgSig.startsWith("-----BEGIN"));
525 		assertTrue(gpgSig.endsWith("END PGP SIGNATURE-----"));
526 	}
527 
528 	@Test
529 	public void testParse_NoGpgSig() throws Exception {
530 		final RevCommit c = create("a message");
531 		assertNull(c.getRawGpgSignature());
532 	}
533 }