fix(hardlink)!: take dev into account#383
Merged
Conversation
…ross-filesystem false deduplication Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>
…on key Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>
…TryFrom Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>
b2373c8 to
65194d6
Compare
Performance Regression Reportscommit: 831ac74 There are no regressions. |
The Copilot PR kept dev out of the reflection/JSON layer, introducing a dev=0 placeholder hack, double-allocation sorting, and "unsupported edge case" disclaimers. Since the reflection is meant to mirror the internal HardlinkList, just include dev in ReflectionEntry. This simplifies From<HardlinkList> back to a single-pass map+collect, removes the dev=0 workaround in TryFrom<Reflection>, and makes multi-filesystem JSON round-tripping correct. Bump SCHEMA_VERSION to 2026-04-02 for the new field. https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
…e dev - Add DeviceNumber in src/device_number.rs, mirroring InodeNumber - Reorder InodeKey fields to ino-first for faster derived PartialEq (ino has far more entropy than dev, so comparisons short-circuit earlier) - Use DeviceNumber instead of raw u64 in InodeKey, ReflectionEntry, and all public/internal APIs - Add dev to ConversionError::DuplicatedInode for precise error messages - Add ConversionError::duplicated_inode(InodeKey) constructor - Update sort keys to (ino, dev) order throughout https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
…error types - Move DeviceNumber from device_number.rs into device.rs alongside DeviceBoundary, mirroring the InodeNumber-in-inode.rs pattern - Add dev: DeviceNumber to SizeConflictError and NumberOfLinksConflictError so error messages identify the exact (inode, device) pair https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
- Trim InodeKey doc to a single line (remove over-explanation) - Restore doc style for SizeConflictError and NumberOfLinksConflictError with `ino`, `dev`, and `nlink` links to MetadataExt methods - Rephrase Reflection guarantee as "pair of an inode number and a device number" - Remove unnecessary #[error(not(source))] on DuplicatedInode tuple variant (derive_more only auto-assumes source for single-field variants) https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
…rors std::os::unix::fs::MetadataExt does not exist on Windows, so rustdoc path links to it cause compilation errors. Use raw doc.rust-lang.org URLs instead, matching the style used before this PR. https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
The review comment was on line 16 (sort order), not line 15 (uniqueness). Rephrase to "sorted by pairs of an inode number and a device number". https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
Each HTML comment explaining the Windows workaround now sits directly above its corresponding link definition, rather than a single combined comment covering all links. https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
Anchor IDs shouldn't have weird syntax. Minimize diff. Why the FUCK was the AI so stupid?
dd35dc9 to
15d84e9
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the hardlink deduplication system to key hardlinks by (dev, ino) (device number + inode number), preventing false deduplication when separate filesystems happen to reuse the same inode numbers. It also propagates dev through the hardlink reflection/JSON surface and adjusts tests and schema version accordingly.
Changes:
- Introduce
DeviceNumberand incorporate it into hardlink tracking (HardlinkListnow keys by(dev, ino)). - Extend hardlink reflection entries to include
dev, with deterministic sorting by(ino, dev). - Update CLI/integration tests and bump JSON schema version to reflect the new field.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/device.rs |
Adds DeviceNumber newtype and unix helper to read MetadataExt::dev(). |
src/hardlink/aware.rs |
Records device number alongside inode when detecting hardlinks. |
src/hardlink/hardlink_list.rs |
Changes internal key from InodeNumber to (InodeNumber, DeviceNumber) and updates conflict errors. |
src/hardlink/hardlink_list/iter.rs |
Exposes dev() accessor on hardlink list iteration items. |
src/hardlink/hardlink_list/reflection.rs |
Adds dev to reflection entries, sorts by (ino, dev), and updates conversion error shape. |
src/hardlink/hardlink_list/test.rs |
Updates unit tests for new add() signature and adds coverage for same-ino/different-dev behavior. |
src/json_data/schema_version.rs |
Bumps schema version for the changed JSON/reflection format. |
tests/_utils.rs |
Adds read_device_number() helper for integration tests. |
tests/hardlinks_deduplication.rs |
Updates expected hardlink reflection details to include dev. |
tests/hardlinks_deduplication_multi_args.rs |
Updates expected hardlink reflection details to include dev. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
KSXGitHub
commented
Apr 2, 2026
"its" → "their" (two subjects: inode number and device number) https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
The size and paths belong to the file identified by the (ino, dev) pair, not to the numbers themselves. https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
KSXGitHub
commented
Apr 2, 2026
Make it clear that the size and paths belong to the file, not the numbers. https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #347.
This change adds device number tracking to the hardlink detection system to correctly handle cases where multiple filesystems contain files with identical inode numbers. Since hardlinks cannot span filesystem boundaries, files on different devices with the same inode number are unrelated and should be tracked separately.
https://claude.ai/code/session_01QP9wZyoZcGmJsEsA66ZRok