From: Christian Brauner <brauner@kernel.org>
To: "Kernel.org Tools" <tools@kernel.org>
Cc: Konstantin Ryabitsev <konstantin@linuxfoundation.org>,
"Christian Brauner (Amutable)" <brauner@kernel.org>
Subject: [PATCH RFC 07/11] review-tui: add a "Find older revisions" action
Date: Sat, 18 Jul 2026 00:37:43 +0200 [thread overview]
Message-ID: <20260718-work-b4-multiver-rows-v1-7-3c539d2a3095@kernel.org> (raw)
In-Reply-To: <20260718-work-b4-multiver-rows-v1-0-3c539d2a3095@kernel.org>
Offer discover_older_revisions() from the tracker's action menu,
available wherever manual revision linking is. The search runs in a
lore worker; on success the list reloads (deferring to the DB mtime
poll when a modal is up).
Assisted-by: LLM
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
src/b4/review_tui/_tracking_app.py | 55 ++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/src/b4/review_tui/_tracking_app.py b/src/b4/review_tui/_tracking_app.py
index 3057367..cc20ad6 100644
--- a/src/b4/review_tui/_tracking_app.py
+++ b/src/b4/review_tui/_tracking_app.py
@@ -90,6 +90,7 @@ _ACTION_SHORTCUTS: Dict[str, str] = {
'unsnooze': 'u',
'upgrade': 'U',
'link': 'l',
+ 'discover': 'o',
'thank': 't',
'abandon': 'A',
'archive': 'x',
@@ -891,6 +892,36 @@ class TrackingApp(LoreNodeShutdownMixin, CheckRunnerMixin, App[Optional[str]]):
elif event.state == WorkerState.ERROR:
self.notify('Could not fetch series', severity='error')
return
+ if event.worker.name == '_discover_older':
+ if event.state == WorkerState.SUCCESS:
+ result = event.worker.result or {}
+ error = result.get('error')
+ found = result.get('found', 0)
+ if error:
+ self.notify(
+ f'Older-revision search failed: {error}', severity='error'
+ )
+ elif found:
+ revs = result.get('revisions') or []
+ if revs:
+ rlist = ', '.join(f'v{r}' for r in revs)
+ self.notify(f'Found and added: {rlist}')
+ else:
+ self.notify(f'Found {found} older revision(s)')
+ # Reload so the new revisions show up right away; if a
+ # modal is up, the DB mtime poll picks it up instead.
+ if len(self.app.screen_stack) == 1:
+ if self._selected_series:
+ self._focus_change_id = self._selected_series.get(
+ 'change_id'
+ )
+ self._invalidate_caches()
+ self._load_series()
+ else:
+ self.notify('No older revisions found')
+ elif event.state == WorkerState.ERROR:
+ self.notify('Older-revision search failed', severity='error')
+ return
if event.worker.name != '_startup_rescan':
return
if event.state == WorkerState.SUCCESS:
@@ -1338,6 +1369,7 @@ class TrackingApp(LoreNodeShutdownMixin, CheckRunnerMixin, App[Optional[str]]):
actions.append(('upgrade', 'Upgrade to newer revision'))
if status == 'new':
actions.append(('link', 'Manually link a revision'))
+ actions.append(('discover', 'Find older revisions'))
actions.append(('abandon', 'Abandon series'))
if status == 'new':
actions.append(('waiting', 'Mark as waiting on new revision'))
@@ -1365,6 +1397,7 @@ class TrackingApp(LoreNodeShutdownMixin, CheckRunnerMixin, App[Optional[str]]):
actions.append(('thank', 'Send thank-you'))
if status in ('reviewing', 'replied', 'partial', 'waiting'):
actions.append(('link', 'Manually link a revision'))
+ actions.append(('discover', 'Find older revisions'))
# 'Return to reviewing' sits just above the abandon/archive block
# rather than at the top of the menu.
if status in ('accepted', 'partial', 'thanked'):
@@ -1389,6 +1422,7 @@ class TrackingApp(LoreNodeShutdownMixin, CheckRunnerMixin, App[Optional[str]]):
'thank': self.action_thank,
'upgrade': self.action_update_revision,
'link': self.action_link_revision,
+ 'discover': self.action_discover_older,
'archive': self.action_archive,
'waiting': self.action_waiting,
'snooze': self.action_snooze,
@@ -3882,6 +3916,27 @@ class TrackingApp(LoreNodeShutdownMixin, CheckRunnerMixin, App[Optional[str]]):
),
)
+ def action_discover_older(self) -> None:
+ """Search lore for older revisions of the selected series."""
+ if not self._selected_series or not self._identifier:
+ return
+ series = dict(self._selected_series)
+ config = b4.get_main_config()
+ linkmask = str(config.get('linkmask', ''))
+ topdir = b4.git_get_toplevel()
+ identifier = self._identifier
+ self.notify('Searching lore for older revisions…')
+
+ def _discover() -> Dict[str, Any]:
+ # The search machinery logs to the console; keep it from
+ # scribbling over the TUI.
+ with _quiet_worker():
+ return b4.review.tracking.discover_older_revisions(
+ identifier, series, linkmask, topdir=topdir
+ )
+
+ run_lore_worker(self, _discover, name='_discover_older')
+
def action_link_revision(self) -> None:
"""Manually link another revision to the selected series by msgid.
--
2.53.0
next prev parent reply other threads:[~2026-07-17 22:38 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-17 22:37 [PATCH RFC 00/11] review: track and browse every version of a tracked series Christian Brauner
2026-07-17 22:37 ` [PATCH RFC 01/11] review-tui: fix rethreaded series thread viewing Christian Brauner
2026-07-17 22:37 ` [PATCH RFC 02/11] review: track message counts for all revisions of a series Christian Brauner
2026-07-17 22:37 ` [PATCH RFC 03/11] review: test per-revision message tracking Christian Brauner
2026-07-17 22:37 ` [PATCH RFC 04/11] review-tui: poll every revision on u/U updates Christian Brauner
2026-07-17 22:37 ` [PATCH RFC 05/11] review-tui: guarantee the tracked revision in revision lists Christian Brauner
2026-07-17 22:37 ` [PATCH RFC 06/11] review: add backward discovery of older series revisions Christian Brauner
2026-07-17 22:37 ` Christian Brauner [this message]
2026-07-17 22:37 ` [PATCH RFC 08/11] review: test backward revision discovery Christian Brauner
2026-07-17 22:37 ` [PATCH RFC 09/11] review-tui: extract the Msgs column renderer from TrackedSeriesItem Christian Brauner
2026-07-17 22:37 ` [PATCH RFC 10/11] review-tui: expand tracked series into per-version rows Christian Brauner
2026-07-17 22:37 ` [PATCH RFC 11/11] review-tui: test per-version tracker rows Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260718-work-b4-multiver-rows-v1-7-3c539d2a3095@kernel.org \
--to=brauner@kernel.org \
--cc=konstantin@linuxfoundation.org \
--cc=tools@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox