* [PATCH b4] b4: Add option to b4-send to include git-notes
@ 2026-02-25 1:01 Vishal Verma
2026-02-25 2:54 ` Konstantin Ryabitsev
0 siblings, 1 reply; 4+ messages in thread
From: Vishal Verma @ 2026-02-25 1:01 UTC (permalink / raw)
To: Kernel.org Tools; +Cc: Konstantin Ryabitsev, Vishal Verma
Add an option (and a config entry) for b4-send to include any git-notes
in the formatted patch after the '---' break.
Note that git-show with the notes option adds notes with a 'Notes:'
prefix, and with an indent. The convention for mailing lists is
typically to just include the notes after the break, without either of
the above. Do some regex munging to remove it.
Assisted by Claude Code.
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
I've only tested this using b4 send --dry-run until now. This patch
should be the first time actually sending anything with the
modifications. This paragraph should be coming from git-notes, not from
the b4-prep cover letter as it can for a single patch series - but I've
left the cover letter empty.
docs/config.rst | 22 ++++++++++++++++++++++
src/b4/__init__.py | 13 ++++++++++++-
src/b4/command.py | 4 ++++
src/b4/ez.py | 29 +++++++++++++++++++++--------
4 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/docs/config.rst b/docs/config.rst
index a1145af..8c7b3eb 100644
--- a/docs/config.rst
+++ b/docs/config.rst
@@ -437,6 +437,28 @@ Contributor-oriented settings
Default: ``None``
+``b4.send-notes``
+ When set, includes git notes in the patches below the ``---`` line. This is
+ useful for adding per-patch changelog entries or other annotations that
+ should not be part of the permanent commit message. Notes are appended by
+ passing ``--notes`` to ``git show`` when generating patches. This can be
+ overridden on the command line with ``--notes`` or ``--no-notes`` flags to
+ ``b4 send``.
+
+ .. note::
+
+ Since git notes are keyed by commit hash, they are normally lost
+ when commits are rebased or amended (e.g. by ``b4 prep --edit-cover``).
+ To make git preserve notes across these operations, set the following
+ in your git configuration::
+
+ [notes]
+ rewriteRef = refs/notes/commits
+ rewrite.rebase = true
+ rewrite.amend = true
+
+ Default: ``no``
+
``b4.prep-perpatch-check-cmd`` (v0.14+)
The command to use when running ``--check``. The command is run once for each
patch to check. The patch file to check is piped through stdin. If this
diff --git a/src/b4/__init__.py b/src/b4/__init__.py
index 3d774f7..4309325 100644
--- a/src/b4/__init__.py
+++ b/src/b4/__init__.py
@@ -3670,7 +3670,8 @@ def git_range_to_patches(gitdir: Optional[str], start: str, end: str,
extrahdrs: Optional[List[Tuple[str, str]]] = None,
ignore_commits: Optional[Set[str]] = None,
limit_committer: Optional[str] = None,
- presubject: Optional[str] = None) -> List[Tuple[str, EmailMessage]]:
+ presubject: Optional[str] = None,
+ with_notes: bool = False) -> List[Tuple[str, EmailMessage]]:
gitargs = ['rev-list', '--no-merges', '--reverse']
if limit_committer:
gitargs += ['-F', f'--committer={limit_committer}']
@@ -3694,6 +3695,8 @@ def git_range_to_patches(gitdir: Optional[str], start: str, end: str,
'--encoding=utf-8',
'--find-renames',
]
+ if with_notes:
+ showargs.append('--notes')
if git_check_minimal_version("2.40"):
showargs.append("--default-prefix")
@@ -3758,6 +3761,14 @@ def git_range_to_patches(gitdir: Optional[str], start: str, end: str,
payload = msg.get_payload(decode=True)
if isinstance(payload, bytes):
payload = payload.decode()
+ if with_notes:
+ # git show --notes adds notes with a "Notes:" header and
+ # indentation. Strip that to match the mailing list
+ # convention of plain text after the "---" line.
+ payload = re.sub(
+ r'\nNotes:\n((?:[ \t]+.+\n)+)',
+ lambda m: '\n' + re.sub(r'^[ \t]+', '', m.group(1), flags=re.MULTILINE),
+ payload)
if inbodyhdrs:
payload = '\n'.join(inbodyhdrs) + '\n\n' + payload
if gitver and not payload.find('\n-- \n') > 0:
diff --git a/src/b4/command.py b/src/b4/command.py
index 1f8b8f1..37873c9 100644
--- a/src/b4/command.py
+++ b/src/b4/command.py
@@ -397,6 +397,10 @@ def setup_parser() -> argparse.ArgumentParser:
help='Resend a previously sent version of the series')
sp_send.add_argument('--no-sign', action='store_true', default=False,
help='Do not add the cryptographic attestation signature header')
+ sp_send.add_argument('--notes', dest='send_notes', action='store_true', default=None,
+ help='Include git notes in the patches below the --- line')
+ sp_send.add_argument('--no-notes', dest='send_notes', action='store_false',
+ help='Do not include git notes (overrides b4.send-notes config)')
sp_send.add_argument('--use-web-endpoint', dest='send_web', action='store_true', default=False,
help="Force going through the web endpoint")
ag_sendh = sp_send.add_argument_group('Web submission', 'Authenticate with the web submission endpoint')
diff --git a/src/b4/ez.py b/src/b4/ez.py
index 298e382..7e7bf5a 100644
--- a/src/b4/ez.py
+++ b/src/b4/ez.py
@@ -1567,7 +1567,7 @@ def rethread(patches: List[Tuple[str, EmailMessage]]) -> None:
def get_prep_branch_as_patches(movefrom: bool = True, thread: bool = True, addtracking: bool = True,
prefixes: Optional[List[str]] = None, usebranch: Optional[str] = None,
- expandprereqs: bool = True,
+ expandprereqs: bool = True, with_notes: bool = False,
) -> Tuple[List[Tuple[str, str]], List[Tuple[str, str]], str, List[Tuple[str, EmailMessage]]]:
cover, tracking = load_cover(strip_comments=True, usebranch=usebranch)
@@ -1604,7 +1604,8 @@ def get_prep_branch_as_patches(movefrom: bool = True, thread: bool = True, addtr
seriests=seriests,
mailfrom=mailfrom,
ignore_commits=ignore_commits,
- presubject=presubject)
+ presubject=presubject,
+ with_notes=with_notes)
base_commit, _, _, _, shortlog, diffstat = get_series_details(start_commit=start_commit,
usebranch=usebranch)
@@ -1767,7 +1768,8 @@ def get_prep_branch_as_patches(movefrom: bool = True, thread: bool = True, addtr
return alltos, allccs, tag_msg, patches
-def get_sent_tag_as_patches(tagname: str, revision: int, presubject: str = None) \
+def get_sent_tag_as_patches(tagname: str, revision: int, presubject: str = None,
+ with_notes: bool = False) \
-> Tuple[List[Tuple[str, str]], List[Tuple[str, str]], List[Tuple[str, EmailMessage]]]:
cover, base_commit, change_id = get_base_changeid_from_tag(tagname)
@@ -1784,7 +1786,8 @@ def get_sent_tag_as_patches(tagname: str, revision: int, presubject: str = None)
msgid_tpt=msgid_tpt,
seriests=seriests,
mailfrom=mailfrom,
- presubject=presubject)
+ presubject=presubject,
+ with_notes=with_notes)
alltos, allccs, cbody = get_cover_dests(cbody)
if len(patches) == 1:
@@ -1796,8 +1799,11 @@ def get_sent_tag_as_patches(tagname: str, revision: int, presubject: str = None)
def format_patch(output_dir: str) -> None:
+ config = b4.get_main_config()
+ with_notes = config.get('send-notes', '').lower() in {'yes', 'true', 'y'}
try:
- _, _, _, patches = get_prep_branch_as_patches(thread=False, movefrom=False, addtracking=False)
+ _, _, _, patches = get_prep_branch_as_patches(thread=False, movefrom=False, addtracking=False,
+ with_notes=with_notes)
except RuntimeError as ex:
logger.critical('CRITICAL: Failed to convert range to patches: %s', ex)
sys.exit(1)
@@ -1916,6 +1922,11 @@ def cmd_send(cmdargs: argparse.Namespace) -> None:
config = b4.get_main_config()
+ if cmdargs.send_notes is not None:
+ with_notes = cmdargs.send_notes
+ else:
+ with_notes = config.get('send-notes', '').lower() in {'yes', 'true', 'y'}
+
tag_msg = None
cl_msgid = None
_, tracking = load_cover(strip_comments=True)
@@ -1942,8 +1953,9 @@ def cmd_send(cmdargs: argparse.Namespace) -> None:
presubject = tracking['series'].get('presubject', None)
try:
- todests, ccdests, patches = get_sent_tag_as_patches(tagname, revision=revision,
- presubject=presubject)
+ todests, ccdests, patches = get_sent_tag_as_patches(tagname, revision=revision,
+ presubject=presubject,
+ with_notes=with_notes)
except RuntimeError as ex:
logger.critical('CRITICAL: Failed to convert tag to patches: %s', ex)
sys.exit(1)
@@ -1963,7 +1975,8 @@ def cmd_send(cmdargs: argparse.Namespace) -> None:
prefixes = None
try:
- todests, ccdests, tag_msg, patches = get_prep_branch_as_patches(prefixes=prefixes)
+ todests, ccdests, tag_msg, patches = get_prep_branch_as_patches(prefixes=prefixes,
+ with_notes=with_notes)
except RuntimeError as ex:
logger.critical('CRITICAL: Failed to convert range to patches: %s', ex)
sys.exit(1)
---
base-commit: 477734000555ffc24bf873952e40367deee26f17
change-id: 20260224-add-git-notes-1b1c3c5bda1f
Best regards,
--
Vishal Verma <vishal.l.verma@intel.com>
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH b4] b4: Add option to b4-send to include git-notes
2026-02-25 1:01 [PATCH b4] b4: Add option to b4-send to include git-notes Vishal Verma
@ 2026-02-25 2:54 ` Konstantin Ryabitsev
2026-02-25 3:46 ` Verma, Vishal L
0 siblings, 1 reply; 4+ messages in thread
From: Konstantin Ryabitsev @ 2026-02-25 2:54 UTC (permalink / raw)
To: Vishal Verma; +Cc: Kernel.org Tools
On Tue, Feb 24, 2026 at 06:01:49PM -0700, Vishal Verma wrote:
> Add an option (and a config entry) for b4-send to include any git-notes
> in the formatted patch after the '---' break.
This has come up multiple times, but unfortunately there is still no proper
support for git notes with git-filter-repo, so your notes will be lost
after a lot of very common b4 prep commands. See:
https://lore.kernel.org/tools/20250130-rich-orangutan-from-eldorado-04f621@lemur/
--
KR
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH b4] b4: Add option to b4-send to include git-notes
2026-02-25 2:54 ` Konstantin Ryabitsev
@ 2026-02-25 3:46 ` Verma, Vishal L
2026-02-25 4:07 ` konstantin
0 siblings, 1 reply; 4+ messages in thread
From: Verma, Vishal L @ 2026-02-25 3:46 UTC (permalink / raw)
To: konstantin@linuxfoundation.org; +Cc: tools@kernel.org
On Tue, 2026-02-24 at 21:54 -0500, Konstantin Ryabitsev wrote:
> On Tue, Feb 24, 2026 at 06:01:49PM -0700, Vishal Verma wrote:
> > Add an option (and a config entry) for b4-send to include any git-notes
> > in the formatted patch after the '---' break.
>
> This has come up multiple times, but unfortunately there is still no proper
> support for git notes with git-filter-repo, so your notes will be lost
> after a lot of very common b4 prep commands. See:
>
> https://lore.kernel.org/tools/20250130-rich-orangutan-from-eldorado-04f621@lemur/
Ah good point - I should've searched for it.
I see Yazen posted a follow-up[1] using a workaround from the
discussion filter-repo issue - I can see if you consider this whole
thing to be a bit clunky, but it would certainly be nice to have. Or is
there another preferable way to add these 'basement' notes to patches
while using a b4 prep/send workflow?
[1]: https://lore.kernel.org/tools/20250407-add-git-notes-v2-1-c0042e938e91@amd.com/
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH b4] b4: Add option to b4-send to include git-notes
2026-02-25 3:46 ` Verma, Vishal L
@ 2026-02-25 4:07 ` konstantin
0 siblings, 0 replies; 4+ messages in thread
From: konstantin @ 2026-02-25 4:07 UTC (permalink / raw)
To: Verma, Vishal L; +Cc: tools@kernel.org
On Wed, Feb 25, 2026 at 03:46:56AM +0000, Verma, Vishal L wrote:
> Ah good point - I should've searched for it.
>
> I see Yazen posted a follow-up[1] using a workaround from the
> discussion filter-repo issue - I can see if you consider this whole
> thing to be a bit clunky, but it would certainly be nice to have. Or is
> there another preferable way to add these 'basement' notes to patches
> while using a b4 prep/send workflow?
Yes, you can literally just amend/interactive rebase a patch and add a section
under ---. :)
--
KR
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-02-25 4:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-25 1:01 [PATCH b4] b4: Add option to b4-send to include git-notes Vishal Verma
2026-02-25 2:54 ` Konstantin Ryabitsev
2026-02-25 3:46 ` Verma, Vishal L
2026-02-25 4:07 ` konstantin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox