Skip to content

feat!: start blame from Start instead of ObjectId - #2719

Merged
Sebastian Thiel (Byron) merged 4 commits into
GitoxideLabs:mainfrom
cruessler:blame-untracked-changes
Aug 6, 2026
Merged

feat!: start blame from Start instead of ObjectId#2719
Sebastian Thiel (Byron) merged 4 commits into
GitoxideLabs:mainfrom
cruessler:blame-untracked-changes

Conversation

@cruessler

@cruessler Christoph Rüßler (cruessler) commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

This PR changes gix_blame::file()’s API to use Start as the starting point instead of a simple ObjectId. Start can be either a Commit or Contents { 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 changes Repository::blame_file nor gix blame …; both use Start::Commit to keep their existing behaviour. I plan on adding support for Start::Contents to 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 something Platform::set_resource should 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 diffable Vec<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).

@cruessler
Christoph Rüßler (cruessler) marked this pull request as ready for review July 15, 2026 19:44

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread gix-blame/src/file/function.rs
@cruessler

Copy link
Copy Markdown
Contributor Author

Would it make sense to add a test for high-level gix blame … behaviour at the command-line level? From what I remember, you generally consider CLI behaviour unstable and prefer not to add tests. Is that still the case?

@Byron

Copy link
Copy Markdown
Member

you generally consider CLI behaviour unstable and prefer not to add tests. Is that still the case?

Yes, that's correct. If there should be tests, they have to be in plumbing or gix (crate).
Lastly, what I noticed that agents like to write tests in gitoxide-core for faster turnaround times, and that's fine, I just delete them when they are done and I could run it successfully once or twice.

@cruessler

Copy link
Copy Markdown
Contributor Author

The failing job seems to be unrelated to the changes in this PR.

- 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>

@Byron Sebastian Thiel (Byron) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Start where 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/fix titles, 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.

@Byron
Sebastian Thiel (Byron) merged commit 95e0213 into GitoxideLabs:main Aug 6, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants