WYRD/TOOLS

Tools / gitpr / Usage

Usage

Review flow

Create a PR for the current worktree branch, review its live basis, and use the exact reported pair for a verdict:

gitpr create --title "Improve validation"
gitpr list
gitpr review <pr-id>
gitpr comment <pr-id> --file internal/example.go --line-start 20 \
  --text "Handle the empty value here."
gitpr approve <pr-id> --basis <source-head>:<base-head>
gitpr merge <pr-id>

--description passes its value through the invoking shell, so backticks, $(), and mixed quoting in a multiline body can be consumed or mangled by the shell before gitpr sees them. Use --description-file <path> (or - for standard input) instead; it is read verbatim, byte-for-byte, with no shell interpretation or trimming, and is mutually exclusive with --description:

gitpr create --title "Improve validation" --description-file description.txt

To correct title or description on an open PR without creating a second record — for example after a shell-mangled description — use gitpr edit. It refuses closed or merged PRs without writing, and never changes anything but the fields given:

gitpr edit <pr-id> --description-file description.txt

Approve records an accepted event and does not merge. Merge reads the latest event and refuses rejected verdicts, head drift, deleted source branches, divergent histories, and equal source/base heads. Reject records a rejected event for the reviewed pair:

gitpr reject <pr-id> --basis <source-head>:<base-head>

Comments can be anchored, PR-level, or replies:

gitpr comment <pr-id> --pr-level --text "Ready for another review."
gitpr comment <pr-id> --thread <thread-id> --text "Addressed."
gitpr resolve <pr-id> <thread-id>
gitpr reopen <pr-id> <thread-id>

Comments are allowed while a PR is open, merged, or closed. A post-closure comment is marked in the record.

End work without merging through gitpr:

gitpr close <pr-id> --reason abandoned
gitpr close <pr-id> --reason superseded --superseded-by <replacement-id>
gitpr close <pr-id> --reason integrated --destination main \
  --commit <landed-commit-sha>

Records remain retained after merge or closure. gitpr delete <id> previews the destructive operation; --force performs it and may make pinned commits collectable.

The CLI accepts a full ULID or a unique prefix. show and comments open a picker without an ID. The TUI lists records and provides a read-only detail view; actions use the CLI review and basis flow.

Legacy records

A record without a schema field is a legacy snapshot from the prior model. gitpr does not read, list, mutate, merge, export, or delete one: every command that takes its ID refuses and carries the commands below, and gitpr list skips it with a count.

There is no migration. Recreate in-flight work with gitpr create and remove the old record by hand. A legacy record is self-describing YAML behind plain Git refs, so no tool is needed to retrieve it.

List the legacy records in a repository:

for ref in $(git for-each-ref --format='%(refname)' 'refs/gitpr/pr/*/meta'); do
  git show "$ref:pr.yaml" | grep -q '^schema:' || echo "$ref"
done

Read one, read its history, and export it before removal:

git show refs/gitpr/pr/<id>/meta:pr.yaml
git log --patch refs/gitpr/pr/<id>/meta
git show refs/gitpr/pr/<id>/meta:pr.yaml > <id>.pr.yaml

Remove every ref belonging to one record. The first pattern is a prefix, not a glob, so it also reaches nested event and anchor pins:

git for-each-ref --format='%(refname)' \
  refs/gitpr/pr/<id> 'refs/gitpr/index/*/<id>' |
  while read -r ref; do git update-ref -d "$ref"; done

Removal is irreversible, and the commits the record pinned become collectable by Git.