Skip to content

Commit

Permalink
Use git interpret-trailers for trailers property
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Ket3r authored and Byron committed Jan 7, 2022
1 parent edbf76f commit cd8b9b2
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 19 deletions.
43 changes: 26 additions & 17 deletions git/objects/commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -14,6 +13,7 @@
finalize_process
)
from git.diff import Diffable
from git.cmd import Git

from .tree import Tree
from . import base
Expand Down Expand Up @@ -322,10 +322,10 @@ def trailers(self) -> Dict:
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:
Expand All @@ -338,20 +338,29 @@ def trailers(self) -> Dict:
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
Expand Down
4 changes: 2 additions & 2 deletions test/test_commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,14 +435,14 @@ def test_trailers(self):
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')
Expand Down

0 comments on commit cd8b9b2

Please sign in to comment.