Repository metrics
- Stars
- (48,085 stars)
- PR merge metrics
- (Avg merge 11d 1h) (45 merged PRs in 30d)
Description
Summary
Add rtk p4 to filter and compress Perforce CLI output — currently the entire p4 command family runs unfiltered, and on large depots the output is huge.
Searched existing issues (perforce, p4) — no prior coverage. Apologies if I missed one.
Motivation
rtk discover on my workstation over the past 30 days (23 Claude Code sessions, 1,914 Bash invocations) shows the Perforce CLI as the single largest uncovered category — 8 of the top 15 unhandled commands are
p4 subcommands:
| Command | Count | Example |
|---|---|---|
p4 |
33 | p4 -p <host>:1666 describe -s <CL> |
p4 files |
29 | P4PORT=<host>:1666 p4 files //depot/path/...@=<CL> |
p4 change |
24 | P4PORT=<host>:1666 P4USER=<user> p4 change -o <CL> |
p4 describe |
20 | p4 describe -s <CL> |
p4 grep |
19 | P4PORT=<host>:1666 p4 grep -e 'pattern' //depot/... |
p4 changes |
15 | P4PORT=<host>:1666 p4 changes -m 20 //depot/path/... |
p4 shelve |
13 | P4PORT=<host>:1666 P4USER=<user> p4 shelve -i |
p4 opened |
11 | P4PORT=<host>:1666 P4USER=<user> p4 opened |
p4 print |
10 | P4PORT=<host>:1666 p4 print -q //depot/file#head |
p4 dirs |
10 | P4PORT=<host>:1666 p4 dirs //depot/* |
| Total p4 | 184 |
Caveat per #538: some of these may have routed through native tools, but p4 has no Claude Code native equivalent — it's pretty much always Bash. So 184/month is a floor, not an estimate.
Typical use cases — working in a large Perforce-managed source tree:
p4 describe -s <CL>→ changelist summary; on large CLs the file list runs into hundreds of linesp4 changes -m 20 //depot/path/...→ recent history; verbose default format with full descriptionsp4 files //depot/...@=<CL>→ file enumeration; can be thousands of lines on large refactorsp4 grep -e 'pattern' //depot/path/...→ already huge on big trees, often gets truncated mid-resultp4 opened/p4 shelve -i/p4 change -o→ form output with verbose comment headers that dominate the useful content
All produce output that floods context.
Proposed behavior
Subcommand-aware filtering, mirroring the pattern used by rtk git / rtk gh:
p4 describe— strip the form header comment block; for-s(summary) keep affected-files list with head/tail truncation past N entries; for full diff treat the diff body likertk diff.p4 changes— one line per CL:<CL> <date> <user> <first-line-of-desc>. Drop the blank lines and indented description bodies unless-l/-Lis explicitly requested.p4 files/p4 dirs/p4 opened— line-based head/tail with ellipsis past N (default ~50, configurable), same shape asrtk ls.p4 grep— group by file, strip whitespace, truncate per-file matches — same strategy asrtk grep.p4 print— treat as file read: delegate tortk readsemantics (head/tail with line count).p4 change -o/p4 shelve -o— strip the boilerplate Perforce form comments (the# A Perforce Change Specification.block etc.), keep only the editable fields.- Form input commands (
p4 change -i,p4 shelve -i) — pass through untouched (these are stdin-driven, no useful filtering). - Unknown / non-listed subcommands — transparent passthrough with usage tracking, like the existing fallback.
- Respect
-G(marshalled python) and-Mj/-ztag(tagged) output — these are machine-readable; either pass through verbatim or apply JSON-aware compression for-Mj.
Env-prefix invocations (P4PORT=... P4USER=... p4 ...) are extremely common — the rtk hook would need to recognize and rewrite these the same way it handles GH_HOST=... gh ... today.
Based on compression ratios I see for rtk grep and rtk read on similar tree-sized output, I'd expect 60–80% savings on the search/list subcommands and 40–60% on describe/change -o/shelve -o.
At ~184 invocations/month for me alone, that's a meaningful chunk — and I'd guess any team working in a Perforce-managed game/engine codebase has similar volume.