Skip to content

Commit edbf76f

Browse files
Peter KempterByron
Peter Kempter
authored andcommitted
Add trailer as commit property
With the command `git interpret-trailers` git provides a way to interact with trailer lines in the commit messages that look similar to RFC 822 e-mail headers (see: https://git-scm.com/docs/git-interpret-trailers). The new property returns those parsed trailer lines from the message as dictionary.
1 parent cdf7ffc commit edbf76f

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

Diff for: git/objects/commit.py

+40-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# This module is part of GitPython and is released under
55
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
66
import datetime
7+
import re
78
from subprocess import Popen
89
from gitdb import IStream
910
from git.util import (
@@ -39,7 +40,7 @@
3940

4041
# typing ------------------------------------------------------------------
4142

42-
from typing import Any, IO, Iterator, List, Sequence, Tuple, Union, TYPE_CHECKING, cast
43+
from typing import Any, IO, Iterator, List, Sequence, Tuple, Union, TYPE_CHECKING, cast, Dict
4344

4445
from git.types import PathLike, Literal
4546

@@ -315,6 +316,44 @@ def stats(self) -> Stats:
315316
text = self.repo.git.diff(self.parents[0].hexsha, self.hexsha, '--', numstat=True)
316317
return Stats._list_from_string(self.repo, text)
317318

319+
@property
320+
def trailers(self) -> Dict:
321+
"""Get the trailers of the message as dictionary
322+
323+
Git messages can contain trailer information that are similar to RFC 822
324+
e-mail headers (see: https://git-scm.com/docs/git-interpret-trailers).
325+
326+
The trailer is thereby the last paragraph (seperated by a empty line
327+
from the subject/body). This trailer paragraph must contain a ``:`` as
328+
seperator for key and value in every line.
329+
330+
Valid message with trailer:
331+
332+
.. code-block::
333+
334+
Subject line
335+
336+
some body information
337+
338+
another information
339+
340+
key1: value1
341+
key2: value2
342+
343+
:return: Dictionary containing whitespace stripped trailer information
344+
"""
345+
d: Dict[str, str] = {}
346+
match = re.search(r".+^\s*$\n([\w\n\s:]+?)\s*\Z", str(self.message), re.MULTILINE | re.DOTALL)
347+
if match is None:
348+
return d
349+
last_paragraph = match.group(1)
350+
if not all(':' in line for line in last_paragraph.split('\n')):
351+
return d
352+
for line in last_paragraph.split('\n'):
353+
key, value = line.split(':', 1)
354+
d[key.strip()] = value.strip()
355+
return d
356+
318357
@ classmethod
319358
def _iter_from_process_or_stream(cls, repo: 'Repo', proc_or_stream: Union[Popen, IO]) -> Iterator['Commit']:
320359
"""Parse out commit information into a list of Commit objects

0 commit comments

Comments
 (0)