feat!: start blame from Start instead of ObjectId - #2719
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9127f126d7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "Codex (@codex) address that feedback".
|
Would it make sense to add a test for high-level |
Yes, that's correct. If there should be tests, they have to be in plumbing or |
|
The failing job seems to be unrelated to the changes in this PR. |
9850daf to
20c42b2
Compare
- Including some unrelated modifications to the contribution guidelines. <!-- agent --> - [P1] Avoid taking ilog10 of an empty outcome — /Users/byron/dev/github.com/GitoxideLabs/gitoxide.blame-untracked-changes/gitoxide-core/src/repository/blame.rs:87-87 When the blamed file is empty, or the requested ranges are wholly outside it, `entries.last()` is `None`, so this calls `0.ilog10()` and panics before producing output. For example, `gix blame empty.txt` exits with status 101 instead of returning no entries; special-case an empty outcome or use a checked logarithm. - [P1] Apply repository filters before blaming worktree bytes — /Users/byron/dev/github.com/GitoxideLabs/gitoxide.blame-untracked-changes/gitoxide-core/src/repository/blame.rs:50-50 When a worktree file requires repository-configured clean or EOL conversion, this default pipeline has neither the repository filter options nor diff drivers, and the empty attribute callback prevents path attributes from applying. For example, an unchanged file governed by `*.txt text eol=crlf` is read with CRLF and compared with the LF blob, causing every line to receive the null ID; construct the pipeline from the repository configuration and attribute stack. - [P2] Preserve symlink entry mode when reading the worktree — /Users/byron/dev/github.com/GitoxideLabs/gitoxide.blame-untracked-changes/gitoxide-core/src/repository/blame.rs:54-54 On systems supporting symlinks, hard-coding `EntryKind::Blob` makes the pipeline follow a worktree symlink and read the target file rather than reading the link target as blob data. An unchanged `link -> target` is therefore shown as the target file's lines attributed to the null ID instead of one committed line containing `target`; obtain the actual entry kind from the index or HEAD. - [P2] Convert the suspect blob with the same textconv driver — /Users/byron/dev/github.com/GitoxideLabs/gitoxide.blame-untracked-changes/gix-blame/src/file/function.rs:994-996 When `Start::Contents` contains binary-to-text-derived data from the documented `convert_to_diffable()` route, this compares that derived text against the raw blob from the object database. Even an unchanged file using a textconv driver is then reported as uncommitted; prepare the first suspect through the same diff pipeline or otherwise ensure both sides use the same representation. Assisted-by: GPT 5.6 Co-authored-by: GPT 5.6 <codex@openai.com>
20c42b2 to
2ea191f
Compare
Sebastian Thiel (Byron)
left a comment
There was a problem hiding this comment.
Thanks a lot! I verified it's working as expected for common blob input and gix blame <file>.
I did make some minor changes to gix-blame itself, please take a look and submit a follow-up if corrections are necessary.
Also:
- tests for symlinks seem to be missing, I added a TODO (even though I am thinking that this already works correctly). This also relates to
Startwhere I added a similar TODO. - There is definitely something wrong/missing tests with textconv conversions. This allows blaming of binary files that can be converted, which is probably not very well supported right now. Also getting this to work needs more control over the filter pipeline than there currently is.
Some more notes on commits mainly
- there only ever needs to be a single "adapt to changes" commit
- now that I see this, I became aware that I am not a fan of "record any history" anymore. Instead, squash commits down to their essence and think of
feat/fixtitles, along with a message body that is nice to read in changelogs. - Generally, I am a big fan of explaining the motivation/reasoning in the commit message body, while I see little value in summarizing what it does just because that's in the code already and agents can summarize perfectly. But why it is, no matter how trivial the motivation, that's what can otherwise only be deduced.
This PR changes
gix_blame::file()’s API to useStartas the starting point instead of a simpleObjectId.Startcan be either aCommitorContents { first_suspect: ObjectId, contents: Cow<'_, u8> }. This is useful when callers have a version of the file that is not committed yet.This PR potentially addresses #2666 if changes to
gix_blame::file()are sufficient. This PR neither changesRepository::blame_filenorgix blame …; both useStart::Committo keep their existing behaviour. I plan on adding support forStart::Contentsto both in follow-up PRs. Do you potentially have any suggestions on how to get the worktree version of a file as idiomatically as possible? Is this somethingPlatform::set_resourceshould be used for?Update 2026-07-19: I’ve adapted
gix blame …, in order to provide an example for how to load a file from the worktree and convert it to a diffableVec<u8>.This PR also affects #2457 as it changes some of the same locations, but I think the resulting conflicts should be manageable.
This PR was made with the help of an LLM, mostly for inspiration and getting an overview of the problem space, but also for some initial blocks of code (that I then reworked).