Skip to content

CLI Tools en

Won-Kyu Park edited this page Aug 28, 2026 · 2 revisions

CLI Tools

The command-line scripts live under tools/. Run any of them from the repo root with uv run tools/<name>.py. Handy when you want to poke at the library from a terminal instead of writing Python.

srcs_commit.py — commit a file

uv run tools/srcs_commit.py my_doc.txt -m "initial commit"
  • content_file (required) — the source file to commit
  • rcs_file (optional) — path to the .srcs file. If omitted, it's placed at .srcs/<filename>.srcs automatically
  • -m/--message (required) — commit log message
  • -a/--author — defaults to $USER
  • --no-sign — skip GPG signing
  • --binary — force a binary commit even if the content is decodable as text
  • --encoding — how binary payloads are stored: base64 (default), raw or base85. raw is the RCS approach — keep the bytes and let the block's escaping carry them — costing ~0.4% against base64's 33%, and decoding faster. base85 uses git's alphabet. Only base64 streams stay byte-identical to earlier releases; raw and base85 blocks cannot be read by simple-rcs 0.2.0
  • --srcs-dir — directory to use for auto-placement (default .srcs)

The file is read as bytes first, then committed as text if there's no NUL byte in the first 8KB and it decodes as UTF-8 (the same heuristic git uses to distinguish text from binary). That decision happens in this script, not the library — SimpleRCS.commit() itself takes any bytes straight down the binary path, no auto-detection.

srcs_log.py — view history

uv run tools/srcs_log.py my_doc.txt.srcs
uv run tools/srcs_log.py my_doc.txt.srcs -n 5 --reverse --show-signature
  • -n/--limit — show only the most recent N commits
  • -r/--reverse — oldest first
  • --show-signature — also verify GPG signatures

srcs_diff.py — diff between versions

uv run tools/srcs_diff.py my_doc.txt -r 1.1:1.3
uv run tools/srcs_diff.py my_doc.txt --engine ses
  • content_file (required) — the tracked file, not the .srcs file. It looks for <name>.srcs in the current directory, then .srcs/<name>.srcs. Pass the .srcs path as the second positional argument to be explicit. (srcs_log/srcs_verify/srcs_sign_head take the .srcs path instead, and srcs_blame accepts either — the tools are not consistent about this)
  • -r/--revision'1.1' (compare against HEAD) or '1.1:1.2' (compare two specific versions)
  • --enginedifflib (default) / pydifflib / myers / ses / dmp. The ses/dmp engines only work if the Cython extensions have been built
  • --binary — for a pair of binary revisions, emit a patch git apply can read instead of Binary files ... differ (simple_rcs/gitpatch.py). It is a literal block, so it carries the whole target file rather than the change: our BSDIFF deltas are not compatible with git's pack-delta.
uv run tools/srcs_diff.py logo.png -r 1.0:1.1 --binary > p.diff
git apply p.diff      # git apply -R p.diff to undo

This is the tool for actually eyeballing the difference between the diff algorithms discussed in Diff Engines.

srcs_blame.py — per-line authorship

uv run tools/srcs_blame.py my_doc.txt
uv run tools/srcs_blame.py my_doc.txt --depth 10
  • content_file — the source file (or you can point it directly at a .srcs file)
  • rcs_file (optional) — explicit .srcs path
  • --srcs-dir — auto-discovery directory (default .srcs)
  • --depth — only walk back this many versions; anything older gets attributed to the oldest version reached

Doesn't work if HEAD is binary — there's no such thing as a "line" there.

srcs_verify.py — integrity check

uv run tools/srcs_verify.py my_doc.txt.srcs

Verifies the entire hash chain and any GPG signatures. On failure, exits with code 1 and prints ❌ VERIFICATION FAILED.

srcs_sign_head.py — sign HEAD

uv run tools/srcs_sign_head.py my_doc.txt.srcs -s <GPG_KEY_ID>
  • -s/--signer — GPG key ID of the signer. Pass it multiple times for multiple signatures
  • Falls back to the SRCS_SIGNING_KEY environment variable if not specified
  • Doesn't work on v1 files — signing is v2-only

bench_diff.py — diff engine benchmark

uv run tools/bench_diff.py
uv run tools/bench_diff.py --size 500 --diff-ratio 0.1 --runs 5
  • --size (KB) — size of the synthetic test data
  • --diff-ratio — fraction of content that differs between the two inputs
  • --file-a/--file-b — use real files instead of synthetic data
  • --runs — number of repetitions (for averaging/min)
  • --skip — exclude specific engines

Reports both timing and peak memory (tracemalloc). Compares pure-Python Myers, Cython SES/DMP, StreamSequenceMatcher, StreamTextSequenceMatcher, and standard difflib all at once.

compare_memory_usage.py

A standalone memory-comparison utility. Since bench_diff.py already measures memory too, there's not much reason to reach for this one separately anymore.

Clone this wiki locally