lore: Handle nested repositories as working-tree scan boundaries#89
Open
lehuan5062 wants to merge 4 commits into
Open
lore: Handle nested repositories as working-tree scan boundaries#89lehuan5062 wants to merge 4 commits into
lehuan5062 wants to merge 4 commits into
Conversation
d5a6e05 to
900bcc7
Compare
Collaborator
|
I think this is a good change - nested repos should be ignored. However, you are bundling two changes into one here - the discard on scan fix and the nested repo ignore. Could you break out the discard scan fix to a separate PR please? |
39431d8 to
bc31e74
Compare
Member
Author
Please see #104. |
A working-tree scan (`status --scan` / `stage --scan`) already discards a reverted uncommitted *file* add so `state_staged` matches the filesystem: a file that was staged and then removed before any commit has no committed base to delete from, so reporting a `Delete` would leave an unremovable "zombie" entry. A reverted uncommitted *directory* add was not handled the same way. Extend the same treatment to directories. When a directory node exists in `state_from` but neither in `state_current` (never committed) nor on disk, queue it for discard instead of emitting a meaningless `Delete`. Discarding a directory node must also reclaim its subtree: `apply_pending_discards` now recursively discards every child below a directory node before unlinking the node itself, so no stale descendant slots are left behind. Includes a Rust test covering the index-then-remove cycle for a directory add, asserting the node is discarded (and does not resurface on a later scan) rather than reported as a delete. Signed-off-by: Huân Lê-Vương <[email protected]>
A child directory that carries its own `.lore/` control directory is a nested repository — its contents belong to it, not the parent. The parent's working-tree scan (from `status --scan` or `stage --scan`) must treat it as an implicit boundary: do not descend into or index it, just as git treats a nested `.git` directory as a submodule boundary. When scanning the filesystem, skip any child directory that is itself a Lore working copy. A node previously indexed for such a directory (from before the boundary check existed) falls through to the delete pass, where it is cleared as a reverted uncommitted directory add on the next scan. Add a new optional-paths argument struct (FileOptionalPathsTargetsArgs) to support `lore stage --scan` with no path, which reconciles and stages the entire working tree from the repository root. Without `--scan`, a path remains required. Includes: a Rust test covering the nested-repository boundary (with state-based setup), plus a CLI smoke test for both nested-repository handling and `stage --scan` with no path. Signed-off-by: Huân Lê-Vương <[email protected]>
bc31e74 to
2e65f1b
Compare
mjansson
reviewed
Jul 10, 2026
Move the is_nested_repository_root() check from the directory-walk loop (where it runs for every item) into the unmatched-child arm of binary_search_by, since a nested repository will never be tracked in the current repository's merkle tree and therefore always falls there. Normal directory descent (matched tracked nodes) now pays zero extra filesystem metadata queries (no is_dir probes for .lore or .urc). Preserve zombie-entry cleanup by restricting the check in the matched `was_directory && is_directory` branch to the staged-only case (scan_dirty && !current_node_id.is_valid_node_id()), where the cost is already paid by other mutations. This prevents re-indexing of nested repositories that were indexed before this boundary feature existed. BEHAVIOR CHANGE: A nested repository directory that was *committed* into the parent before this boundary check existed is no longer auto-unmatched and will stay tracked until explicitly removed, matching git's behavior with nested .git directories. Only staged (never-committed) nested roots are auto-discarded on the next scan. Add test case for the zombie-migration path: a staged directory that becomes a nested repository root must be discarded and its contents not re-indexed. Signed-off-by: Huân Lê-Vương <[email protected]>
The previous commit's zombie-discard fix only fires for never-committed staged directories, leaving a gap: no test exercised the documented behavior change where a directory committed before becoming a nested repository root stays tracked. Add committed_directory_becoming_nested_repository_stays_tracked, which stages+commits a directory, turns it into a nested repository root, then modifies its tracked file to confirm the parent still descends into and indexes it rather than treating it as an implicit boundary. Signed-off-by: Huân Lê-Vương <[email protected]>
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.
A child directory that carries its own
.lore/control directory is a nested repository — its contents belong to it, not the parent. The parent's working-tree scan (fromstatus --scanorstage --scan) must treat it as an implicit boundary: do not descend into or index it, just as git treats a nested.gitdirectory as a submodule boundary.When applying pending discards during a scan, recursively discard the entire subtree below a directory node before unlinking the node itself. This ensures all stale "zombie" entries are cleared — for example, a nested repository's contents that an older client indexed before the boundary check existed.
When scanning the filesystem, skip any child directory that is itself a Lore working copy. A node previously indexed for such a directory (from before the boundary check existed) falls through to the delete pass, where an empty never-committed entry is discarded on the next scan.
Add a new optional-paths argument struct (FileOptionalPathsTargetsArgs) to support
lore stage --scanwith no path, which reconciles and stages the entire working tree from the repository root. Without--scan, a path remains required.Includes: Rust tests covering both the nested-repository boundary (with state-based setup) and the reverted-directory discard logic, plus a CLI smoke test for both nested-repository handling and
stage --scanwith no path.