Skip to content

Document that writing the index does not refresh the tree-cache extension#2664

Merged
Sebastian Thiel (Byron) merged 2 commits into
GitoxideLabs:mainfrom
ameyypawar:docs/2421-index-write-tree-cache
Jun 21, 2026
Merged

Document that writing the index does not refresh the tree-cache extension#2664
Sebastian Thiel (Byron) merged 2 commits into
GitoxideLabs:mainfrom
ameyypawar:docs/2421-index-write-tree-cache

Conversation

@ameyypawar

Copy link
Copy Markdown
Contributor

What

Documents a footgun on the index write methods, per #2421.

File::write, File::write_to, and State::write_to serialize the tree (tree-cache) extension from its current in-memory state — it is not recomputed or invalidated to match the entries. So if entries were modified since the index was read, the tree-cache is written back still marked valid even though it is now stale.

Git uses the tree-cache to skip unchanged directories when building a tree (on git commit / git write-tree), so a stale-but-valid tree-cache can make a later commit capture outdated subtree content; more generally, git status and later commits can disagree about what is staged.

The note points to State::remove_tree() as the workaround until the tree-cache is updated on write:

index.remove_tree();
index.write(gix_index::write::Options::default())?;

This is the documentation route (option 1) you preferred in the issue, rather than a behavior change.

Notes

  • Doc-only. The caveat is placed on all three public index serializers (File::write, File::write_to, State::write_to), with the full explanation on File::write and cross-references on the other two.
  • cargo doc -p gix-index --features sha1 (with RUSTDOCFLAGS=-D warnings) and cargo fmt --check are clean.

Addresses #2421.

`File::write` and `File::write_to` serialize the `tree` (tree-cache)
extension from its in-memory state without recomputing it from the
current entries. If entries were modified, the stale tree-cache is
written out, which other Git implementations misread -- e.g. `git
status` showing no changes, or a commit including unexpected content.

Document this on both methods and point to `State::remove_tree()` as the
workaround until the tree-cache is updated on write.

For GitoxideLabs#2421
- Lead with the verifiable consequence (a commit capturing stale subtree
  content via `git write-tree`) rather than asserting `git status`
  consults the tree-cache; keep the maintainer's "status and later
  commits can disagree about what is staged" framing as the general
  statement.
- Make the mechanism precise: the tree-cache is written back still
  marked valid without being invalidated, hence stale.
- Add the same caveat to the public `State::write_to`, the serializer
  both `File::write`/`write_to` delegate to.

@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, that's a great catch!

Let's start with that and see if eventually this shortcoming can be removed.

For now, the index is very much plumbing and as such can have such foot guns, just to accelerate certain cases that don't actually need the tree cache to be recomputed or removed.

@Byron
Sebastian Thiel (Byron) merged commit f7d6608 into GitoxideLabs:main Jun 21, 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