Skip to content

Fix stale folded buffers in split diff view#49699

Merged
bennetbo merged 2 commits intomainfrom
fix-unmapped-folded-buffer-repro
Feb 20, 2026
Merged

Fix stale folded buffers in split diff view#49699
bennetbo merged 2 commits intomainfrom
fix-unmapped-folded-buffer-repro

Conversation

@as-cii
Copy link
Member

@as-cii as-cii commented Feb 20, 2026

When a buffer is folded in the split diff view and then removed from the multibuffer (via remove_excerpts_for_path), the block map's folded_buffers set retains a stale entry for that buffer ID. Later, when the split view syncs folded state from the RHS display map to the LHS, it tries to look up the companion mapping for this stale buffer and fails because the companion no longer tracks a buffer that's been removed from the multibuffer.

This originally caused a panic via .expect(). This PR:

  1. Converts the panic into graceful handling by skipping unmapped buffers.
  2. Actively removes stale entries from folded_buffers so they don't persist as ghost state — ensuring that if the same buffer is later re-added, it won't incorrectly appear as folded.
  3. Adds a regression test covering the full lifecycle: fold → remove → split → re-add → assert both LHS and RHS report the buffer as not folded.

Release Notes:

  • Fixed a crash in split diff view when a folded buffer was removed and re-added.

When a buffer is removed from a multibuffer (via remove_excerpts_for_path),
the block map's folded_buffers set retains a stale entry for that buffer.
Later, when the split view syncs folded buffers from RHS to LHS, it tries
to look up the companion mapping for this stale buffer ID and fails because
the companion no longer has a mapping for a buffer that's no longer in the
multibuffer.

Previously this was an expect() that panicked; the prior commit turned it
into a log::warn and skip. This commit goes further: instead of just
skipping the unmapped buffer, we actively remove it from the RHS's
folded_buffers set so it doesn't persist as stale state. This ensures that
if the same buffer is later re-added to the multibuffer, it won't
incorrectly appear as folded.

The test is extended to cover this scenario: after removing a folded buffer
and re-adding it via set_excerpts_for_path, both the LHS and RHS editors
correctly report the buffer as not folded.
@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Feb 20, 2026
@zed-community-bot zed-community-bot bot added the staff Pull requests authored by a current member of Zed staff label Feb 20, 2026
@bennetbo bennetbo enabled auto-merge (squash) February 20, 2026 09:47
@bennetbo bennetbo merged commit 11bccbc into main Feb 20, 2026
37 checks passed
@bennetbo bennetbo deleted the fix-unmapped-folded-buffer-repro branch February 20, 2026 09:49
@bennetbo
Copy link
Member

/cherry-pick preview

@bennetbo
Copy link
Member

/cherry-pick stable

@zed-zippy
Copy link
Contributor

zed-zippy bot commented Feb 20, 2026

🍒💥 Cherry-pick did not succeed
https://github.com/zed-industries/zed/actions/runs/22219350524

@zed-zippy
Copy link
Contributor

zed-zippy bot commented Feb 20, 2026

🍒💥 Cherry-pick did not succeed
https://github.com/zed-industries/zed/actions/runs/22219354222

bennetbo pushed a commit that referenced this pull request Feb 20, 2026
When a buffer is folded in the split diff view and then removed from the
multibuffer (via `remove_excerpts_for_path`), the block map's
`folded_buffers` set retains a stale entry for that buffer ID. Later,
when the split view syncs folded state from the RHS display map to the
LHS, it tries to look up the companion mapping for this stale buffer and
fails because the companion no longer tracks a buffer that's been
removed from the multibuffer.

This originally caused a panic via `.expect()`. This PR:

1. Converts the panic into graceful handling by skipping unmapped
buffers.
2. Actively removes stale entries from `folded_buffers` so they don't
persist as ghost state — ensuring that if the same buffer is later
re-added, it won't incorrectly appear as folded.
3. Adds a regression test covering the full lifecycle: fold → remove →
split → re-add → assert both LHS and RHS report the buffer as not
folded.

Release Notes:

- Fixed a crash in split diff view when a folded buffer was removed and
re-added.
bennetbo pushed a commit that referenced this pull request Feb 20, 2026
When a buffer is folded in the split diff view and then removed from the
multibuffer (via `remove_excerpts_for_path`), the block map's
`folded_buffers` set retains a stale entry for that buffer ID. Later,
when the split view syncs folded state from the RHS display map to the
LHS, it tries to look up the companion mapping for this stale buffer and
fails because the companion no longer tracks a buffer that's been
removed from the multibuffer.

This originally caused a panic via `.expect()`. This PR:

1. Converts the panic into graceful handling by skipping unmapped
buffers.
2. Actively removes stale entries from `folded_buffers` so they don't
persist as ghost state — ensuring that if the same buffer is later
re-added, it won't incorrectly appear as folded.
3. Adds a regression test covering the full lifecycle: fold → remove →
split → re-add → assert both LHS and RHS report the buffer as not
folded.

Release Notes:

- Fixed a crash in split diff view when a folded buffer was removed and
re-added.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement staff Pull requests authored by a current member of Zed staff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants