Skip to content

Add dry-run index preview - #274

Open
faysou wants to merge 1 commit into
cocoindex-io:mainfrom
faysou:dry-index-preview
Open

Add dry-run index preview#274
faysou wants to merge 1 commit into
cocoindex-io:mainfrom
faysou:dry-index-preview

Conversation

@faysou

@faysou faysou commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary

ccc index --dry lists files that the next index would add, update, or delete. It uses the same include patterns, exclude patterns, nested .gitignore rules, and max_file_size limit as normal indexing, then prints each group in sorted order with an exact count. Modified files appear under Files to update.

Successful indexes persist a content fingerprint for every matched source file. The dry-run command hashes the current matched files and reads those fingerprints through a read-only SQLite connection. It does not start indexing or change the target database.

Design

CocoIndex 1.0.18 exposes App.update(preview=True), but its preview planner supports only flat target actions. The code index uses a SQLite table target with child row providers, so applying that API to the indexing app fails before it can report file changes.

This change adds a small flat CocoIndex app for the file manifest. Each track_file component owns one path and stores the file content fingerprint in code_file_manifest. CocoIndex memoization lets normal incremental indexes skip unchanged manifest components. The manifest update runs only after the main indexing app succeeds.

flowchart TB
    Index["ccc index"] --> Main["Update search index"]
    Main --> Manifest["Update file manifest"]
    Manifest --> Stored["code_file_manifest"]

    Dry["ccc index --dry"] --> Match["Match and hash source files"]
    Dry --> Read["Read stored fingerprints"]
    Stored --> Read
    Match --> Compare["Compare paths and fingerprints"]
    Read --> Compare
    Compare --> Added["Added"]
    Compare --> Updated["Updated"]
    Compare --> Deleted["Deleted"]
Loading

The normal index writes the baseline. Dry runs compare against that baseline without updating it.

Behavior and compatibility

  • Report matched empty files because source membership is independent of vector row creation.
  • Detect updates from content fingerprints rather than modification times.
  • Use the configured database path mapping for the manifest because it lives in target_sqlite.db.
  • Treat every matched file as an addition when no index exists.
  • Fall back to the prior path comparison for an index created before the manifest table exists. In that case, the output states that updates are unavailable until the next successful index.

Relevant files

Verification

  • uv run --no-sync pytest tests/test_index_changes.py tests/test_cli_helpers.py -q: 31 passed.
  • uv run --no-sync pytest tests/test_e2e.py::test_session_index_dry_lists_changes_without_indexing -q: 1 passed.
  • uv run --no-sync pytest tests/test_embed_params_forwarding.py tests/test_chunker_registry.py -q: 7 passed.
  • uv run --no-sync pytest tests/test_project_indexing.py -q: 5 passed.
  • Focused mypy, Ruff lint, Ruff format, and git diff --check: passed.

@badmonster0
badmonster0 requested a review from georgeh0 August 16, 2026 01:20
@georgeh0

Copy link
Copy Markdown
Member

Hi @faysou ,

Thanks for the PR!

Just wonder what's the main motivation for this new feature? When will you use it?

I ask because this will determine how precise we need it to be. Under the current implementation, we'll show new files and deleted files, but not showing updated files. It may be unexpected and misleading for many cases.

cocoindex has a "shadow run / preview API". With this, we may be able to report more precise diffs.

@faysou

faysou commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

Hi @georgeh0 my use case was initially for new files. I saw many more files were about to get indexed but I didn't know where they were from. They turned up to be from another wortree created by an agent. I asked the agent where are the files and it wrote some custom script and I thought it could be useful for the future as a proper feature. But I agree that it could be more precise as well for updated files. I can leave the implementation to you if you prefer or I can update the PR. But I'm not a regular on this project so you may know better.

@faysou
faysou force-pushed the dry-index-preview branch from 492e563 to cf4c51e Compare August 18, 2026 16:33
- Track file fingerprints after successful index updates
- Report added, updated, and deleted files without writes
- Preserve path-only previews until the manifest exists
@faysou
faysou force-pushed the dry-index-preview branch from cf4c51e to 6ed59d7 Compare August 18, 2026 17:17
@faysou

faysou commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

I've updated the PR.

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