Commit Graph
940 Commits
Author SHA1 Message Date
Ben Kunkle aecaacdb44 git: Move diff hunk operations onto buffer diffs (#63556)
# Objective

Keep Git-specific diff-base knowledge in `GitStore`, where Git
operations are defined.

Related to FR-135.

## Solution

Give each `BufferDiff` its supported hunk operations. Keep editor hooks
limited to rendering custom controls.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- N/A
2026-09-01 15:52:33 +00:00
6d0f8c93d8 git_ui: Add multi-select to git panel for bulk stage, unstage, and discard (#60340)
Closes #26430
Complements: #52935 by Jacob Binnie

Enables multi-select in the Git Panel, following the Project Panel
rules.



https://github.com/user-attachments/assets/2892c1e2-3071-47f9-af1a-48e1c69dbb8a



**Core selection gestures:**

1. Click one file, shift+click a file deeper in the list: all files
between highlight.
2. Click one file, then ctrl/cmd+click another file: it joins the
selection; or removes it when selected.
3. Shift+down extends the selection from the current row; shift+up
shrinks it back and re-extends past the anchor.
4. Escape with a selection clears it and keeps focus; Escape again
toggles focus as before.
5. Plain click collapses selection to file and opens its diff;
double-click triggers the alternate open action.
6. Shift+click on a checkbox still performs the pre-existing range
staging.

**Bulk operation gestures:**

1. Select multiple files, press space: if any member is unstaged, all
become staged; press space again: all unstaged.
2. Right-click a file inside the selection: menu reads
Stage/Discard/Trash N files, depending on context.
3. Select multiple files, press delete: confirmation prompt. Mixed
selections: untracked = trashed, staged = unstaged.

**Folders, in tree view:**

1. Ctrl/cmd+click a folder row behaves like its checkbox does: selects
it as a unit, expands operations to descendants.
2. Folder rows inside a shift range join the selection. A collapsed
folder is selected including its hidden files.
3. The same directory under Tracked and Untracked is two independent
selections (so marks are section-qualified).
5. Plain click on a folder still expands/collapses it and clears the
selection.

**Implementation notes:**

1. Selection is stored as repo paths plus section-qualified tree keys to
survive status refreshes.*
2. Stale entries are pruned on rebuild, selection is cleared on active
repository change.
3. Range selection follows visual order in both flat and tree view.
4. Bulk operations batch into a single git operation.

\* Not sure if this is the best option for storing it.


**Why this is necessary**

- Multi-select has been an ongoing feature wish since 2025 with various
upvotes
- Current state of the art IDEs offer this (VSCode, IntelliJ, VS)
- It greatly increases efficiency using the diff panel


**Why is the PR from #52935 not enough?**

This PR builds on its approach. Thanks to @jacobbinnie. But I noticed a
few things:

- never clears the selection when the active repository changes
- a failed checkout or trash disappears silently
- hardcodes single-click = project diff and double-click = file diff,
ignoring the entry_primary_click_action setting
- its context menu still reads "Stage File" / "Discard Changes"
(singular)
- discard prompt always says "Discard" even for an all-untracked
selection that will actually trash files
- no shift+arrow range extension, no Escape to clear
- it skips directory rows entirely, in tree view you can't act on a
folder's subtree at all
- its range_select only ever accumulates, consecutive shift+clicks grow
the set and nothing shrinks it
- Uses Vec<RepoPath> on marks, linear contains scans -> This PR uses
HashSets, relevant for huge repos.
- doesn't ship any tests -> This PR covers the whole range with tests
too*

\* Tests dominate this PR (~850 lines). The actual feature sits around
400.

Release Notes:

- Added multi-select to the git panel

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
Co-authored-by: Jacob Binnie <jacob.b@linktr.ee>
Co-authored-by: Andrea Leone <andrealeone@hey.com>
2026-09-01 12:59:39 +00:00
Conrad Irwin 37083e77dd git_ui: Batch merge conflict anchor resolution (#63394)
Improves merge-conflict loading by resolving ordered conflict anchors
with a single excerpt sweep instead of restarting the excerpt scan four
times per conflict.

The pull request also adds `script/generate-merge-conflict-benchmark`,
which creates validated small, medium, or severe repositories with real
unresolved Git merges.

On the severe workload (128 files × 256 conflicts), anchor conversion
decreased from 483.5 ms to 5.9 ms, saving about 478 ms, or roughly 5% of
the total refresh.

Closes
https://linear.app/zed-industries/issue/FR-174/improve-git-panel-performance-for-large-merge-conflicts

## Testing

- `cargo test -p multi_buffer
test_ordered_buffer_anchor_ranges_to_anchor_ranges`
- `cargo test -p git_ui conflict`
- `./script/clippy -p multi_buffer -p git_ui`
- Generated and validated the small synthetic merge-conflict workload

Release Notes:

- Improved performance when opening large merge conflicts
2026-08-31 15:07:24 +00:00
Kirill Bulatov b6490c5fbd Stop re-resolving editorconfig sections on every language settings lookup (#63323)
Closes https://github.com/zed-industries/zed/issues/59689

Symbolicating the reporter's profile (21s of typing, Windows) showed
`Window::draw` taking 63% of the main thread at ~62 redraws/s (p95 draw
= 40ms), and 30.9% of the *entire* main thread inside
`EditorconfigStore::properties()`:
every `LanguageSettings` lookup — several per frame via
`DisplayMap::tab_size`, `MultiBuffer::language_settings`, indent guides,
and `LspStore::supports_range_formatting` — re-ran the full editorconfig
resolution (ancestor walk plus `ec4rs::Section::apply_to` over every key
of every section) and then cloned the whole `LanguageSettings` struct.
Real-world `.editorconfig` files carry hundreds of irrelevant keys
(`dotnet_*`, `ij_*`, ...), so the per-call map assembly dominated:
`RtlAllocateHeap` 7.3%, `memcmp` 7.0%, `memcpy` 6.6%,
`Properties::find_idx` 5.9% self time.

## Commit 1: resolve only the editorconfig properties Zed reads

- `EditorconfigStore::properties()` now applies only the 7 keys Zed
consumes (`indent_style`, `indent_size`, `tab_width`, `end_of_line`,
`max_line_length`, `insert_final_newline`, `trim_trailing_whitespace`)
instead of materializing every key of every matching section.
- Worktrees with no editorconfig at all now return `None` early instead
of allocating an empty `Properties` and forcing a `LanguageSettings`
clone on every lookup.
- Adds an `editor_render_with_editorconfig` benchmark: maximized window,
file-backed buffer at `src/app/components/editor_pane.ts`, a root
`.editorconfig` shaped after [the second
report](https://github.com/zed-industries/zed/issues/59689#issuecomment-5475124891)
(no `root = true`, a `[*]` section with ~3200 keys, 25 sections with
large `{...}` alternation lists) plus a 4-level nested chain, and a
typing workload (insert/delete + cursor moves).

```
main (f034409b6a):      time: [37.905 ms 38.005 ms 38.107 ms]
                        time: [38.069 ms 38.157 ms 38.248 ms]
this commit:            time: [2.8547 ms 2.8618 ms 2.8702 ms]
                        time: [2.8372 ms 2.8435 ms 2.8510 ms]
```

The candidate is ~13x faster.
GPUI frame report over the same workload: window draw p50 12.71 ms →
0.76 ms, p99 23.38 ms → 1.22 ms; frame budget overruns 556 → 0.

## Commit 2: cache resolved `LanguageSettings` per buffer

- `Buffer` and `BufferSnapshot` now hold `resolved_settings:
Arc<LanguageSettings>`, recomputed by a `SettingsStore` global observer.
- Global methods for retrieving the settings are still there, but buffer
only uses them for multi buffer's `language_settings_at` with an
injected language different from the buffer's primary; cold scopes such
as extension API, LSP workspace configuration, server startup still use
the global resolution

Same benchmark, same method, on top of commit 1 (alternated runs, quiet
machine):

```
commit 1:               time: [2.8547 ms 2.8618 ms 2.8702 ms]
                        time: [2.8372 ms 2.8435 ms 2.8510 ms]
this commit:            time: [1.6256 ms 1.6325 ms 1.6403 ms]
                        change: [-42.685% -42.270% -41.854%] (p = 0.00 < 0.05)
                        time: [1.6221 ms 1.6284 ms 1.6352 ms]
```

Window draw p50 0.76 ms → 0.47 ms, p99 1.22 ms → 0.69 ms, max 1.02 ms;
zero frame-budget overruns on both sides.
Combined, the benchmark's per-keystroke cost drops ~23x vs `main`
(37.9–38.2 ms → 1.62–1.64 ms).


Release Notes:

- Improved typing and rendering performance in projects that use
`.editorconfig` files.
2026-08-31 11:58:50 +00:00
DongandKirill Bulatov 7472da6de7 Add folder_indicator setting to show chevron and folder icon together (#62393)
# Objective

- Enable panels to show chevron and icon at the same time.
- Closes #8661

## Solution

- Replaces `folder_icon` with a new `folder_indicator` which converts
from a boolean to enum (`both`, `chevron`, `icon`) for the three display
cases

## Testing

- gpui and migration tests had been applied

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

### project panel

both | chevron | icon
--- | --- | ---
<img width="400" alt="both_project_panel"
src="https://github.com/user-attachments/assets/4c21e1a1-a7a4-4471-b7de-fe867373ddbd"
/> | <img width="400" alt="chevron_project_panel"
src="https://github.com/user-attachments/assets/a626a82e-e5b7-470d-9d93-ed5787dc83d6"
/> | <img width="400" alt="icon_project_panel"
src="https://github.com/user-attachments/assets/20f9c55e-87c4-477a-b4c9-b070d6e5a1db"
/>

### git panel

both | chevron | icon
--- | --- | ---
<img width="400" alt="both_git_panel"
src="https://github.com/user-attachments/assets/3dc166dd-9e63-4943-b803-df3f167876b6"
/> | <img width="400" alt="chevron_git_panel"
src="https://github.com/user-attachments/assets/8dfd2c10-3a68-439a-8019-4951b72e17d1"
/> | <img width="400" alt="icon_git_panel"
src="https://github.com/user-attachments/assets/d78a9938-91e7-4d39-a3c8-04647da67768"
/>

### outline panel

both | chevron | icon
--- | --- | ---
<img width="400" alt="both_outline_panel"
src="https://github.com/user-attachments/assets/1b58c679-0bea-4600-a8ac-e800b0e8d24c"
/> | <img width="400" alt="chevron_outline_panel"
src="https://github.com/user-attachments/assets/0a9358e4-ec89-40d8-8d5e-a53b784ed30a"
/> | <img width="400" alt="icon_outline_panel"
src="https://github.com/user-attachments/assets/d8bf5199-5a8c-4de0-b516-00247e6531a5"
/>



---

Release Notes:

- Added a `folder_indicator` setting that can show the disclosure
chevron and folder icon at the same time in the project, outline, and
git panels.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 20:11:28 +00:00
Jacob WolfandSmit Barmase 3ba893e4ac editor: Add file permalink support to tabs and the Project Panel (#62177)
# Objective

- Add file-level hyperlink support for opening and copying hyperlinks
for Git remote source control to project panel and tabs
- Unify the language for Git remote hyperlinks across blame, project
panels, and tabs to be similar to GitLens' definitions (which are
commonly used in VS Code)

## Solution

- Updated the Git crate to expose relevant metadata to surface new
options within the editor
- Added new options for `Open File on Remote` and `Copy Remote File URL`
to project panel/file explorer and file tabs
- Altered the blame UI options to be consistent with new labels / more
clear

## Testing

- Ran `cargo run` to boot app and manually smoke test (see proof below)
- Added unit tests for this change

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase



https://github.com/user-attachments/assets/d600ca4f-47e7-438c-90e1-f40124a606b4

---

Release Notes:

- Added options to open or copy whole-file permalinks from file tabs and
the Project Panel.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-08-26 18:21:33 +00:00
Kirill BulatovandKostia R 677e8174b5 Flush all persistence threads for the rest for various shutdown cases (#63213)
Follow-up to https://github.com/zed-industries/zed/pull/60477
Closes #25022

We have more places that need a similar synchronization before quitting
the app: restarts on update, reloading the workspace.

On top of it, two more findings:

* `on_app_will_quit` was redundant: the global `on_app_quit` hook
flushes a strict superset of the same tasks and runs before windows are
cleared, while the entity hook held only a weak handle and could never
flush the `Window`-dependent workspace state anyway.

* previously, shutdown was run as `cx.spawn`, yet main threads got
parked on app shutdown: now using `cx.background_spawn` instead

Release Notes:

- Improved data persistence during various app shutdown cases

---------

Co-authored-by: Kostia R <k-bx@k-bx.com>
2026-08-26 14:33:10 +00:00
Kirill BulatovandBennet Bo Fenner 6c6673e4a5 Fix shallow diffs causing a lot of computations (#63024)
For repositories with shallow mode enabled, before, Zed instantly loaded
diff changes which could be very large and CPU-demanding:


https://github.com/user-attachments/assets/5577730a-efef-424f-b749-501394a8b51f

Now, we show the following state instead of loading:

<img width="1728" height="1084" alt="after"
src="https://github.com/user-attachments/assets/03cc47fe-7074-4e8b-ba12-2fefa101377d"
/>

(the button allows to move on and do the load nonetheless)


Release Notes:

- Fixed shallow diffs causing a lot of computations

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-08-26 14:33:08 +00:00
Cole Miller 3bd76bb912 git_ui: Prevent crash when selecting collapsed sections (#63164)
## Summary

- Select the first Git panel entry from the visible row indices instead
of treating an entry index as a visible-row position
- Avoid selecting files hidden by collapsed sections in both tree and
flat views
- Add a regression test for collapsing the only populated section in
tree view with no active selection

Fixes ZED-AZ3
Fixes ZED-B0Z

Release Notes:

- Fixed a crash in the Git panel when collapsed sections were used in
tree view.
2026-08-24 20:30:19 +00:00
Kirill Bulatov a86d40eda5 Do not show useless toasts during recursive blaming (#63111)
Follow-up to https://github.com/zed-industries/zed/pull/62614

<img width="1728" height="1084" alt="bad"
src="https://github.com/user-attachments/assets/5fafb9cb-38be-44ba-b8a3-a33dc10106da"
/>

Properly disable actions instead of showing odd toasts and do nothing
when invoked without the prerequisites.

Release Notes:

- N/A
2026-08-23 19:29:43 +00:00
Ben Kunkle f5187eac10 git_ui: Add action to toggle diff base (#62966)
# Objective

- Make it easy to switch Git features between showing uncommitted
changes and all changes on the current branch.

## Solution

- Add `git::ToggleDiffBase`, which toggles the user setting between
`head` and `default_branch`.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Git: Added an action to toggle the diff base between HEAD and the
default branch.
2026-08-21 16:02:27 +00:00
Dino be775dbac2 git_ui: Prevent context menu binding flicker (#63021)
# Objective

Ensure that the bindings displayed in the Git Panel's context menu do
not change between the first and subsequent frames.

## Solution

Git panel context menus could briefly display bindings from the generic
`GitPanel` context before switching to the more specific `ChangesList`
bindings. This was especially noticeable with Vim mode enabled, where
"Stage All" changed from `ctrl-cmd-y` to `shift-x`.

Since `GitPanel::dispatch_context` relies on
`FocusHandle::contains_focused` to be `true` in order to add the `menu`
and `ChangesList` contexts it could fail on the first frame the context
menu is shown, as the menu's focus handle is absent from the previous
frame's dispatch tree when first focused.

The simplest fix in this case is to fallback to
`GitPanel::context_menu::is_some()` in case
`GitPanel::focus_handle::contains_focused` returns `false`.

## Testing

Tested both manually as well as updated an existing test to ensure that,
when the context menu is first focused, both the `menu` and
`ChangesList` context are still present, even if no frame is rendered.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
  <summary>Before</summary>

Notice how the "Stage All" binding changes from `ctrl-cmd-y` (macOS) to
`shift-x` (vim).


https://github.com/user-attachments/assets/1d2e2de5-dce4-422c-8d63-4bcd93375431
</details>

<details>
  <summary>After</summary>


https://github.com/user-attachments/assets/79e74c3f-8358-4e7c-8eb9-74fa36adde67
</details>

## Future Work

It's still possible for the bug to show up the first time the very first
time the context menu is actually opened, if the Git Panel was not
previously focused, that is, using `right-click` on the Git Panel while
the editor was focused, for example. I suspect this has to do with how
`Window::highest_precedence_binding_for_action_in` also relies on the
previous frame's dispatch tree, at which point the `GitPanel` was not
yet available in the context.

---

Release Notes:

- Fixed issue where the bindings shown in the Git Panel's context menu
would change after the first frame.
2026-08-21 14:37:51 +00:00
Finn Evers 36ef5aeb8d git_graph: Focus search editor on open (#63002)
Release Notes:

- The git graph and git history view will now focus the search editor on
initial focus
2026-08-21 10:36:13 +00:00
Neel 255880598d Switch from cargo-machete to cargo-shear (#62643)
This results in ~110 crates being removed, and some orphaned files also.

---

Release Notes:

- N/A

Signed-off-by: Neel <neel@zed.dev>
2026-08-20 10:08:48 +00:00
Enzo GAZZOLIandKirill Bulatov 1155a5becd Render control characters in tab titles and project panel entries (#62875)
# Objective

Fixes #62664

File names may contain control characters (`\n`, `\r`, `\t`, …) on most
platforms. Zed rendered them verbatim, so a file named `notes\ndraft.md`
broke the layout of its tab and of its project panel entry instead of
showing a readable name. The same held anywhere else a name reached the
screen without going through `Label::single_line`.

## Solution

The substitution lives in one shared place,
`ui::utils::replace_control_characters`, reached through
`Label::single_line`. `\n` keeps rendering as the `⏎` Zed already used,
so nothing that renders correctly today changes; every other C0 control
character maps onto the Unicode "Control Pictures" block by a single
rule (`U+2400 + code point`), giving `␉` for tab and `␍` for carriage
return. `DEL` maps to `␡`. C1 controls are left alone, having no
equivalent there.

Where that is wired in:

- **`Label::single_line`** — replaces its previous `\n`-only
substitution. The project panel already used it everywhere, including
folded directory components, so the panel is fixed by this alone.
- **Editor tabs** and the **default `Item::tab_content`**, neither of
which called `single_line`.
- **Terminal tab titles**, which render through their own `tab_content`.
Those titles come from OSC escape sequences, so the control characters
in them are attacker-controlled.
- **`HighlightedLabel::single_line`**, which never substituted anything
— not even `\n`. See below.
- **The file finder**, for both the file name and the path.
- **Nine `tab_content` overrides in git_ui**, by deleting them.
- **`HighlightedMatchWithPaths`**, for both the match label and its
paths — it backs the tab switcher and the outline panel, among others.

### `HighlightedLabel` needs its offsets moved, not just its text

Its highlight indices are byte offsets, and every stand-in is wider in
bytes than the character it replaces, so the offsets have to move with
the text. Left alone they index into the middle of a character, and
`highlight_ranges` slices the string at exactly those offsets — which
panics in release builds too. The constructor's `debug_panic!` does not
cover this, since `single_line` runs after construction.

So `replace_control_characters_remapping_offsets` substitutes and remaps
in one pass, over an old-to-new byte offset table built the way
`ensure_uniform_list_compatible_label` does it in `lsp_store`. This also
fixes the call sites that already asked for a single line, including the
branch picker and the tabular column filter values.

### Deleting the git_ui overrides

Nine files replicated the default `Item::tab_content` verbatim except
for the colour, hardcoding `selected ? Default : Muted` instead of
`params.text_color()`. Deleting them lets those tabs inherit the fixed
default, and fixes a second bug along the way: none of them dimmed when
the pane lost focus. Titles and icons are unaffected — they come from
`tab_content_text` and `tab_icon`, which the default calls.
`git_graph.rs` already did it this way.

### Tabular column headers

These never went through a `Label` at all: the raw `SharedString` was a
child of a `div`. They now display stand-ins, while right-click-copy
still yields the real column name.

Two notes for reviewers:

- Both helpers avoid allocating when there is nothing to replace, so the
common path is untouched. The previous `self.label.replace('\n', "⏎")`
allocated a `String` on every render for every label — including every
visible project panel entry, every frame.
- Every stand-in is exactly one character, so character offsets are
preserved and the existing `truncate_and_trailoff` math on tab titles
stays correct.

## Testing

- Unit tests cover both helpers: each control character's substitution,
repeated occurrences, multi-byte characters (accents, emoji), the
borrow-vs-own behaviour, the preserved character count, C1 passthrough,
and — for the remapping — offsets before, at and after a replacement,
offsets at and past the end, and the invariant that every remapped
offset lands on a character boundary.
- Unit tests cover `Label::single_line` and
`HighlightedLabel::single_line`, the entry points every call site uses.
`highlighted_label.rs` had no tests before.
- `cargo test -p ui -p file_finder -p workspace -p project_panel -p
git_ui -p git_ui_core -p terminal_view -p tabular_data_preview` passes
(774 tests), as do `cargo clippy` and `cargo fmt --check`.
- No existing test changes behaviour: tests assert on
`tab_content_text`, which is untouched; only rendering paths changed.
- Verified manually on macOS (aarch64) — see Showcase.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — none added
- [x] The content adheres to Zed's UI standards
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

A directory holding `report<TAB>table.csv`, `notes<LF>draft.md`,
`carriage<CR>return.txt` and a normally named `normal.txt`, all four
open as tabs.

**Before**


![before](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/before.png)

**After**


![after](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/after.png)

Three things change:

1. **The `notes<LF>draft.md` tab** is the clearest one. Before, the
literal newline splits the tab across two lines — `notes` above
`draft.md` — distorting the whole tab bar. After, it stays on one line.
2. **`carriage<CR>return.txt` in the project panel** renders as
`carriagereturn.txt` before: the `\r` is completely invisible, so the
name reads as one word and there is no way to tell a character is there.
After, it renders as `carriage␍return.txt`.
3. **`report<TAB>table.csv`** shows a bare gap before, indistinguishable
from a space. After, it renders as `report␉table.csv`.

Note that `notes<LF>draft.md` looks the same in the project panel in
both shots: that entry already called `single_line`, which already
handled `\n`. That is precisely the asymmetry this PR removes.

### File finder

Before, the newline also breaks the list itself — the
`notes<LF>draft.md` row grows to two lines and overlaps the row beneath
it.

**Before**

![file finder
before](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/finder-before.png)

**After**

![file finder
after](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/finder-after.png)

Searching for `table` exercises the offset remapping, the match falling
after the control character:

**Before**

![match
before](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/match-before.png)

**After**

![match
after](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/match-after.png)

One thing this PR does **not** cover: the breadcrumb below the tab bar
still renders the raw tab character, as it goes through a different
path.

## Release Notes:

- Fixed file names containing control characters, such as tabs and
newlines, rendering unreadably in tabs, the project panel, the file
finder, the tab switcher and terminal tab titles.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-19 21:10:56 +00:00
Dino 7f6677e795 git_ui: Improve discard tracked changes context menu option (#62872)
# Objective

Ensure that the "Discard Tracked Changes" option shown in the context
menu that can be opened in the Git Panel's "Changes" tab is only
displayed when it can actually be used. Currently, it is also shown when
the "Unstaged" section has tracked files, even though clicking will not
actually do anything.

Besides fixing that, the changes in this Pull Request also update how
the "Discard Tracked Changes" action works when picked from a subfolder,
with only changes in that subfolder being discarded.

Closes #62535

## Solution

- Update `git_ui::git_panel::git_panel_context_menu` to now accept a
`has_staged_tracked_changes` boolean, in order to be able to
differentiate between the panel having tracked changes, be it unstaged
or staged, and specifically staged tracked changes, as we only want the
"Discard Tracked Changes" to be enabled and affect staged changes.
- Add `git_ui::git_panel::GitPanel::directory_context_descendants` in
order to be able to obtain the list of entries under the directory where
the context menu was deployed, if any.
- Update `git_ui::git_panel::GitPanel::restored_tracked_files` to
leverage the new `directory_context_descendants` method, ensuring that
only the entries under the context menu's directory are restored,
instead of all staged tracked files

## Testing

Tested both manually, as shown in the "Showcase" section, as well as
introduced a new test for these changes –
`git_ui::git_panel::tests::test_directory_discard_tracked_changes`.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
  <summary>Before</summary>


https://github.com/user-attachments/assets/24bbb23c-78fb-4fe3-82da-d8bcaec0d79c
</details>

<details>
  <summary>After</summary>
  

https://github.com/user-attachments/assets/70db9189-9122-4ee4-b03f-648935c4f0a4
</details>

---

Release Notes:

- Fixed the "Discard Tracked Changes" option being enabled for files in
the "Unstaged" section in the Git Panel
- Updated the "Discard Tracked Changes" option to only affects files in
the directory where the context menu was deployed
2026-08-19 14:52:29 +00:00
Dino 942b9b9803 git_ui: Refactor git panel entry collapse (#61846)
# Objective

Standardize the behavior of collapsing/expanding entries between Project
Panel and Git Panel. At the time of writing, using `left` or `right` on
the Project Panel would find the nearest parent directory and collapse
it while, on the Git Panel, that will only happen if the directory is
already selected, otherwise it'll select the previous entry instead.

## Solution

Update `git_ui::git_panel::GitPanel::collapse_selected_entry` in order
to always try to find the nearest expanded directory, regardless of the
selected entry, and then collapse it and select it.

The default keymap for Vim/Helix has also been updated to ensure that
`h` and `l` work for collapsing or expanding entries, similar to what
already happens in Project Panel.

## Testing

Tested both manually, as can be seen in the "Showcase" section as well
as added a new test for these changes,
`git_ui::git_panel::tests::test_collapse_selected_entry` .

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
  <summary>Before</summary>


https://github.com/user-attachments/assets/2fd8db03-155a-4406-a190-17a1958dda11
</details>

<details>
  <summary>After</summary>


https://github.com/user-attachments/assets/f64bd584-a3c2-4a33-b95a-2547c8b721d2
</details>

---

Release Notes:

- Improved `git panel: collapse selected entry` in order to find and
collapse the nearest parent directory, similar to the Project Panel.
- Added support for using `h` and `l`, in Vim/Helix mode, to collapse
and expand entries in the Git Panel.
2026-08-19 10:06:46 +00:00
John YaniandKirill Bulatov 9fa09ccc24 Remove deprecated std::usize import from uniform_list.rs (#62841)
<img width="993" height="370" alt="image"
src="https://github.com/user-attachments/assets/15e3a185-3328-4069-ad86-21d29f647f83"
/>

# Objective

- using `std::usize` currently is a warning, but it's a hard fairule in
rust nightly
- gpui-web requires rust nightly
- https://doc.rust-lang.org/std/usize/index.html
 
## Solution

- remove std::usize import, it would be used a primitive type

## Testing

-
https://github.com/iamnbutler/gpui-unofficial/actions/runs/32189970651/job/95882109895#step:8:753

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- N/A

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-18 22:41:54 +00:00
ebd0e0b3a0 Fix the git_gutter_width setting (#62704)
# Objective

- Fixes #62645
## Solution
Since the default value isnt constant.It now has two options 1) Default
2) custom where user inputs a value.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

## Showcase
<img width="798" height="361" alt="Screenshot 2026-08-16 at 4 29 54 PM"
src="https://github.com/user-attachments/assets/0af302f6-4733-4a23-9e93-1f9d98dd772f"
/>

<img width="798" height="92" alt="Screenshot 2026-08-16 at 4 30 13 PM"
src="https://github.com/user-attachments/assets/2c87c2a3-2947-45c7-8495-f6a0b36dd793"
/>

Release Notes:

- Added git_gutter_width setting to the Settings UI with default
(font-size-scaled) and custom (fixed pixel width) options

---------

Co-authored-by: Abdul Rafey Ahmed <abdul.r@hyperverge.co>
Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-18 12:40:18 +00:00
tidely 12f3994269 git_ui: Dismiss askpass prompts when requests end (#61292)
# Objective

Fixes #47623

- When authenticating git commands using a security key through
`askpass`. The modal which asks for user presence does not get dismissed
even after the git command finishes successfully.

## Solution

Add a cancellation task to the `AskPassModal`, which gets dropped when
the requested operation completes. This cancellation task then dismisses
the modal.

## Testing

- I've tried authentication through `askpass` using my own security key.
Testing both successful and failed authentication.
- I've added tests which confirm that the modal gets dismissed when a
task is cancelled, and that the cancellation is triggered when
`ask_password` Task gets dropped.

Willing to pair on review, message me on Slack. Showcase video left out
because it would leak private information.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed authentication prompts not dismissing automatically when using
security keys with ssh
2026-08-18 10:02:20 +00:00
PriyadharshanandChristopher Biscardi f652da59e8 Added Tracked , Staged options to stash (#62254)
# Objective

Closes #62252 

The Git Panel could only stash *everything* — `Stash All` runs
`git stash push --include-untracked`, sweeping tracked edits and
untracked files
into a single entry. There was no way to stash a subset, so the common
workflows
of "park my tracked edits but keep my new scratch files" and "park what
I've
staged and keep working on the rest" required dropping to the terminal.

## Images

<img width="389" height="358" alt="Screenshot 2026-08-10 at 3 10 50 PM"
src="https://github.com/user-attachments/assets/18e4c943-e320-4802-ada8-59e54bf4cefd"
/>

<img width="504" height="462" alt="Screenshot 2026-08-10 at 3 10 37 PM"
src="https://github.com/user-attachments/assets/783237eb-980d-47bc-a0f5-17b03a23a60c"
/>






## Solution

Add two stash variants alongside `Stash All`, surfaced in the Git
Panel's
overflow menu based on how the list is currently grouped, so the menu
mirrors the
sections the user can actually see:

| Group By | Stash entries offered |
| --- | --- |
| None | Stash All |
| Tracked & Untracked | Stash All, **Stash Tracked** |
| Staged & Unstaged | Stash All, **Stash Staged** |

- **`git::StashTracked`** stashes tracked changes and leaves untracked
files in
place. It reuses the existing pathspec plumbing
(`Repository::stash_entries`),
  filtering the status list down to the paths to stash.
- **`git::StashStaged`** stashes the index only, leaving unstaged
changes in
place. This *cannot* be expressed as a pathspec — a partially staged
file would
have its unstaged hunks stashed too — so it needs git's own `--staged`
flag.
  That meant a new `GitRepository::stash_staged` backend method and an
`optional bool staged` field on `proto::Stash` so remote projects work
too.

Both actions are unbound by default and are dispatchable from the
command palette
when the panel is focused.

One subtlety worth calling out for review: `Stash Tracked` filters on
`FileStatus::is_created()`, not `is_untracked()`. Staging a new file
flips it from
`Untracked` to `Tracked { Added }`, but the panel still lists it under
**Untracked** — using `is_untracked()` meant staged-new files were
silently
stashed. `is_created()` is the same predicate the panel uses to build
that section
(`git_panel.rs`), so the menu item and the list can no longer disagree.

This branch also includes a separate commit adding **per-section
staging**
(`git::StageSection` / `git::UnstageSection`) — right-click a file to
stage or
unstage every entry in its section. Happy to split that into its own PR
if
preferred.

## Testing

Manually tested on macOS against a scratch repo with a mix of states:
modified
tracked files, untracked files, and untracked files that had been
staged.

- `Stash Tracked` with tracked edits + untracked files → only tracked
edits
  stashed; untracked files remain.
- `Stash Tracked` with untracked files **staged** → they remain, staged.
This was
  broken in an earlier revision and drove the `is_created()` fix above.
- `Stash Staged` with one file staged and another modified-but-unstaged
→ only the
  staged file is stashed; the unstaged edit and untracked files survive.
- `Stash Pop` round-trips both cases back to the original state, with no
conflicts.
- Menu contents and disabled states verified in all three Group By
modes.
- Per-section staging covered by a new unit test,
  `test_stage_section_scopes_to_selected_section`.

Not covered by automated tests: the stash actions themselves.
`FakeGitRepository`
leaves every stash method `unimplemented!()`, so stash behavior isn't
reachable
from GPUI tests today — consistent with the existing untested
`StashAll`. Adding
fake-repo stash support looks like a worthwhile follow-up but felt out
of scope here.

Reviewers on non-macOS platforms: nothing here is platform-specific.
Note that
`Stash Staged` requires **git 2.35+** (Jan 2022) for `git stash push
--staged`;
older git surfaces a clear error toast rather than failing opaquely. The
remote
path (`proto::Stash.staged`) has not been exercised against a live
collab session.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Added `Stash Tracked` and `Stash Staged` options to the Git Panel,
letting you stash only tracked changes or only staged changes.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-08-18 05:36:16 +00:00
Ayush f3b8308c83 git_ui: Enable navigation for single-hunk diffs (#62615)
## What

Keep the hunk navigation controls available when a diff contains one
hunk, so users can return to it after scrolling away. This applies to
solo, staged, unstaged, and project diff views.

## Why

The controls were only rendered when `hunk_count > 1`, even though the
existing navigation actions already wrap and recenter a single hunk.

## How

Render the previous and next hunk controls whenever `hunk_count > 0`,
reusing the existing navigation actions.

Closes #62469

## Testing

- `cargo +stable-x86_64-pc-windows-gnu test -p git_ui --lib` — 130
passed.
- `cargo +stable-x86_64-pc-windows-gnu build -p zed -j 1` — passed.
- `rustfmt --edition 2024 --check` on the four changed files — passed.
- `git diff --check` — passed.
- Manually verified with the branch-built Zed on Windows: opened a
tracked file with exactly one diff hunk, expanded the context, scrolled
below the hunk, and used **Go to Previous Hunk**. The view returned to
the changed line.

## Showcase


https://github.com/user-attachments/assets/e7b63030-50ad-4536-8266-13987ed85f3d

## Self-Review Checklist

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://zed.dev/docs/development/ux-ui) and [icon
guidelines](https://zed.dev/docs/development/ui-icons))
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Enable "Go to Previous Hunk" and "Go to Next Hunk" buttons even if
there's a single diff hunk.
2026-08-17 18:16:10 +00:00
hvckandCole Miller 75c80abb31 git: Decode non-UTF-8 blobs for project diffs (#60821)
## Summary

Fixes #56449.
Related to #16965.

Zed’s Git panel and Project Diff build UI diffs from `language::Buffer`
diff bases loaded through the Git backend. Git blob loading previously
converted bytes with `String::from_utf8(...).ok()`, so legacy-encoded
blobs were treated as missing and the whole worktree file appeared newly
added.

This follows the same encoding path used for worktree buffers:

- move shared byte decoding and encoding into `language`
- keep Git blob, revision, and index APIs byte-oriented with `Vec<u8>`
- decode diff bases and index contents in `GitStore`, where
`language::Buffer`s are created
- encode index writes using the open buffer’s encoding and BOM so
partial staging does not rewrite the file as UTF-8
- keep worktree loading and saving on the same shared implementation

Regression coverage includes Windows-1251 decoding/encoding,
UTF-8/UTF-16 BOM preservation, raw Windows-1251 Git blob loading, and a
`BufferDiffSnapshot` assertion that a one-line CP1251 edit produces one
modified-line hunk instead of a full-file rewrite.

This does not run Git `textconv` commands. It fixes the reported
legacy-encoding case without executing repository-configured commands or
modifying working files on disk.

## Testing

- `cargo test -p language file_content::tests --locked`
- `cargo test -p git repository::tests::test_load_revisions --locked`
- `CARGO_INCREMENTAL=0 cargo test -p project
git_store::tests::test_decode_git_text_windows_1251_one_line_change
--locked`
- `CARGO_INCREMENTAL=0 cargo test -p project --test integration
test_restaging_hunk_after_optimistic_unstage --locked`
- `CARGO_INCREMENTAL=0 cargo check -p project --tests --locked`
- `CARGO_INCREMENTAL=0 cargo check -p git_ui --tests --locked`
- `cargo fmt --all --check`
- `git diff --check`

## Suggested .rules additions

- N/A

Release Notes:

- Fixed Git panel and Project Diff rendering for legacy-encoded text
files whose Git blobs are not valid UTF-8.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-08-17 01:47:11 +00:00
Tai NguyenandCole Miller 8fd8efd105 git_ui: Fix Trash Untracked Files with many files (#61602)
Release Notes:

- Fixed Trash Untracked Files bailing out early with many selected files
when trashing one file failed.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-08-16 23:19:39 +00:00
AbdAlRahman Gad 437fe0f797 git_ui: prevent branch name overflow in git details pane (#62665)
# Objective

- prevent branch name overflow in git details pane
- Fixes #62526 

## Solution

- set min width
- add tooltip for readability

## Testing

- manual testing

## Self-Review Checklist:

- [X] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [X] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

## Showcase
### before
- 
<img width="670" height="205" alt="image"
src="https://github.com/user-attachments/assets/26716b50-6f09-40c1-bec5-d78bd913d4ec"
/>

- No tooltip

### After
- 
<img width="499" height="203" alt="image"
src="https://github.com/user-attachments/assets/3eee21e8-f9e8-4c30-a21d-0c23bf25c9de"
/>

- Tooltip: 

<img width="609" height="364" alt="image"
src="https://github.com/user-attachments/assets/822d784d-889e-4d26-b8e6-de46f8206569"
/>

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-08-15 15:13:04 +00:00
Kirill Bulatov c1dab7a0d3 Support blaming parent revisions (#62614)
Closes https://github.com/zed-industries/zed/discussions/42583

Adds more tooltip entries and `editor::BlameRevision`,
`editor::BlamePreviousRevision` actions to use.
Started to highlight gutter blame entries that belong to currently
annotated commit.


https://github.com/user-attachments/assets/ba754e0b-6431-407c-8d79-2f8b0324fde1


Release Notes:

- Supported blaming parent revisions
2026-08-14 20:24:13 +00:00
Toru NayukiandKirill Bulatov fa19fe3c5c project: Don't let a canceled caller leak a loading worktree forever (#61009)
# Objective

`WorktreeStore::find_or_create_worktree` inserts the shared
worktree-creation task into `loading_worktrees` and relies on the task
it returns to each caller to remove that entry once creation resolves.
But the creation task keeps running through the clone the map itself
holds, while the map cleanup lives only in the callers' returned tasks.

If every caller is cancelled before creation resolves, the resolved task
stays in `loading_worktrees` forever, retaining the `Entity<Worktree>`
captured in its result (a `Shared` task memoizes its output). Such a
worktree can never be released: `remove_worktree` only unlists it, so
its background scan keeps running and its snapshot keeps growing for the
lifetime of the window. The stale entry also keeps
`initial_scan_complete` permanently `false` (that flag is
`loading_worktrees.is_empty() && …`).

Callers are cancelled routinely — worktree creation is async and can
take seconds on a large tree, while the tasks awaiting it are owned by
UI that the user can close at any time (a tab or pane, a debugger panel
resolving a path, an agent session, or the whole window). See the
existing note in `crates/zed/src/zed.rs` that external-file worktrees
are "released on file close".

Observed in the wild: a home-directory worktree removed from the project
kept scanning for hours and grew Zed past 45 GB; neither removing the
folder nor ending the agent session freed it — only quitting Zed. (The
scan-amplification half of that incident is #60988.)

## Solution

Spawn the map cleanup as its own detached task, next to the map
insertion, so a loading entry always leaves `loading_worktrees` when
loading resolves regardless of what happens to the callers. The returned
per-caller task is unchanged apart from no longer owning that cleanup.

## Testing

- Added `test_worktree_released_when_creation_caller_is_cancelled`: it
requests a worktree, drops the returned task immediately (as a cancelled
caller would), lets creation complete, removes the worktree, and asserts
the entity is released. It fails on `main` and passes with this change.
- Full worktree-related project integration suite is green (45/45).

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed a memory leak where a worktree whose creation was requested by a
since-cancelled task (e.g. a folder opened as its owning
tab/panel/window closed) could never be released, leaving its background
scan running and its snapshot growing for the lifetime of the window.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-12 18:13:37 +00:00
PriyadharshanandChris Biscardi 1d8ba864ae Add optional message support to git stash (#62439)
Show a modal when invoking the stash action to allow users to provide an
optional custom message for the stash entry.

Closes #62430 


# Image

<img width="1622" height="1106" alt="Screenshot 2026-08-10 at 9 14
00 PM"
src="https://github.com/user-attachments/assets/0d26dac2-919d-4bb1-b6a7-433ceff18955"
/>

<img width="1622" height="1106" alt="Screenshot 2026-08-10 at 9 14
11 PM"
src="https://github.com/user-attachments/assets/896b68ff-999f-4ec9-a6a4-e0e7a6867286"
/>



# Objective

Zed's stash action runs `git stash push --quiet --include-untracked --`
with no `-m`, so every stash is labelled with git's auto-generated `WIP
on <branch>: <sha> <subject>`. That text describes the commit you were
sitting on, not what you stashed — so two stashes taken from the same
commit are indistinguishable.

This undercuts the stash picker (`git::ViewStash`), which lists entries
as `#<index>: <message>` and fuzzy-searches over exactly that string.
The search box already exists; there is just nothing meaningful to
search, because every candidate is a variation of the same
auto-generated line.

## Solution

`git::StashAll` now opens a single-line modal ("Optionally provide a
stash message") before stashing.

- Confirming with text passes `--message <text>` to `git stash push`.
- Confirming with the field empty omits the flag entirely, keeping git's
default description — so the prompt is a one-keystroke pass-through and
existing muscle memory still works.
- Cancelling aborts the stash, so the prompt doubles as a confirmation
step.

Implementation:

- `StashMessageModal` (`Editor::single_line`) in `git_panel.rs`, toggled
from `GitPanel::stash_all`. `menu::Confirm` trims the input and maps
empty to `None`.
- `message: Option<String>` threaded through `Repository::stash_all` →
`stash_entries` → `GitRepository::stash_paths`. The flag is appended
before the `--` separator so a message is never parsed as a pathspec.
- New `message` field on the `Stash` proto message, so remote and collab
projects behave identically.

One non-obvious detail: the modal is opened via `cx.defer_in` rather
than inline. `git::StashAll` is registered on the workspace
(`git_ui.rs`) as well as on the panel element, and
`Workspace::register_action` dispatches while `Workspace` is leased — so
opening the modal inline re-enters that update and hits GPUI's
`double_lease_panic`. This only reproduces when focus is *outside* the
Git Panel, which makes it easy to miss.

`Option<String>` rather than `String` is deliberate: `--message ""`
produces a blank stash description, which is strictly worse than git's
default.

## Testing

Manually verified the modal in a local build on macOS: the prompt
appears on `git::StashAll`, accepts a message, and the named entry shows
up in the stash picker.

Also verified at the git level by replaying the exact argument vector
`stash_paths` builds against a scratch repo with mixed staged / unstaged
/ untracked changes:

| Case | Result |
|---|---|
| `stash push --quiet --include-untracked --message "my named stash" --
<paths>` | `stash@{0}: my named stash`; worktree clean, untracked file
included |
| same, without `--message` | `stash@{0}: <sha> <subject>` — git's
default text |
| `--message "x" --` with no paths (clean repo) | exit 0, no stash
created — the empty pathspec does **not** stash everything |

`cargo fmt --check` clean, `./script/clippy -p git -p fs -p project -p
git_ui` passes with `--deny warnings`, and the existing suites pass
(`cargo test -p project -p git_ui`, 436 tests).

Worth a reviewer's attention: trigger `git::StashAll` with focus in the
**editor** rather than the Git Panel. That routes through the workspace
action registration and is the case the `cx.defer_in` deferral exists to
keep from panicking.

No new automated tests — the behavior is testable with the existing
`git_panel.rs` harness (`init_test`, `GitPanel::new`) if reviewers would
prefer coverage over a manual check.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — n/a, no unsafe
added
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior — no new tests; see Testing
- [x] Performance impact has been considered and is acceptable — one
extra process argument; no new work on any hot path


---

Release Notes:

- Added an optional stash message prompt when stashing changes
`

---------

Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
2026-08-11 04:38:21 +00:00
Sathwik Chirivelli 077d3c3581 git_panel: Add collapsable sections (#62441)
# Objective

- Make Git Panel grouping sections collapsible so users can hide
sections they are not currently interested in.
- Support collapsible sections when grouping changes by tracking and by
staging.
- Provide a clear visual indicator showing whether each section is
expanded or collapsed.

## Solution

- Added per-section collapsed state to the Git Panel.
- Made grouping headers clickable to toggle their section between
expanded and collapsed.
- Added chevron indicators that point down when expanded and right when
collapsed.
- Applied the behavior to both flat and tree views.
- Kept the stage/unstage checkbox independent from the header collapse
interaction.
- Ensured a previously collapsed Tracked section does not hide files
after switching to Group by None.

## Testing

- Ran `rustfmt --edition 2024 crates/git_ui/src/git_panel.rs --check`.
- Ran `cargo check -p git_ui`.
- Ran `cargo test -p git_ui`:
  - 129 tests passed
  - 0 tests failed
- Ran `git diff --check`.
- Attempted `./script/clippy -p git_ui` twice. It produced no lint
diagnostics but did not finish compiling the release, all-targets,
all-features dependency graph within the available timeout.
- Manually verify by selecting both grouping modes in the Git Panel and
clicking each section header in flat and tree views. Confirm that:
  - The section contents are hidden and restored.
  - The chevron updates to reflect the current state.
  - Clicking the stage/unstage checkbox does not collapse the section.
  - Switching to Group by None does not leave tracked files hidden.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase



https://github.com/user-attachments/assets/77ec4c88-4a6d-4e49-ac9f-ddbf80e724ca


---

Release Notes:

- Improved Git Panel organization by allowing grouped change sections to
be collapsed
2026-08-11 04:01:48 +00:00
狐狸 4043c82956 git_panel: Add copy path actions to the context menu (#62352)
# Objective

When developing remotely, when I close the uncommitted changes tab, I
need some time to load before I can copy the path. Or have to switch to
the project panel to find the specific file. All of this is annoying, so
I added a copy path action to the git panel's context menu and key
bindings consistent with the project panel.

## Solution

Already described in the Objective section.

## Testing

I wrote a unit test and tested it manually.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<img width="411" height="535" alt="showcase"
src="https://github.com/user-attachments/assets/a17e7633-eb92-4737-aa30-958fe58bb99f"
/>
<img width="717" height="427" alt="showcase"
src="https://github.com/user-attachments/assets/d067e892-17de-4527-ac20-16cad6f38015"
/>


---

Release Notes:

- Added "Copy Path" and "Copy Relative Path" actions to the Git Panel's
context menu
2026-08-10 22:42:22 +00:00
Kirill Bulatov 3692029a80 Bump rustc to 1.97 (#62395)
Release Notes:

- N/A
2026-08-09 22:29:52 +00:00
Piotr Osiewicz ff50948537 deps: Bump pathfinder_simd & fix upcoming rustc warnings (#62170)
While building Zed with nightly rustc I've noticed it doesn't compile
because of good old pathfinder_simd. It also emits a bunch of warnings
about use of f64 literals where f32 is expected, so I've fixed them - it
should make future upgrades more straightforward.
2026-08-07 10:16:57 +00:00
feeiyu 4be749399d git_panel: Fix focus navigation across Changes and History (#62215)
# Objective

Fix several Git panel focus issues:

- Directional navigation could not move focus into the History tab.
- History focus state was not updated when the panel received focus.
- Switching back to Changes could leave focus on the panel instead of
the commit editor.

Fixes #62211


## Solution

- Use the Git panel root as the activation focus target when History is
active.
- Reuse the panel's focus handle for focus events.
- Use the appropriate activation target when switching tabs.


## Testing

- Add a regression test
`test_history_tab_pane_navigation_focuses_rendered_panel` for navigating
between the editor and History.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

after fix:

[2026-08-05
22-45-38.webm](https://github.com/user-attachments/assets/fdb3f87a-f1af-4ae1-95f7-0d61acfb3095)



---

Release Notes:

- Fixed directional focus navigation into the Git panel's History tab.
2026-08-06 06:38:10 +00:00
Albert Bogusz 8f0161b3c2 Use correct provider icons for extension repository links (#58108)
Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments (N/A)
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

I was unable to find an issue or PR which mentions this.

Extensions with non-GitHub repository links always use the GitHub icon,
which is inconsistent with the changes merged in #44738 and #57500. This
change makes `extension_ui.rs` use the Git hosting provider registry to
determine these icons. Below is a preview of the change:

<div align="center">
    <img
        width="450"
        alt="Preview"

src="https://github.com/user-attachments/assets/e35f0eed-de54-48f9-824d-8a5b9bfc596f"
    />
</div>

Release Notes:

- Improved extension repository links to show provider-specific icons.
2026-08-04 15:14:33 +00:00
Kirill Bulatov 01961bef59 Speed up cargo build -p zed compilation (#62059)
Splits the crate graph.
Before, the compilation graph: `editor → picker_preview → search →
project_panel → open_path_prompt → recent_projects → title_bar →
collab_ui → zed`
After, the compilation graph: `editor → picker_preview → search →
agent_ui → sidebar → zed`

With sccache disabled and project fully built, `touch
crates/editor/src/editor.rs` and `cargo build -p zed` took time
Before (0500fd9ee9): 13.19s
After: 11.85s (-10.2% speed up)

Each commit contains a separate compilation instructions, and a test in
the final commit.
The main approach is to split coupled crates and replace them with
`zed_actions` and move some shared functionality into `git_ui_core` new,
shared module.

I've also tried to add a test to prevent common pitfalls, but not sure
I'm happy with the end result — can remove it if it looks too synthetic.

Release Notes:

- N/A
2026-08-01 19:42:37 +00:00
Mikayla MakiandBen Kunkle 0500fd9ee9 git: Add diff_base setting for showing changes since the default branch (#61501)
# Objective

Let git indicators — the editor gutter, file colors, and `git::Diff` —
show all changes on the current branch relative to its merge base with
the default branch, instead of only uncommitted changes.

Supersedes #60398; thanks to @samuelcolvin for the original
implementation and motivation.

Closes FR-135

## Solution

- New `git.diff_base` setting (`"head"` | `"default_branch"`), applied
live and toggleable per session from the editor controls menu ("Diff
Against Default Branch").
- Statuses come from a real merge-base-to-worktree tree diff (`git diff
--merge-base`), so local edits that revert branch changes correctly show
as unchanged.
- `GitStore` shares one `DiffBufferList` per repository with the Branch
Diff view; `repo_snapshots` and `project_path_git_status` keep returning
index/worktree truth, while display surfaces use separate `display_*`
APIs.
- `BufferDiff` now records what its base is (`DiffBaseKind`); hunks
whose base isn't HEAD are read-only in the gutter — stage/restore
buttons and keybindings are inert, so committed work can't be silently
rewritten.
- `git::Diff` follows the setting; new `git::DiffHead` always opens the
HEAD diff; `git::BranchDiff` is renamed `git::DiffBranch` (deprecated
alias kept).

Tradeoffs / known limitations:

- Hunk-level staging is unavailable while in `default_branch` mode
(whole-file staging via the git panel still works). Staging just the
uncommitted sub-ranges of a branch hunk is a follow-up.
- Remote hosts running an older server ignore the new
`GetTreeDiff.includes_worktree` proto field and degrade to
committed-changes-only branch diffs.
- Repositories with no resolvable default branch fall back to
HEAD-relative behavior; a failed first resolution retries on the next
branch-list change.

## Testing

- Real-git-repo tests for the merge-base-to-worktree diff's edge cases:
files recreated after index deletion, committed deletions recreated on
disk, and symlinks.
- GPUI tests for status semantics (a branch change reverted on disk
shows clean), `git::Diff` routing, live setting changes, and read-only
hunk enforcement (restore/stage leave buffer and index untouched).

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Git: Added a `git.diff_base` setting (`"head"` or `"default_branch"`)
that makes the editor gutter, file colors, and diff view show all
changes on the current branch since its merge base with the default
branch, instead of only uncommitted changes.

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-07-31 19:57:13 +00:00
Lukas Geigeranddino b9e8d99a71 git: Do not re-compute git_access for .git/ changes (#60503)
This builds on #59521 and addresses @dinocosta's comment
https://github.com/zed-industries/zed/pull/59521#pullrequestreview-4563460240

Looking at it again, I think
https://github.com/zed-industries/zed/pull/59521/commits/e7ed02cc4963868632ba97a1fb09f1b398d3b22b
was too conservative. Re-running the access check on every commit,
stage, or checkout, doesn't really make sense. Access depends on `.git`
ownership/permissions and on the global `safe.directory` config.

File writes in `.git/` can actually never change the access. The only
case where this access can change is an external command that changes
the ownership or permission of the folder. That sounds like a quite rare
edge case and I'm not 100% sure whether all file watchers even currently
correctly trigger events for ownership changes. @dinocosta Let me know
what you think.

Release Notes:

- Improved Git Panel performance by avoiding redundant repository access
checks.

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-07-29 09:25:16 +00:00
Ben Kunkle ecac6c00a6 Fix zoomed panels closing when focus moves within the panel (#59439)
Closes FR-139

Most focus-lost issues that close the agent panel in Zen mode stem from
panels returning a transient child editor's focus handle from
`Focusable::focus_handle`. The Zen-mode check closes the zoomed panel
when the focused element is not a descendant of the panel's focus
handle, so any focus movement inside the panel that landed outside that
child editor looked like the panel losing focus.

This PR separates the two roles that handle was serving:

- `Focusable::focus_handle` now always returns a stable handle tracked
at the panel's root element, used for containment checks (Zen-mode
auto-close, `toggle_panel_focus`, dock focus subscriptions).
- The new `Panel::activation_focus_handle` returns what should receive
focus when the panel is activated (e.g. a filter/commit/message editor)
and must be a focus-tree descendant of the root handle. All "focus the
panel" callsites in workspace/dock now use it.

Migrated panels: `AgentPanel` (including thread views and the toolbar
title editor), `CollabPanel`, `GitPanel`, `OutlinePanel`, and
`TerminalPanel` (previously delegated to the active pane, so focus in a
non-active pane dropped containment). `CollabPanel` activation falls
back to the panel root when signed out or collaboration is disabled,
since the filter editor isn't rendered in those states. Also fixes
duplicate element ids for tool calls with multiple content blocks.

Tests: a regression test that clicks tool-call output and focuses the
thread title editor while zoomed (both previously closed Zen mode), and
a dock-level test asserting the activation handle receives focus on
panel activation while the panel root reports containment.

Release Notes:

- Fixed zoomed panels (e.g. the agent panel in Zen mode) closing
unexpectedly when focus moved to elements inside the panel, such as tool
call output or the thread title editor.
2026-07-27 17:11:33 +00:00
Levin Rickert 1c244c194b git_panel: Use specific label and prompt for reverting deleted file (#61554)
# Objective

I expected a different label for reverting a file deletion like Zed
already has for reverting a file creation.

## Solution

This PR implements a new label and prompt. VS Code also shows a
different prompt while keeping the label static but I think it makes
more sense to let both adapt.

## Testing

Just deleted a file and checked menu label and prompt.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

## Showcase

<img width="363" height="139" alt="image"
src="https://github.com/user-attachments/assets/6be7e5b9-7250-449e-9cba-ea5a2099dd3a"
/>

<img width="349" height="240" alt="image"
src="https://github.com/user-attachments/assets/d87d5b4b-ff29-4976-8078-314c94a71896"
/>

---

Release Notes:

- Git Panel: Added specific label and prompt to context menu for
reverting a deleted file
2026-07-27 13:44:25 +00:00
Tai Nguyenandzed-zippy[bot] 04e53be020 git_ui: Ensure discarding tracked changes respects staging state (#61608)
Closes #56020

Release Notes:

- Fixed Discard Tracked Changes discarding unstaged files

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-07-27 12:42:54 +00:00
Smit Barmase 737f3384f0 git_ui: Add option to commit with --no-verify (#61529)
Follow-up to #61185, which moved hook execution from Zed into `git
commit` itself. There was previously no way to skip hooks from the UI;
#59846 and #56318 attempted to add one on top of the old behavior. This
PR adds support on top of the new implementation.

Adds a “Skip Hooks” toggle to the commit menus in the Git panel and
commit modal, with a corresponding command-palette action. When enabled,
the next commit runs with `git commit --no-verify`, skipping pre-commit
and commit-msg hooks. The toggle clears after a successful commit or
when switching repositories, but remains enabled when a commit fails so
it can be retried.

Release Notes:

- Added a “Skip Hooks” commit option that skips pre-commit and
commit-msg hooks.
2026-07-23 15:45:21 +00:00
Finn EversandBen Brandt 25632b979b language: Refactor available_languages into its own struct (#61388)
This adds a dedicated `AvailableLanguages` struct in preparation for a
more cabable language matching based on a given language config. No
functional changes, just shuffling some code around for this round.

Also made the LanguageMatcher non-cloneable in favor of wrapping it in
an Arc, since cloning is rather expensive for this and having a
reference is sufficient in all cases right now.

Release Notes:

- N/A

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-07-23 11:22:43 +00:00
Om Chillureanddino 52944fa0dd Support loading Git commit templates when remote (#55490)
## Summary

Fixes the git commit template not loading in remote (SSH) projects. The
`load_commit_template_text` method in `git_store.rs` was a no-op for
`RepositoryState::Remote`, always returning `Ok(None)`. This patch adds
a `LoadCommitTemplate` RPC so the client can ask the remote host to read
its `commit.template` git config and return the file contents —
mirroring the existing `GetBlobContent` pattern.

## Changes

- **`crates/proto/proto/git.proto`** — new `LoadCommitTemplate` /
`LoadCommitTemplateResponse` messages.
- **`crates/proto/proto/zed.proto`** — registered envelope IDs 449/450.
- **`crates/proto/src/proto.rs`** — wired up message priority, request
pairing, and entity-message routing.
- **`crates/project/src/git_store.rs`** — added
`handle_load_commit_template` on the host side; replaced the `Ok(None)`
no-op on the remote side with the RPC call.

## Self-Review Checklist

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — *no unsafe code
added*
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
— *no UI changes*
- [ ] Tests cover the new/changed behavior — *see "Testing notes" below*
- [x] Performance impact has been considered and is acceptable — *one
extra RPC on commit panel open for remote projects only; payload is a
single optional string*

## Testing notes — why no automated test

I did write an integration test (`test_remote_git_commit_template` in
`collab/tests/integration/git_tests.rs`, modeled after
`test_remote_git_head_sha`) along with the supporting changes to
`FakeGitRepositoryState` (adding a `commit_template` field +
`set_commit_template_for_repo` setter on `FakeFs`, since the fake
hardcoded `load_commit_template` to `None`).

The test compiled and the smaller crates (`fs`, `proto`, `project`)
checked clean, but `cargo test -p collab --test collab_tests`
cold-compile takes a very long time on my machine and I wasn't able to
confirm the test actually passed locally. Rather than push a test I
hadn't seen pass, I removed it. Happy to add it back in a follow-up PR
(or in this one if reviewers prefer) once I can run the collab suite
end-to-end — the diff is small and I can share it on request.

Verification was done end-to-end manually using a Docker dev container
as the SSH remote:

#### Closes #55265

Video : 
[Screencast from 2026-05-02
18-09-03.webm](https://github.com/user-attachments/assets/9cb7f375-57fa-4af3-bde4-871c28f61efc)

Release Notes:
- Added support for loading git commit template messages in both remote
and collab projects.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-07-22 12:01:29 +00:00
Danilo Leal 1f63fef270 git_panel: Adjust commit items in the history tab (#61456)
This PR is super small mostly adjusting a few things in the commit item
within the history tab: author label truncation, tooltip
label/description, and unpushed arrow icon design.

Release Notes:

- N/A
2026-07-22 11:55:43 +00:00
Malin Dhamsara Ruwan Pathirana 870ffffcd8 Fix git file context menu focus issue (#61339)
## Objective #61331

Ensure the Git panel receives focus when a file context menu is opened.
Previously, focusing the menu immediately could prevent the Git panel
from becoming focused.

## Solution

Defer focusing the context menu’s focus handle until the next window
update cycle. This allows the menu to be established before focus is
applied, preserving expected focus behavior in the Git panel.

## Testing

- Automated tests were not run.
- The change should be manually tested by opening a file context menu
from the Git panel and confirming the Git panel remains focused and
keyboard interaction with the menu works as expected.
- This is a UI focus change and should be verified on supported desktop
platforms.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable



## Showcase

### Previously


https://github.com/user-attachments/assets/28fb7f9b-3e1f-4939-a8ae-13b33ac0d805

### Now


https://github.com/user-attachments/assets/d85e7459-d260-41bc-955c-37a269be23c1


Release Notes:

- Fixed Git panel focus when opening a file context menu
2026-07-22 08:53:44 +00:00
Sathwik Chirivelli fcd85e1bfb git_ui: Show full files by default in solo diffs (#60989)
# Objective

Make solo diff views show the full file by default while preserving an
easy way to focus on changed hunks. This addresses a recurring request
across issues and pull requests for full-file context in single-file Git
diffs.

## Solution

- Initialize the solo diff with a singleton multibuffer so the entire
file is visible on open.
- Keep the existing toolbar toggle available for switching to
changes-only excerpts.
- Use the singleton path key when replacing excerpts so toggling remains
reliable.
- Preserve Git change indicators in the scrollbar; the editor generates
those markers for singleton buffers.

## Testing

- Ran `cargo fmt -p git_ui`.
- Ran `git diff --check`.
- Ran `cargo check -p git_ui --no-default-features` successfully.
- Manually reviewed the full-file and changes-only state transitions in
`SoloDiffView`.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

Before, solo diffs opened with only changed hunks and surrounding
context. They now open with the complete file, retain Git change
indicators in the scrollbar, and can still be toggled to changes-only
from the toolbar.

---

Release Notes:

- Improved solo diffs to show the full file by default while retaining
Git change indicators in the scrollbar.
2026-07-20 21:31:42 +00:00
Danilo Leal af7fd8b72f branch_picker: Ensure description truncates (#61360)
Just a small tweak ensuring the description truncates nicely. I think
this was a recently-introduced regression, as I am pretty sure it was
truncating well not too long ago.

Release Notes:

- N/A
2026-07-20 20:25:07 +00:00
Joseph T. Lyons 3e34dcf2a7 Keep git panel history entry highlighted while context menu is open (#61354)
Also, unifies the naming of the variable naming for the target entry in
both the git graph and git panel history tab.

Release Notes:

- Improved the git panel's history tab to keep an entry highlighted
while its context menu is open
2026-07-20 17:27:25 +00:00
Danilo Leal e1ee74dcbf worktree_picker: Improve discoverability of tasks as a creation setup mechanism (#61148)
Sometimes when creating Git worktrees, it's necessary to set things up
so the new worktree is ready. For example, copying env.vars, installing
dependencies, etc. That was already possible in Zed through the tasks
system, but you'd only maybe know about that if you read the
documentation or is super familiar with it already; nothing in the
product in the context of worktrees told you about that. This is what
this PR does.

Now, in the worktree picker, there's a "" button that opens the
`tasks.json` file exposing the `create_worktree` hook, which allows you
to plugin all sorts of things to be run by the time of a worktree
creation. If you don't already have a `tasks.json` file, we will create
a new one for you with a worktree-creation template. Otherwise, we
either append the `create_worktree` hook content to it or just open the
file.

Here's a quick video:


https://github.com/user-attachments/assets/21908be4-306b-4cf3-bed0-50d52cad9d79

Release Notes:

- Git Worktrees: Improved discoverability of the `create_worktree` hook
for setting up things that need to happen by the time of worktree
creation.
2026-07-20 11:17:21 +00:00
saberoueslatiandChris Biscardi 7113882745 git_ui: Restore search in solo diff views (#60936)
## Context

Buffer search did not work in file diffs opened from the Git panel
because `SoloDiffView` did not expose its embedded editor as searchable.
Restoring search also revealed that the primary toolbar clipped several
search controls, so the deployed search bar now uses the full-width
secondary row for this view.

Closes #60659.

## How to Review

Three files changed. Read in this order:

**`crates/git_ui/src/solo_diff_view.rs`** :
`SoloDiffView::as_searchable` now returns its embedded
`SplittableEditor`, restoring search for the focused diff side while
keeping the editor hidden from global diff-style controls.

**`crates/search/src/buffer_search.rs`** : Buffer search now detects
when its searchable split editor is intentionally hidden by the
containing item. When deployed, this case uses the secondary toolbar row
so Toggle Replace, search options, match navigation, and match counts
remain visible. Other multibuffer layouts keep their existing primary
toolbar location.

**`crates/git_ui/src/git_panel.rs`** : The regression test now opens a
solo diff through the Git panel, confirms the split editor is
searchable, deploys buffer search, verifies the secondary toolbar
location, runs a query, and checks that the focused editor receives a
search highlight.

Manual test after the fix below :

[Screencast from 2026-07-14
00-39-04.webm](https://github.com/user-attachments/assets/022ab106-d35a-4a75-98db-8809b86fa58d)

## Self-Review Checklist

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the UI/UX checklist
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed searching in file diffs opened from the Git panel.

Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
2026-07-20 05:37:29 +00:00