What I'd like
Two halves of one round trip for the reviewed marks (Space):
--reviewed-output <file> — on exit, write the paths marked reviewed, one relative path per line.
--reviewed <file> — on start, mark those paths as reviewed up front.
revdiff already ships exactly this pair for the other half of a review's state: -o writes annotations, --annotations preloads them. Reviewed marks have no such pair, so they die with the process.
Why
A large review is not one sitting. I mark 27 of 85 files reviewed, quit, come back the next morning — everything is unreviewed again and F (unreviewed only) has nothing to filter on. Nothing else preserves it either: review history saves annotations plus diffs, and only when annotations exist, so a session that produced marks and no annotations leaves no trace at all.
With the pair above the second pass is what it should be: preload what I already finished, press F, and look only at what is left.
Why not --include / --only
I can already compute the remaining set outside revdiff and pass it in — but those flags drop every other file from the review. When the file I am reading refers to one I already checked, I cannot glance at it, and I cannot change my mind and un-finish a file mid-session.
A preloaded reviewed mark is different in exactly the way that matters: every file stays present and openable, the finished ones simply stop competing for attention, and Space still un-marks one when it turns out to deserve a second look. "Out of the way but reachable" is the state --only cannot express.
It also closes the loop with GitHub
GitHub tracks the same per-reviewer concept and it is scriptable: markFileAsViewed / unmarkFileAsViewed mutations, and PullRequestChangedFile.viewerViewedState reads back VIEWED / UNVIEWED / DISMISSED (the last meaning the file changed since it was viewed). So the export feeds the PR directly:
revdiff --reviewed-output reviewed.txt "$base"
xargs -I{} gh api graphql \
-f query='mutation($pr:ID!,$p:String!){markFileAsViewed(input:{pullRequestId:$pr,path:$p}){clientMutationId}}' \
-F pr="$PR_ID" -F p={} < reviewed.txt
and the query feeds the preload back on the next round. Today I read the files in revdiff and then re-click each one in the GitHub web UI by hand.
Shape
Probably not on the annotation stream: the record format is ## path[:line[-line]] (…), and the README already documents defending that parser against ## collisions in comment bodies, so a second record kind there would break existing consumers. A separate sink avoids the question — a plain path-per-line file, or a field in a structured (JSON) output mode if one is planned anyway.
Nothing new needs tracking: the model already holds the set, and R already owns the rule for when a mark survives a reload. This is persisting state that exists.
Environment
revdiff v1.12.0-ad8c796-20260804T171719 (homebrew, umputun/apps/revdiff), macOS 15.6.
What I'd like
Two halves of one round trip for the reviewed marks (
Space):--reviewed-output <file>— on exit, write the paths marked reviewed, one relative path per line.--reviewed <file>— on start, mark those paths as reviewed up front.revdiff already ships exactly this pair for the other half of a review's state:
-owrites annotations,--annotationspreloads them. Reviewed marks have no such pair, so they die with the process.Why
A large review is not one sitting. I mark 27 of 85 files reviewed, quit, come back the next morning — everything is unreviewed again and
F(unreviewed only) has nothing to filter on. Nothing else preserves it either: review history saves annotations plus diffs, and only when annotations exist, so a session that produced marks and no annotations leaves no trace at all.With the pair above the second pass is what it should be: preload what I already finished, press
F, and look only at what is left.Why not
--include/--onlyI can already compute the remaining set outside revdiff and pass it in — but those flags drop every other file from the review. When the file I am reading refers to one I already checked, I cannot glance at it, and I cannot change my mind and un-finish a file mid-session.
A preloaded reviewed mark is different in exactly the way that matters: every file stays present and openable, the finished ones simply stop competing for attention, and
Spacestill un-marks one when it turns out to deserve a second look. "Out of the way but reachable" is the state--onlycannot express.It also closes the loop with GitHub
GitHub tracks the same per-reviewer concept and it is scriptable:
markFileAsViewed/unmarkFileAsViewedmutations, andPullRequestChangedFile.viewerViewedStatereads backVIEWED/UNVIEWED/DISMISSED(the last meaning the file changed since it was viewed). So the export feeds the PR directly:and the query feeds the preload back on the next round. Today I read the files in revdiff and then re-click each one in the GitHub web UI by hand.
Shape
Probably not on the annotation stream: the record format is
## path[:line[-line]] (…), and the README already documents defending that parser against##collisions in comment bodies, so a second record kind there would break existing consumers. A separate sink avoids the question — a plain path-per-line file, or a field in a structured (JSON) output mode if one is planned anyway.Nothing new needs tracking: the model already holds the set, and
Ralready owns the rule for when a mark survives a reload. This is persisting state that exists.Environment
revdiff v1.12.0-ad8c796-20260804T171719(homebrew,umputun/apps/revdiff), macOS 15.6.