patman: Show base commit on each patch when no cover letter

If a series is sent without a cover letter, there is no indication of
the base commit. Add support for this, since single patches of small
series may not always have a cover letter.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2025-03-28 07:02:20 -06:00 committed by Tom Rini
parent 5a7ad313a1
commit 60218f07f3
3 changed files with 55 additions and 6 deletions

View file

@ -63,7 +63,8 @@ def prepare_patches(col, branch, count, start, end, ignore_binary, signoff,
branch, start, to_do, ignore_binary, series, signoff) branch, start, to_do, ignore_binary, series, signoff)
# Fix up the patch files to our liking, and insert the cover letter # Fix up the patch files to our liking, and insert the cover letter
patchstream.fix_patches(series, patch_files, keep_change_id) patchstream.fix_patches(series, patch_files, keep_change_id,
insert_base_commit=not cover_fname)
if cover_fname and series.get('cover'): if cover_fname and series.get('cover'):
patchstream.insert_cover_letter(cover_fname, series, to_do) patchstream.insert_cover_letter(cover_fname, series, to_do)
return series, cover_fname, patch_files return series, cover_fname, patch_files

View file

@ -357,6 +357,31 @@ Changes in v2:
expected = expected.splitlines() expected = expected.splitlines()
self.assertEqual(expected, lines[start:(start+len(expected))]) self.assertEqual(expected, lines[start:(start+len(expected))])
def test_base_commit(self):
"""Test adding a base commit with no cover letter"""
orig_text = self._get_text('test01.txt')
pos = orig_text.index('commit 5ab48490f03051875ab13d288a4bf32b507d76fd')
text = orig_text[:pos]
series = patchstream.get_metadata_for_test(text)
series.base_commit = Commit('1a44532')
series.branch = 'mybranch'
cover_fname, args = self._create_patches_for_test(series)
self.assertFalse(cover_fname)
with capture_sys_output() as out:
patchstream.fix_patches(series, args, insert_base_commit=True)
self.assertEqual('Cleaned 1 patch\n', out[0].getvalue())
lines = tools.read_file(args[0], binary=False).splitlines()
pos = lines.index('-- ')
# We expect these lines at the end:
# -- (with trailing space)
# 2.7.4
# (empty)
# base-commit: xxx
# branch: xxx
self.assertEqual('base-commit: 1a44532', lines[pos + 3])
self.assertEqual('branch: mybranch', lines[pos + 4])
def make_commit_with_file(self, subject, body, fname, text): def make_commit_with_file(self, subject, body, fname, text):
"""Create a file and add it to the git repo with a new commit """Create a file and add it to the git repo with a new commit
@ -527,6 +552,11 @@ complicated as possible''')
self.assertEqual(f'base-commit: {base}', lines[0]) self.assertEqual(f'base-commit: {base}', lines[0])
self.assertEqual('branch: second', lines[1]) self.assertEqual('branch: second', lines[1])
# Make sure that the base-commit is not present when it is in the
# cover letter
for fname in patch_files:
self.assertNotIn(b'base-commit:', tools.read_file(fname))
# Check that it can skip patches at the end # Check that it can skip patches at the end
with capture_sys_output() as _: with capture_sys_output() as _:
_, cover_fname, patch_files = control.prepare_patches( _, cover_fname, patch_files = control.prepare_patches(

View file

@ -76,8 +76,13 @@ class PatchStream:
are interested in. We can also process a patch file in order to remove are interested in. We can also process a patch file in order to remove
unwanted tags or inject additional ones. These correspond to the two unwanted tags or inject additional ones. These correspond to the two
phases of processing. phases of processing.
Args:
keep_change_id (bool): Keep the Change-Id tag
insert_base_commit (bool): True to add the base commit to the end
""" """
def __init__(self, series, is_log=False, keep_change_id=False): def __init__(self, series, is_log=False, keep_change_id=False,
insert_base_commit=False):
self.skip_blank = False # True to skip a single blank line self.skip_blank = False # True to skip a single blank line
self.found_test = False # Found a TEST= line self.found_test = False # Found a TEST= line
self.lines_after_test = 0 # Number of lines found after TEST= self.lines_after_test = 0 # Number of lines found after TEST=
@ -103,6 +108,7 @@ class PatchStream:
self.recent_quoted = collections.deque([], 5) self.recent_quoted = collections.deque([], 5)
self.recent_unquoted = queue.Queue() self.recent_unquoted = queue.Queue()
self.was_quoted = None self.was_quoted = None
self.insert_base_commit = insert_base_commit
@staticmethod @staticmethod
def process_text(text, is_comment=False): def process_text(text, is_comment=False):
@ -658,6 +664,13 @@ class PatchStream:
outfd.write(line + '\n') outfd.write(line + '\n')
self.blank_count = 0 self.blank_count = 0
self.finalise() self.finalise()
if self.insert_base_commit:
if self.series.base_commit:
print(f'base-commit: {self.series.base_commit.hash}',
file=outfd)
if self.series.branch:
print(f'branch: {self.series.branch}', file=outfd)
def insert_tags(msg, tags_to_emit): def insert_tags(msg, tags_to_emit):
"""Add extra tags to a commit message """Add extra tags to a commit message
@ -778,7 +791,8 @@ def get_metadata_for_test(text):
pst.finalise() pst.finalise()
return series return series
def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False): def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False,
insert_base_commit=False):
"""Fix up a patch file, by adding/removing as required. """Fix up a patch file, by adding/removing as required.
We remove our tags from the patch file, insert changes lists, etc. We remove our tags from the patch file, insert changes lists, etc.
@ -792,6 +806,7 @@ def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False):
series (Series): Series information about this patch set series (Series): Series information about this patch set
cmt (Commit): Commit object for this patch file cmt (Commit): Commit object for this patch file
keep_change_id (bool): Keep the Change-Id tag. keep_change_id (bool): Keep the Change-Id tag.
insert_base_commit (bool): True to add the base commit to the end
Return: Return:
list: A list of errors, each str, or [] if all ok. list: A list of errors, each str, or [] if all ok.
@ -799,7 +814,8 @@ def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False):
handle, tmpname = tempfile.mkstemp() handle, tmpname = tempfile.mkstemp()
outfd = os.fdopen(handle, 'w', encoding='utf-8') outfd = os.fdopen(handle, 'w', encoding='utf-8')
infd = open(fname, 'r', encoding='utf-8') infd = open(fname, 'r', encoding='utf-8')
pst = PatchStream(series, keep_change_id=keep_change_id) pst = PatchStream(series, keep_change_id=keep_change_id,
insert_base_commit=insert_base_commit)
pst.commit = cmt pst.commit = cmt
pst.process_stream(infd, outfd) pst.process_stream(infd, outfd)
infd.close() infd.close()
@ -811,7 +827,7 @@ def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False):
shutil.move(tmpname, fname) shutil.move(tmpname, fname)
return cmt.warn return cmt.warn
def fix_patches(series, fnames, keep_change_id=False): def fix_patches(series, fnames, keep_change_id=False, insert_base_commit=False):
"""Fix up a list of patches identified by filenames """Fix up a list of patches identified by filenames
The patch files are processed in place, and overwritten. The patch files are processed in place, and overwritten.
@ -820,6 +836,7 @@ def fix_patches(series, fnames, keep_change_id=False):
series (Series): The Series object series (Series): The Series object
fnames (:type: list of str): List of patch files to process fnames (:type: list of str): List of patch files to process
keep_change_id (bool): Keep the Change-Id tag. keep_change_id (bool): Keep the Change-Id tag.
insert_base_commit (bool): True to add the base commit to the end
""" """
# Current workflow creates patches, so we shouldn't need a backup # Current workflow creates patches, so we shouldn't need a backup
backup_dir = None #tempfile.mkdtemp('clean-patch') backup_dir = None #tempfile.mkdtemp('clean-patch')
@ -829,7 +846,8 @@ def fix_patches(series, fnames, keep_change_id=False):
cmt.patch = fname cmt.patch = fname
cmt.count = count cmt.count = count
result = fix_patch(backup_dir, fname, series, cmt, result = fix_patch(backup_dir, fname, series, cmt,
keep_change_id=keep_change_id) keep_change_id=keep_change_id,
insert_base_commit=insert_base_commit)
if result: if result:
print('%d warning%s for %s:' % print('%d warning%s for %s:' %
(len(result), 's' if len(result) > 1 else '', fname)) (len(result), 's' if len(result) > 1 else '', fname))