Renames and moves

A rename is one change, not two

When an agent renames a function or moves it to another file, Branchscope pairs the old element with the new one by its code, not by its name or its place. The review shows one rename instead of a removal and an addition, and rules, plans and conflict maps follow it.

Same code

Paired by what the code is

Each function, type and field gets a fingerprint when the graph is built: a hash of its declaration's tokens, with whitespace and comments left out and its own name replaced by $. A removed element and an added one with the same fingerprint are the same code. A rename that also changed the body gets another fingerprint and stays a removal and an addition: pairing never guesses.

alice/invoices › src/lib/api/invoices.ts

Before

export function fetchInvoice(id: string) {
  return get("/invoices/" + id);
}

After, renamed and with a doc comment

/** Loads one invoice. */
export function loadInvoice(id: string) {
  return get("/invoices/" + id);
}

Its tokens, with its own name as $

export function $ ( id : string ) { return get ( "/invoices/" + id ) ; }
fingerprint 028d4e472bc8ebc9d402e30639a3bb66same fingerprint: renamed

Renames and moves

In place, to another file, or a whole file

Same fingerprint and place with another name is a rename. Same fingerprint and name in another file, namespace or package is a move. A file, namespace or type whose declared children all reappear in exactly one new one pairs too, with everything in it. A pair is the same kind of element in the same language, and the only match both ways: with two candidates, nothing pairs. It's worked out from the graphs, not from git's rename detection.

GET /v1/repos/alice/invoices/changes/12/views
"renamed": [
  { "from": "ts:apps/web|src/lib/api/invoices.ts|fetchInvoice()",
    "to":   "ts:apps/web|src/lib/api/invoices.ts|loadInvoice()" },
  { "from": "ts:apps/web|src/lib/api/invoices.ts|searchInvoices()",
    "to":   "ts:apps/web|src/lib/api/search.ts|searchInvoices()" },
  { "from": "dotnet:src/Billing.Api|Billing.Api.Controllers|InvoicesController#",
    "to":   "dotnet:src/Billing.Api|Billing.Api.Controllers|BillsController#" },
  { "from": "dotnet:src/Billing.Api|Billing.Api.Controllers|InvoicesController#Get(System.Guid)",
    "to":   "dotnet:src/Billing.Api|Billing.Api.Controllers|BillsController#Get(System.Guid)" }
]

In the review

Drawn once, with where it came from

The change map draws a renamed or moved element once, by its new name, in its own colour, with a note: was fetchInvoice() for a rename, moved from src/lib/api/invoices.ts for a move. Its unchanged calls aren't redrawn as removed and added. Findings list each pair, as do bscope change review and the API. A renamed element isn't counted as edited: its body is the same.

alice/invoices › Changes › #12

src/lib/api/invoices.ts

loadInvoice()

was fetchInvoice()

src/lib/api/search.ts

searchInvoices()

moved from src/lib/api/invoices.ts

renamed or moved

Rules and plans

Rules follow it to its new name

A rule violation that was already there is compared under the element's new ID, so a renamed or moved one stays existing, counted and not blamed on the change, rather than one new and one fixed. A connection that differs only by a renamed end is unchanged. Checked against a PLAN.md, a rename touches both its old place and its new one.

alice/invoices › Changes › #12
  • Rules: no new violations of the 2 configured rules.
  • Renamed or moved (same code under a new name or in a new place; rules follow them)
    • InvoicesController → BillsController
    • InvoicesController.Get() → BillsController.Get()
    • fetchInvoice() → loadInvoice()

Conflict maps

Renamed on one side, used on the other

When one side renames or moves something and the other adds a use of its old name, the conflict map reports it, even when the text merges cleanly. It's a warning beside Merge that says what the element is called now, never a block.

alice/invoices › Change #9
Merges cleanly as text, but:

createInvoice() was renamed to issueInvoice() on main, and this change adds a use of it

Merge

Rename freely

Push a branch that renames or moves code, open a change, and its graph review lists each rename once.