Browse docs
Docs / Guides / Line Attribution
View as Markdown

Line Attribution

Line attribution shows who last changed each line of a text file and which saved version introduced or replaced it. It is a read-only view over the project's existing version history - it never writes line data to the hub and never needs a Git clone.

Where to find it#

  • Web dashboard and Desktop App: open a text file's History panel and choose Line attribution. The web view can also open the comparison for a line's version; the Desktop App jumps to that version in the history list.
  • CLI: swarmfile blame --lines <path> prints the ranges (and --format=gutter a blame-style gutter). --json returns the same ranges for scripts.

Attribution is available for files the client can decrypt and read. End-to-end encrypted projects work in the Desktop App (the key never reaches the hub); the web view cannot decrypt them and points at the Desktop App.

Reading the view#

Each range names the writer and the version's own time. Copied source rows from a clean merge keep the source writer and age, not the merge time; a merge line is labeled like an ordinary save. A line the history cannot resolve is reported as unknown rather than credited to the wrong writer. If the retained window starts mid-file, the view says the history is truncated and marks the prefix unknown.

Source copies: a clean merge copies up to 30 source versions into the target as internal side rows. Ordinary history hides them; the web History panel's Show source copies button (and the Desktop App, when a line range points at one) reveals them with a source copy badge. They are display-only provenance and cannot be rolled back from the versions table.

Limits#

  • Text files only; binaries have no meaningful line-level diff.
  • Copied source rows are a hosted-hub feature; the community server's history has no copied source side rows, so clean merges there have no source-age attribution.
  • A version over 8 MiB, a file over 50,000 lines, or more than 64 MiB of version text stops the walk and is reported as truncated; an oversized current version is a hard error instead. The walk also has a wall-clock bound.
  • The CLI/engine reads up to --max-versions (default 100), enforced at page granularity (a page can add up to 50 versions beyond the limit); the web panel keeps 32 content versions and at most 96 copied side rows. Older versions may be outside either window. Managed and plaintext content is read through the same signed version URL as the diff view.
  • A version read timeout is reported as content_unavailable (there is no separate content_timeout code).
  • Staged changelist work is not included until it is submitted; the panel says so.
  • Exact agent attribution requires the save to come from the agent's own engine session. The line label carries the machine/agent identity the history row recorded; several agents sharing one mount are not separated by line.

Privacy#

The view reads only versions the caller may already read. Copied source rows are gated on the source entry's ACL; the hub hides a row the caller cannot read and redacts the copied source CID from the merge row. A revoked source entry is refused by the engine before cached content is served.

See also Trash, History & Rollback and the CLI reference.