Re: b4 review available in master

Conor Dooley
2026-02-28T16:36:10Z

[-- Attachment #1: Type: text/plain, Size: 28691 bytes --]

On Fri, Feb 27, 2026 at 02:53:07PM -0500, Konstantin Ryabitsev wrote:
> Hi, all:
>
> TLDR: "b4 review" is a terminal UI that hopes to streamline a lot of
> maintainer duties. A getting-started guide with screencasts is here:
> https://b4.docs.kernel.org/en/latest/reviewer/getting-started.html
>
> It's available from b4 master pending initial testing and will be generally
> available in b4-0.15.
>
> Longread:
>
> I've been working on "b4 review" for a while, with a few false-starts, a lot
> of despair, and then a whole new direction that seemed to have finally worked.
> So, the usual. :)
>
> I am finally feeling confident enough to release the code as initial
> technology preview, with the primary goal to get some direct feedback. The
> goal of the UI was to work alongside your usual email client, allowing you to
> use it for as much or as little as you like.
>
> The feature only exists in b4 master branch, so if you want to try it, you'll
> need to be comfortable running b4 from checkout. It also requires having a
> valid email server configured with git for sending outgoing mail. If you're
> already using "b4 ty" then you're good to go.
>
> The only new dependency introduced is python-textual. I say this with a bit of
> tongue-in-cheek, because textual pulls in a ton of other dependencies, but
> it's usually already installed on many modern distros anyway.
>
> You can do the following things:
>
> - Track incoming patch series from lore using a message-id, URL, change-id,
> or by piping a message from your mail client (e.g. via mutt integration)
> - TUI-based tracking list with series lifecycle management (new, reviewing,
> replied, taken, thanked, archived, waiting)
> - Split-pane review interface with patch list and syntax-highlighted diff view
> - Quick trailer addition (Reviewed-by, Acked-by, Tested-by) with a single
> keypress
> - Inline diff commenting via $EDITOR — comments are automatically formatted
> as proper quoted-reply emails for the mailing list
> - Preview emails to inspect exactly what will be sent before sending
> - Fetch and display follow-up messages from other reviewers directly in the
> diff view
> - Range-diff between series revisions without leaving the TUI
> - Automatic discovery of older and newer revisions when tracking a series
> - Revision upgrade that preserves your review comments on unchanged patches
> - Three merge strategies for applying series: merge commit, linear (git-am),
> and cherry-pick
> - Thank-you note generation listing each applied commit with its hash (and
> more reliably than b4 ty, since we keep track of applied series instead of
> guessing)
> - AI-assisted review using an external agent (Claude Code, Gemini CLI,
> OpenAI Codex CLI, GitHub Copilot CLI) — agent findings are private to the
> maintainer and can then be selectively incorporated into the review

> - Patchwork integration: browse series, view CI check results, track series
> directly from Patchwork, and automatically synchronise Patchwork state as
> you work

This patchwork part is neat, this is definitely something that I'll play
with. Patchwork is great, but I really dislike all the jumping back and
forth between editor/website/mailer. One thing that immediately seemed like
it'd be neat is a shortcut from the patchwork pane that does track + review.

Worktree support is something I didn't expect to exist, but it does that
that's real helpful ;)

Also, I attempted to open patchwork while my b4.pw-project was set to
"devicetree" and got an error:
MarkupError: Expected markup style value (found '1/1] dt-bindings: net: can: nxp,sja1000: add reference to fsl,imx-weim-peripherals.yaml').
There's some massive splat I can send you if this does not reproduce.

I wanted to look into whether or not I could quickly reply to stuff from
the tui (since like 80% of binding patches don't require a checkout) and
encountered this smaller reproduction of the same thing.

$ /stuff/b4/b4.sh review track -i linux-dt D8CE6E5B1001D797+a6f36da0272ac18fff2a992976b1defc3bb01af6.1772289741.git.lv.zheng@linux.spacemit.com
< snip >
$ /stuff/b4/b4.sh review tui -i linux-dt
Retrieving series: 52E07C3A9B398459+126b1f464ae2a8bfcca6f504c64346541ae4db6f.1772289741.git.lv.zheng@linux.spacemit.com
Looking up https://lore.kernel.org/all/52E07C3A9B398459%2B126b1f464ae2a8bfcca6f504c64346541ae4db6f.1772289741.git.lv.zheng@linux.spacemit.com/
Grabbing thread from lore.kernel.org/all/52E07C3A9B398459%2B126b1f464ae2a8bfcca6f504c64346541ae4db6f.1772289741.git.lv.zheng@linux.spacemit.com/t.mbox.gz
Checking attestation on all messages, may take a moment...
---
✓ [PATCH v5 1/8] iommu/riscv: Enable IOMMU DMA mapping support
✓ [PATCH v5 2/8] iommu/riscv: Add auxiliary bus framework and HPM device support
✓ [PATCH v5 3/8] iommu/riscv: Add HPM support for performance monitoring
✓ [PATCH v5 4/8] dt-bindings: iommu: Add spacemit/t100 features
✓ [PATCH v5 5/8] spacemit/t100: Add global filter awareness for RISC-V IOMMU HPM
✓ [PATCH v5 6/8] iommu/riscv: Add SpacemiT T100 IOATC HPM support
✓ [PATCH v5 7/8] iommu/riscv: Add vendor event support for RISC-V IOMMU HPM
✓ [PATCH v5 8/8] perf vendor events riscv: Add SpacemiT T100 HPM event aliases
---
✓ Signed: DKIM/linux.spacemit.com
Guessing base commit...
Base: tags/next-20260227 (best guess, 9/11 blobs matched)
Base: tags/next-20260227
Magic: Preparing a sparse worktree
---
Applying: iommu/riscv: Enable IOMMU DMA mapping support
Applying: iommu/riscv: Add auxiliary bus framework and HPM device support
Applying: iommu/riscv: Add HPM support for performance monitoring
Applying: dt-bindings: iommu: Add spacemit/t100 features
Applying: spacemit/t100: Add global filter awareness for RISC-V IOMMU HPM
Applying: iommu/riscv: Add SpacemiT T100 IOATC HPM support
Applying: iommu/riscv: Add vendor event support for RISC-V IOMMU HPM
Applying: perf vendor events riscv: Add SpacemiT T100 HPM event aliases
---
Fetching into FETCH_HEAD
Review branch b4/review/20260228-iommu-riscv-enable-iommu-dma-mapping-support-feee43387d2a created successfully
Review branch created: b4/review/20260228-iommu-riscv-enable-iommu-dma-mapping-support-feee43387d2a
Checking out branch and starting review UI...
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ /stuff/b4/src/b4/review_tui/_review_app.py:219 in on_mount │
│ │
│ 216 │ ╭─────────────────────────────────────────── locals ────────────────────────────────────────────╮ │
│ 217 │ def on_mount(self) -> None: │ self = ReviewApp(title='b4 review', classes={'-dark-mode'}, pseudo_classes={'focus', 'dark'}) │ │
│ 218 │ │ self._refresh_newer_warning() ╰───────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ ❱ 219 │ │ self._refresh_title_bar() │
│ 220 │ │ self._populate_patch_list() │
│ 221 │ │ self._show_content(self._selected_idx) │
│ 222 │
│ │
│ /stuff/b4/src/b4/review_tui/_review_app.py:235 in _refresh_title_bar │
│ │
│ 232 │ │ else: ╭───────────────────────────────────────────── locals ─────────────────────────────────────────────╮ │
│ 233 │ │ │ label = f' \u270e {subject}' │ bar = Static(id='title-bar') │ │
│ 234 │ │ │ bar.styles.background = self.get_css_variables()['primary-darken-2'] │ label = ' ✎ [PATCH v5 1/8] iommu/riscv: Enable IOMMU DMA mapping support' │ │
│ ❱ 235 │ │ bar.update(label) │ self = ReviewApp(title='b4 review', classes={'-dark-mode'}, pseudo_classes={'focus', 'dark'}) │ │
│ 236 │ │ subject = '[PATCH v5 1/8] iommu/riscv: Enable IOMMU DMA mapping support' │ │
│ 237 │ def _refresh_newer_warning(self) -> None: ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ 238 │ │ """Show or hide the newer-version warning bar based on tracking data.""" │
│ │
│ /usr/lib/python3/dist-packages/textual/widgets/_static.py:106 in update │
│ │
│ 103 │ │ """ ╭────────────────────────────────── locals ───────────────────────────────────╮ │
│ 104 │ │ │ content = ' ✎ [PATCH v5 1/8] iommu/riscv: Enable IOMMU DMA mapping support' │ │
│ 105 │ │ self._content = content │ self = Static(id='title-bar') │ │
│ ❱ 106 │ │ self._visual = visualize(self, content, markup=self._render_markup) ╰─────────────────────────────────────────────────────────────────────────────╯ │
│ 107 │ │ self.refresh(layout=True) │
│ 108 │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
MarkupError: Expected markup style value (found '1/8] iommu/riscv: Enable IOMMU DMA mapping support').

NOTE: 1 of 2 errors shown. Run with textual run --dev to see all errors.
Checking out branch and starting review UI...
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ /stuff/b4/src/b4/review_tui/_review_app.py:219 in on_mount │
│ │
│ 216 │ ╭─────────────────────────────────────────── locals ────────────────────────────────────────────╮ │
│ 217 │ def on_mount(self) -> None: │ self = ReviewApp(title='b4 review', classes={'-dark-mode'}, pseudo_classes={'focus', 'dark'}) │ │
│ 218 │ │ self._refresh_newer_warning() ╰───────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ ❱ 219 │ │ self._refresh_title_bar() │
│ 220 │ │ self._populate_patch_list() │
│ 221 │ │ self._show_content(self._selected_idx) │
│ 222 │
│ │
│ /stuff/b4/src/b4/review_tui/_review_app.py:235 in _refresh_title_bar │
│ │
│ 232 │ │ else: ╭───────────────────────────────────────────── locals ─────────────────────────────────────────────╮ │
│ 233 │ │ │ label = f' \u270e {subject}' │ bar = Static(id='title-bar') │ │
│ 234 │ │ │ bar.styles.background = self.get_css_variables()['primary-darken-2'] │ label = ' ✎ [PATCH v5 1/8] iommu/riscv: Enable IOMMU DMA mapping support' │ │
│ ❱ 235 │ │ bar.update(label) │ self = ReviewApp(title='b4 review', classes={'-dark-mode'}, pseudo_classes={'focus', 'dark'}) │ │
│ 236 │ │ subject = '[PATCH v5 1/8] iommu/riscv: Enable IOMMU DMA mapping support' │ │
│ 237 │ def _refresh_newer_warning(self) -> None: ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ 238 │ │ """Show or hide the newer-version warning bar based on tracking data.""" │
│ │
│ /usr/lib/python3/dist-packages/textual/widgets/_static.py:106 in update │
│ │
│ 103 │ │ """ ╭────────────────────────────────── locals ───────────────────────────────────╮ │
│ 104 │ │ │ content = ' ✎ [PATCH v5 1/8] iommu/riscv: Enable IOMMU DMA mapping support' │ │
│ 105 │ │ self._content = content │ self = Static(id='title-bar') │ │
│ ❱ 106 │ │ self._visual = visualize(self, content, markup=self._render_markup) ╰─────────────────────────────────────────────────────────────────────────────╯ │
│ 107 │ │ self.refresh(layout=True) │
│ 108 │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
MarkupError: Expected markup style value (found '1/8] iommu/riscv: Enable IOMMU DMA mapping support').

NOTE: 1 of 2 errors shown. Run with textual run --dev to see all errors

This seems promising though, could definitely see this making my life
easier, with less hoping between patchwork/mutt/git repo.

Cheers,
Conor.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]