Skip to content

Compare code semantically across a force push in review bundles #606

Open

Description

@Alan52254

Problem

After a force push, review-bundle.sh --since points a reviewer to a tree diff or a git range-diff. Both compare lines. When an author reworks a commit, the range-diff reads almost as long as the whole diff: 925 of 1200 lines on #586, 624 of 1284 on #584.

Current behavior

diffmodel.py pairs moved units by indentation, which workbench.md calls a guess at syntax and not a parse. since.range-diff.txt shows a reworked commit as removed and added lines, so a rename or a moved function reads as new code.

Desired outcome

A reviewer reading a rewritten pull request sees which functions or blocks changed in meaning, and which only moved or were renamed, without rereading the whole commit.

Scope

Out of scope

Replacing since.diff and since.range-diff.txt; they stay the fallback.

Related

#605 adds those two files for #587.

Activity

  1. jserv commented on Nov 6, 2026

    @jserv
    Contributor

    @Alan52254 Before code, state what a reviewer gets and how it is checked: the file the bundle writes and its format, and for each of #585, #584 and #586 what the comparison must report, meaning which units it calls moved or renamed and which it calls changed. Those three become the test cases.

  2. Alan52254 commented on Nov 7, 2026

    @Alan52254
    ContributorAuthor

    When --since compares a rewrite, the bundle also writes since.units.txt next to since.diff or since.range-diff.txt. It is built from diffmodel.reading on the diff between the two heads, limited to the files the pull request touches, and it is absent when the comparison falls back to the whole diff. It says what to read first; the whole diff is still reviewed.

    The first line is # units old=<sha7> new=<sha7> status=<rewritten|rebased>. Every other line is one unit, tab separated and sorted by path and new line: <verdict> <path> <unit> <detail>. The verdict is added, removed, changed, renamed or moved. The unit is the first line of the function, class or block that collect_units cuts, or the hunk section when none is cut. The detail is +<n> -<m> for changed, <old> -> <new> for renamed and from <path>:<line> for moved.

    tests/test_skill_scripts.py feeds the recorded diff between the two heads of each case below and compares the file with the lines listed. reading reports no moved unit on any of the three, so the moved verdict comes from a small fixture.

    #585, d8d4fe8 to 6bf2003, one base:

    changed   .github/workflows/pr-description.yml   jobs:   +0 -6
    

    #584, e64598e to 4d13dd5, base moved:

    added     src/config.rs   pub fn configured_duration
    added     src/main.rs   fn configured_duration
    renamed   tests/web/token_default.rs   fn token_duration_default_stops_at_the_recording_cap   -> async fn the_token_route_grants_the_configured_default_to_a_request_naming_none
    

    The two configured_duration have different signatures and sit in different files, so they are two additions and not a move. The new tests in tests/unit/bin.rs and tests/browser/interviewer-voice.test.js are added, and the other touched files are changed without a unit.

    #586, caff855 to d6e5200, base moved:

    renamed   tests/browser/example-board-ui.test.js   test("the button or Escape shrinks the board, but not from the editor or mid-stroke"   -> test("the button or Escape shrinks the board, but not from a sidebar field or mid-stroke"
    renamed   tests/browser/example-board-ui.test.js   test("closing Example drawing shrinks an expanded board"   -> test("closing Example drawing shrinks an expanded board and frees the editor"
    renamed   tests/browser/example-board-ui.test.js   test("an expanded board covers Jim's Hide avatar button"   -> test("a click where Hide avatar sits reaches the expanded board, not the stage"
    changed   web/example-board.js   export function mountExampleBoard
    changed   web/interview-drawer.js   export function mountInterviewDrawer
    changed   web/interview.js   function bindEvents
    

    The tests added in tests/browser/example-board-ui.test.js, interview-layout.test.js and run-shortcut.test.js are added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions