summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Kempter <peter.kempter@rohde-schwarz.com>2021-09-29 12:08:56 +0200
committerSebastian Thiel <sebastian.thiel@icloud.com>2022-01-07 09:54:53 +0800
commitedbf76f98f8430d711115f2c754de88e268e9303 (patch)
tree39c1fb1abae2c5421c586b43e9e2b3351a28d1ff
parentcdf7ffc33fa05ba5afcb915a374c140c7658c839 (diff)
downloadgitpython-edbf76f98f8430d711115f2c754de88e268e9303.tar.gz
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.
-rw-r--r--git/objects/commit.py41
1 files changed, 40 insertions, 1 deletions
diff --git a/git/objects/commit.py b/git/objects/commit.py
index b36cd46d..780461a0 100644
--- a/git/objects/commit.py
+++ b/git/objects/commit.py
@@ -4,6 +4,7 @@
# This module is part of GitPython and is released under
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
import datetime
+import re
from subprocess import Popen
from gitdb import IStream
from git.util import (
@@ -39,7 +40,7 @@ import logging
# typing ------------------------------------------------------------------
-from typing import Any, IO, Iterator, List, Sequence, Tuple, Union, TYPE_CHECKING, cast
+from typing import Any, IO, Iterator, List, Sequence, Tuple, Union, TYPE_CHECKING, cast, Dict
from git.types import PathLike, Literal
@@ -315,6 +316,44 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
text = self.repo.git.diff(self.parents[0].hexsha, self.hexsha, '--', numstat=True)
return Stats._list_from_string(self.repo, text)
+ @property
+ def trailers(self) -> Dict:
+ """Get the trailers of the message as dictionary
+
+ Git messages can contain trailer information that are similar to RFC 822
+ e-mail headers (see: https://git-scm.com/docs/git-interpret-trailers).
+
+ The trailer is thereby the last paragraph (seperated by a empty line
+ from the subject/body). This trailer paragraph must contain a ``:`` as
+ seperator for key and value in every line.
+
+ Valid message with trailer:
+
+ .. code-block::
+
+ Subject line
+
+ some body information
+
+ another information
+
+ key1: value1
+ key2: value2
+
+ :return: Dictionary containing whitespace stripped trailer information
+ """
+ d: Dict[str, str] = {}
+ match = re.search(r".+^\s*$\n([\w\n\s:]+?)\s*\Z", str(self.message), re.MULTILINE | re.DOTALL)
+ if match is None:
+ return d
+ last_paragraph = match.group(1)
+ if not all(':' in line for line in last_paragraph.split('\n')):
+ return d
+ for line in last_paragraph.split('\n'):
+ key, value = line.split(':', 1)
+ d[key.strip()] = value.strip()
+ return d
+
@ classmethod
def _iter_from_process_or_stream(cls, repo: 'Repo', proc_or_stream: Union[Popen, IO]) -> Iterator['Commit']:
"""Parse out commit information into a list of Commit objects