summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKet3r <github@peter-kempter.de>2021-09-30 16:07:05 +0200
committerSebastian Thiel <sebastian.thiel@icloud.com>2022-01-07 09:54:53 +0800
commitcd8b9b2fd875b5040b1ca9f0c8f5acaffe70ab7f (patch)
treefbbc852b6ef46bf08fb0b36f7f6fb3733895e24e
parentedbf76f98f8430d711115f2c754de88e268e9303 (diff)
downloadgitpython-cd8b9b2fd875b5040b1ca9f0c8f5acaffe70ab7f.tar.gz
Use git interpret-trailers for trailers property
The whitespace handling and trailer selection isn't very trivial or good documented. It therefore seemed easier and less error prone to just call git to parse the message for the trailers section and remove superfluos whitespaces.
-rw-r--r--git/objects/commit.py43
-rw-r--r--test/test_commit.py4
2 files changed, 28 insertions, 19 deletions
diff --git a/git/objects/commit.py b/git/objects/commit.py
index 780461a0..bbd485da 100644
--- a/git/objects/commit.py
+++ b/git/objects/commit.py
@@ -4,8 +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 subprocess import Popen, PIPE
from gitdb import IStream
from git.util import (
hex_to_bin,
@@ -14,6 +13,7 @@ from git.util import (
finalize_process
)
from git.diff import Diffable
+from git.cmd import Git
from .tree import Tree
from . import base
@@ -322,10 +322,10 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
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.
+
+ This funcions calls ``git interpret-trailers --parse`` onto the message
+ to extract the trailer information. The key value pairs are stripped of
+ leading and trailing whitespaces before they get saved into a dictionary.
Valid message with trailer:
@@ -338,20 +338,29 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
another information
key1: value1
- key2: value2
+ key2 : value 2 with inner spaces
+
+ dictionary will look like this:
+ .. code-block::
+
+ {
+ "key1": "value1",
+ "key2": "value 2 with inner spaces"
+ }
: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()
+ d = {}
+ cmd = ['git', 'interpret-trailers', '--parse']
+ proc: Git.AutoInterrupt = self.repo.git.execute(cmd, as_process=True, istream=PIPE) # type: ignore
+ trailer: str = proc.communicate(str(self.message).encode())[0].decode()
+ if trailer.endswith('\n'):
+ trailer = trailer[0:-1]
+ if trailer != '':
+ for line in trailer.split('\n'):
+ key, value = line.split(':', 1)
+ d[key.strip()] = value.strip()
return d
@ classmethod
diff --git a/test/test_commit.py b/test/test_commit.py
index 5aeef2e6..40cf7dd2 100644
--- a/test/test_commit.py
+++ b/test/test_commit.py
@@ -435,14 +435,14 @@ JzJMZDRLQLFvnzqZuCjE
KEY_1 = "Hello"
VALUE_1 = "World"
KEY_2 = "Key"
- VALUE_2 = "Value"
+ VALUE_2 = "Value with inner spaces"
# Check if KEY 1 & 2 with Value 1 & 2 is extracted from multiple msg variations
msgs = []
msgs.append(f"Subject\n\n{KEY_1}: {VALUE_1}\n{KEY_2}: {VALUE_2}\n")
msgs.append(f"Subject\n \nSome body of a function\n \n{KEY_1}: {VALUE_1}\n{KEY_2}: {VALUE_2}\n")
msgs.append(f"Subject\n \nSome body of a function\n\nnon-key: non-value\n\n{KEY_1}: {VALUE_1}\n{KEY_2}: {VALUE_2}\n")
- msgs.append(f"Subject\n \nSome multiline\n body of a function\n\nnon-key: non-value\n\n{KEY_1}: {VALUE_1}\n{KEY_2}: {VALUE_2}\n")
+ msgs.append(f"Subject\n \nSome multiline\n body of a function\n\nnon-key: non-value\n\n{KEY_1}: {VALUE_1}\n{KEY_2} : {VALUE_2}\n")
for msg in msgs:
commit = self.rorepo.commit('master')