bugs: bug tracking with git-bug (alpha)
Warning
b4 bugs is a technology preview (alpha). Commands, keybindings,
and features may change in incompatible ways between releases. Bug
reports and feedback are welcome at tools@kernel.org.
The b4 bugs command provides a TUI and CLI for tracking bug reports
alongside your git repository using git-bug. Bugs are stored as git
objects inside the repo, so they travel with the code and can be shared
via git push/git pull without any external service.
Prerequisites
Bug tracking is an optional feature, so install b4 with the bugs
extra to pull in the ezgb library that drives git-bug:
pipx install b4[bugs]
Then install git-bug v0.10.1 or later. It is a Go binary rather than a
Python package, so it cannot come from PyPI and has to be installed
separately (most distributions package it). b4 will automatically create and
adopt a git-bug identity the first time you run b4 bugs in a
repository, using your user.name and user.email from git config.
TUI overview
Launch with:
b4 bugs tui
The TUI shows a list of all tracked bugs with their submitter, comment count, lifecycle status, and subject. A detail panel at the bottom shows metadata for the highlighted bug.
Bug list keybindings
|
Move cursor up/down |
|
Open bug detail view |
|
New bug (import from lore or create manually) |
|
Edit labels on the selected bug |
|
Triage action (confirm, need info, close, duplicate, etc.) |
|
Update selected bug from lore (fetch new messages) |
|
Update all bugs from lore |
|
Pull bugs from remote |
|
Push bugs to remote |
|
Limit (filter) the bug list |
|
Toggle showing closed bugs |
|
Quit (bare |
Bug detail keybindings
|
Scroll right pane / move between comments (when left pane focused) |
|
Previous/next comment |
|
Reply to selected comment via email |
|
Add an internal comment (not emailed) |
|
Edit the bug title |
|
Remove (tombstone) the selected comment |
|
Page down/up |
|
Return to bug list |
Creating bugs
Press N in the bug list to create a new bug. You can choose between:
- Import from lore
Enter a Message-ID from a lore.kernel.org thread. b4 fetches the full thread, uses the oldest message as the bug title and body, and adds follow-up messages as comments. Importing the same thread twice is detected and prevented.
- Create manually
Opens your editor with a template. The first line becomes the bug title; the rest becomes the description.
Lifecycle states
Bugs move through lifecycle states tracked via lifecycle: labels:
★ |
|
Newly reported, needs triage |
¤ |
|
Triaged and accepted |
‽ |
|
Waiting for more information |
ø |
|
Cannot reproduce (closes the bug) |
≠ |
|
Will not be fixed (closes the bug) |
✓ |
|
Fixed (closes the bug) |
≡ |
|
Duplicate of another bug (closes the bug) |
CLI commands
For scripting and non-interactive use:
b4 bugs import <message-id> Import a lore thread as a new bug
b4 bugs import --no-parent <message-id>
Import only the sub-thread
b4 bugs list List all bugs
b4 bugs list --status open List only open bugs
b4 bugs list --label <label> Filter by label
b4 bugs list -j Same, as JSON (see below)
b4 bugs refresh [bug-id] Fetch new messages from lore
b4 bugs delete <bug-id> Permanently delete a bug
Machine-readable listings
b4 bugs list normally prints a short human-readable line per bug.
Add -j (--json) and it prints an array of objects on stdout
instead, one per bug:
id The full bug id (the short form is just its prefix)
title The bug title
status Either "open" or "closed"
labels The bug's labels, sorted
root_msgid Message-ID of the thread the bug was imported from
comment_msgids Message-IDs of every later message captured as a comment
last_activity ISO 8601 timestamp of the most recent activity
The two message-id fields are what make the listing useful to a tool
that searches the archives for new reports. root_msgid is the same
dedup key b4 bugs import checks against, so a candidate whose
message-id appears there is a bug you already filed. comment_msgids
covers the rest of the thread, so a follow-up that was already pulled in
by b4 bugs refresh does not come back as a fresh report either.
Both are bare message-ids, without the angle brackets.
root_msgid is null for a bug that was filed by hand rather than
imported from a thread. Tombstoned comments keep their Message-ID, so
they still appear in comment_msgids – the message was captured, even
though its content has since been removed.
To build an exclusion set for every bug you are already tracking:
b4 bugs list -j \
| jq -r '.root_msgid, .comment_msgids[] | select(. != null)' \
| sort -u > known-bugs.txt
Running unattended
b4 bugs needs two things before it can do anything: a git repository
to store the bugs in, and an adopted git-bug identity to attribute
changes to. If no identity exists it normally offers to create one from
your user.name and user.email – which means a prompt, and a
prompt means a hang when nothing is there to answer it.
Pass the global -n (--no-interactive) flag and no prompt is ever
issued; the command fails instead. Being a global flag, it goes before
the subcommand:
b4 -n bugs list -j # correct
b4 bugs list -n -j # error: unrecognized arguments: -n
Combined with -j the failure is reported as a JSON object on stdout
rather than as log lines, so a caller always has something to parse:
{
"error": "no-identity",
"message": "No usable git-bug identity"
}
The error slug is stable and is one of no-repo (not in a git
repository), no-identity (no git-bug identity could be adopted), or
no-git-bug (the optional [bugs] extra or the git-bug binary
is not installed). The exit code is 1 in every case.
b4 review list reports its own precondition failures the same way, so
a caller driving both commands only has to know one error shape; see
Building an exclusion set.
Comment removal
Press
Xon a comment to tombstone it. The comment body is replaced with a minimal header preserving the Message-ID (so thread refresh does not re-import it), but all personal data is removed. This supports data removal requests for content visible via cgit or other public interfaces.