## Context
This just makes the UI enforce some git cli rules more clearly and
prevents some unexpected behavior.
## Self-Review Checklist
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
## Context
This adds a setting for controlling the sidebar side
## Self-Review Checklist
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Eric <eric@zed.dev>
This PR moves the `CompletionIntent` enum from the `cloud_llm_client`
crate to the `language_model` crate, as it is no longer part of the
Cloud interface.
Release Notes:
- N/A
Context
The git panel's context menu caused visual jitter (flickering/jumping)
when opened via right-click on a tracked file. The root cause was in
`dispatch_context()`: it used `self.focus_handle == focused` to check if
the panel itself was directly focused, but when a context menu opened,
focus moved to the menu (a child element), causing the `"menu"` and
`"ChangesList"` key contexts to be dropped. This triggered a re-render
with different keybindings, which re-added them, creating a loop of
jitter.
The fix replaces the direct focus equality check with
`self.focus_handle.contains_focused(window, cx)`, which returns `true`
when any child element (including the context menu) holds focus within
the panel's focus tree. This is consistent with how other panels
(project panel, outline panel, collab panel) handle focus-based dispatch
contexts.
Closes#51813
## Demo
**Before fix:**
https://github.com/user-attachments/assets/e18d49b2-72a6-4411-8ec5-519e36628f29
**After fix:**
https://github.com/user-attachments/assets/94c936d2-1e81-4d28-a86a-8b1ed76ddde1
## How to Review
This is a small, focused change in a single file:
`crates/git_ui/src/git_panel.rs`.
1. **The fix** (~line 974): `dispatch_context()` method — the old code
checked direct focus equality (`self.focus_handle == focused`), the new
code uses `self.focus_handle.contains_focused(window, cx)` and
restructures the conditionals so `CommitEditor` is checked first via
`if/else if`.
2. **The test** (~line 7871): `test_dispatch_context_with_focus_states`
— verifies 4 focus state transitions: commit editor focused, changes
list focused, back to commit editor, and back to changes list. Each case
asserts the correct key contexts are present/absent.
## 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](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed git panel context menu jitter caused by keybinding dispatch
context flickering when right-clicking on tracked files (#51813)
## Context
When `git_panel.status_style` is set to `label_color`, the git panel
should indicate file status through text color only, without showing
status icons. However, the icons were still being rendered regardless
of this setting.
The root cause: `git_status_icon(status)` was called unconditionally
in `render_status_entry`, with no check against the current
`status_style` value.
Closes#51714
## How to Review
Single change in `crates/git_ui/src/git_panel.rs` —
`render_status_entry` function. The icon render call is now wrapped
in `.when(status_style != StatusStyle::LabelColor, ...)`.
Release Notes:
- Fixed git panel status icons still showing when
`git_panel.status_style`
is set to `label_color`
Bug:
<img width="2559" height="1357" alt="image"
src="https://github.com/user-attachments/assets/3cad9f96-8b5c-4554-8b9f-f931026bdfe1"
/>
Fix:
<img width="1512" height="801" alt="image"
src="https://github.com/user-attachments/assets/99f36d11-a8b2-412a-ab73-18200f6594d2"
/>
* Add `editor::RewrapOptions::line_length` to, optionally, override the
line length used when rewrapping text.
* Update `editor::Editor::rewrap_impl` to prefer
`editor::RewrapOptions::line_length`, when set.
* Add a `line_length` field to the `vim::rewrap::Rewrap` action.
* Update the `:reflow` vim command with `vim::command::VimCommand::args`
so as to be able to parse the provided argument as `usize`, ensuring
that no effect is taken if the argument can't be parsed as such.
Release Notes:
- N/A
#### Context
Switches `TextDiffView` from using `Editor` directly to
`SplittableEditor`, enabling side-by-side diff view support for "Diff
Clipboard with Selection". The diff view now respects the user's
`diff_view_style` setting.
Split out from #51457. This PR contains only the `SplittableEditor`
wiring. The multibuffer coordinate fix for non-singleton editors will
follow in a separate PR.
Closes#50912 (partially)
#### How to Review
Small PR — all changes are in `crates/git_ui/src/text_diff_view.rs`.
Focus on:
- `new()`: `SplittableEditor::new` replaces `Editor::for_multibuffer`,
editor-specific setup goes through `rhs_editor()`
- Item trait delegation: `act_as_type`, `for_each_project_item`,
`set_nav_history` updated for `SplittableEditor`
- Tests: pinned `DiffViewStyle::Unified` and assertions go through
`rhs_editor()`
#### 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](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
#### Video :
[Screencast from 2026-03-19
23-11-36.webm](https://github.com/user-attachments/assets/c5a2381d-238d-43ef-ac6f-9994996c0c69)
#### Release Notes:
- Improved "Diff Clipboard with Selection" to support side-by-side diff
view style.
- Change the branch button's tooltip to be more accurate given it
displays more stuff than only branches
- Hide the worktree dropdown menu when in a non-Git repo project
- Improve provisioned title truncation
- Remove the plus icon from the "view more" item to improve sidebar's
overall feel
- Remove the always visible "new thread" button but make it visible only
when you're in an empty thread state
- Add worktree icon in the thread item and tooltip with full path
- Space out the worktree name from the branch name in the git picker in
the title bar
- Swap order of views in the git picker to "worktree | branches | stash"
- Improve the "creating worktree" loading indicator
---
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
## Context
Fixes the visual selection update in `TextDiffView::open` to properly
convert between buffer-local and multibuffer coordinates using
`buffer_point_to_anchor`. Previously, raw multibuffer Points were used
directly for line expansion, which produced incorrect regions when
expanded deleted diff hunks shifted multibuffer row numbers.
This provides a single unified code path for both singleton and
non-singleton multibuffers, as suggested in [#51457 review
feedback](https://github.com/zed-industries/zed/pull/51457#issuecomment-4091134303).
Follow-up to #51457.
## How to Review
Small PR - all changes are in `crates/git_ui/src/text_diff_view.rs`.
Focus on:
- `open()`: The visual selection update block now uses
`buffer_point_to_anchor` + `to_point` instead of raw multibuffer
coordinate math
- No more assumption that multibuffer Points == buffer-local Points
- Existing tests validate both singleton and non-singleton multibuffer
paths
## Self-Review Checklist
- [x] I've reviewed my own diff for quality, security, and reliability
- [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 incorrect diff region when using "Diff Clipboard with Selection"
with expanded diff hunks in the editor.
When a git worktree is in a detached HEAD state (e.g. after `git
checkout --detach`), the workspace for that worktree would disappear
from the sidebar UI, and if the workspace was currently open your UI
would just disappear.
This happened because `parse_worktrees_from_str` silently dropped any
worktree entries without a `branch` line in the porcelain output, which
cascaded through the `linked_worktrees` list and caused
`prune_stale_worktree_workspaces` to remove the workspace.
This PR:
- Makes `Worktree::ref_name` an `Option<SharedString>` so detached
worktrees can be represented
- Renames `Worktree::branch()` to `Worktree::display_name()`, which
returns the branch name when available or the short SHA as a fallback
(mirroring how the title bar already handles detached HEAD for
repositories)
- Updates `parse_worktrees_from_str` to include detached and bare
worktree entries instead of dropping them
- Filters detached worktrees out of the worktree picker UI, preserving
the existing product decision to only show branch-based worktrees there
## 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 is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
## Context
I have a project with a nested git repo inside a parent repo (separate
`.git` directory, not a submodule). The title bar shows the parent's
branch instead of the nested repo's own branch.
The issue is in `get_repository_for_worktree()` — it iterates
`git_store.repositories()` (an `FxHashMap`) and returns the first
`starts_with` match. Both the parent and nested repo match, and
whichever one FxHashMap iterates first wins. There's no reason it should
be one or the other.
The fix already exists elsewhere in the codebase —
`GitStore::repository_and_path_for_project_path()` at
`git_store.rs:1826` uses `.max_by_key()` to pick the most specific
(longest path) match. This PR applies the same approach to three
functions that have the same problem:
- `TitleBar::get_repository_for_worktree()` — branch display in title
bar
- `resolve_active_repository()` in `git_ui` — repository selection for
the git panel
- `get_branch_for_worktree()` in `recent_projects` — branch display in
the project switcher
Two other locations use a similar `starts_with` pattern
(`effective_active_worktree()` in `title_bar.rs` and worktree selection
in `recent_projects.rs`) but those iterate worktrees against a single
known repo, not repos against a worktree — so first-match and
longest-match give the same result. Left those unchanged.
Closes#7566
## How to Review
All three changes are the same transformation: first-match loop (or
`.find()`) → `.filter().max_by_key()` on path length. The reference is
at `crates/project/src/git_store.rs:1826`.
The primary fix is `get_repository_for_worktree()` in `title_bar.rs`.
The other two are the same pattern.
One difference from the reference: I used `.as_os_str().len()` instead
of `.clone()` for the `max_by_key` key — avoids cloning an `Arc<Path>`
per comparison. Among prefix-related paths (which is all that passes the
filter), the longer path is always the more specific match, so length
comparison is equivalent.
`title_bar` has no existing test infrastructure. Happy to add a test if
you'd like — the setup would follow the pattern in
`test_git_traversal_with_nested_repos`
(`crates/project/tests/integration/git_store.rs`).
```
cargo test -p title_bar -p git_ui -p recent_projects
./script/clippy
```
## 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 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
Release Notes:
- Fixed branch picker showing parent repository's branch instead of the
nested repository's branch when working in submodules or nested git
repos.
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
* [x] Display original project name as root folder in project panel,
titlebar
* [x] When manually creating worktrees, ensure final path component is
original project name
* [x] Display original project name, worktree name, and branch name in
titlebar
* [x] Only show main checkout in project switcher
Release Notes:
- N/A *or* Added/Fixed/Improved ...
---------
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
All of the important changes are in
[`db.rs`](https://github.com/zed-industries/zed/pull/51809/changes#diff-2f644eab943bfa58feec29256281a3d9e8d4d7784cd34783e845af8beb15b16d).
Consider reading the commit log in order to review this work.
The DB crate's macro and API was changed to fix flakiness observed in
the MultiWorkspace tests when run locally. This flakiness was caused by
a shared `static LazyLock`, that caused concurrent test runs to interact
with the same underlying in-memory database. This flakiness wasn't
possible on CI due to it's usage of `cargo nextest`, whose
process-per-test approach masked this problem.
Essentially, I've changed the `static_connection` macro to remove the
static database variable and redone the internal model. Now, all
database types are thin wrappers around a generic `AppDatabase`. The
`AppDatabase` collects all of the individual table's migrations via the
`inventory` crate, and so only runs the migrations once on startup,
rather than a dozen times on startup.
The new API requires a `cx` so that we can replace the database returned
at runtime, rather than relying exclusively on a process-global
thread-local. However, we are still using a `static LazyLock` so that we
only need to take an `&App`, instead of an `&mut App`. These databases
types are `Clone + Send + Sync`, so you can easily capture-and-move the
database into background tasks and other places that don't have a `cx`.
For tests that require database isolation, it is now possible to set
their own database in init. See
[`workspace::init_test`](https://github.com/zed-industries/zed/pull/51809/changes#diff-041673bbd1947a35d45945636c0055429dfc8b5985faf93f8a8a960c9ad31e28R13610),
for the flakiness fix.
Best part, this change should be entirely compiler driven, so the Zed
agent was able to make the app-wide refactor easily.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Fixes#51542
Adds a `git_panel.starts_open` setting for parity with `project_panel`.
When set to `true`, the git panel opens automatically in new workspaces
that don't have saved panel state.
The default is `false`, matching current behavior (non-breaking).
### Usage
```json
{
"git_panel": {
"starts_open": true
}
}
```
### Implementation
Follows the same pattern as `project_panel.starts_open`:
1. `GitPanelSettingsContent` - added `starts_open: Option<bool>` to the
settings schema
2. `GitPanelSettings` - added `starts_open: bool` field
3. `GitPanel` Panel impl - overrides `starts_open()` to read from
settings
Release Notes:
- Added `git_panel.starts_open` setting to control whether the git panel
opens automatically in new workspaces (default: false)
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
While fixing the tests in the previous PR (#48338), I noticed that the
`delete_branch` tests only verified the UI state changes rather than the
actual state of the underlying repository.
Currently, if `delete_branch` were a no-op that returned Ok(), the tests
would still pass incorrectly. This PR addresses that gap by ensuring the
branch is actually removed from the repository.
|Before|After|
|--|--|
|<img width="3476" height="2564" alt="图片"
src="https://github.com/user-attachments/assets/f5c4c5c4-64fe-4074-9fff-fb166d160d77"
/>|<img width="3476" height="2564" alt="CleanShot 2026-03-18 at 17 51
36@2x"
src="https://github.com/user-attachments/assets/47419d37-5051-4139-969e-65a1347bf555"
/>|
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#48256
It appears that the current git remotes support was implemented in
#42819, following the design described in
https://github.com/zed-industries/zed/pull/42486#issuecomment-3524092306.
That design does not include an interaction for deleting remotes, but
the delete remote branch action was mistakenly implemented as deleting
the remote itself.
After this PR, there should be no code paths that use `remove_remote`
anymore. I've kept it for now though, as it may be useful when we
introduce the corresponding interaction in the future.
Release Notes:
- Fixed a bug where deleting a remote branch from the branch picker
would incorrectly remove the entire remote configuration
This PR fixes that when you are below a header and want to select a
previous item, we would select a non-visible item because we did a -1 of
the newly selected index, which could end up inside a collapsed
directory.
**Note**: This is only an issue for the git tree view mode.
**Before** (See selection is not visible anymore after select previous,
because it's inside the collapsed directory)
https://github.com/user-attachments/assets/bd032768-b947-45f8-b5a1-6185010202cf
**After** (See selection now selects the first visible item in the list
which is the collapsed directory)
https://github.com/user-attachments/assets/47f67237-be7c-4ef5-8b99-6a3a2b016086
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Git UI: Fix selecting previous item would select a non-visible item if
it's inside a collapsed directory
## Summary
- Implements `icon_label` on `GitPanel` to return the total count of
uncommitted changes (`new_count + changes_count`) when non-zero, capped
at `"99+"` for large repos.
- Updates `PanelButtons::render()` to render that label as a small green
badge overlaid on the panel's sidebar icon, using absolute positioning
within a `div().relative()` wrapper.
- The badge uses `version_control_added` theme color and
`LabelSize::XSmall` text with `LineHeightStyle::UiLabel` for accurate
vertical centering, positioned at the top-right corner of the icon
button.
The `icon_label` method already existed on the `Panel`/`PanelHandle`
traits with a default `None` impl, and was already implemented by
`NotificationPanel` (unread notification count) and `TerminalPanel`
(open terminal count) — but was never rendered. This wires it up for all
three panels at once.
## Notes
- Badge is positioned with non-negative offsets (`top(0)`, `right(0)`)
to stay within the parent container's bounds. The status bar's
`render_left_tools()` uses `.overflow_x_hidden()`, which in GPUI clips
both axes (the `overflow_mask` returns a full content mask whenever any
axis is non-`Visible`), so negative offsets would be clipped.
- `LineHeightStyle::UiLabel` collapses line height to `relative(1.)` so
flex centering aligns the visual glyph rather than a
taller-than-necessary line box.
- No new data tracking logic — `GitPanel` already maintains `new_count`
and `changes_count` reactively.
- No feature flag or settings added per YAGNI.
## Suggested .rules additions
The following pattern came up repeatedly and would prevent future
sessions from hitting the same issue:
```
## GPUI overflow clipping
`overflow_x_hidden()` (and any single-axis overflow setter) clips **both** axes in GPUI.
The `overflow_mask()` implementation in `style.rs` returns a full `ContentMask` (bounding box)
whenever any axis is non-`Visible`. Absolute-positioned children that extend outside the element
bounds will be clipped even if only the X axis is set to Hidden.
Avoid negative `top`/`right`/`bottom`/`left` offsets on absolute children of containers
that have any overflow hidden — keep badge/overlay elements within the parent's bounds instead.
```
Release Notes:
- Added a numeric badge to the git panel sidebar icon showing the count
of uncommitted changes.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This PR is motivated by internal feedback in which the notification that
we show inviting to resolve merging conflicts with an agent also pops up
if the agent itself ran `git merge`. In this case, the notification is
unnecessary noise. So, what I'm doing here is simply _not_ showing it if
there's a running agent.
I want to note that this change is accepting a trade-off here, in which
there could be cases that even if an agent is running, the notification
can still be useful. There could be other ways to identify whether the
agent is running `git merge`, but they all felt a bit too complex for
the moment. And given this is reasonably an edge case, I'm favoring a
simple approach for now.
Release Notes:
- N/A
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
Closes https://github.com/zed-industries/zed/discussions/49740
Adds optional file and folder icons to the Git panel so its file list is
easier to scan, especially in larger repositories.
- add folder icons for Git panel entries
- add Git panel settings for file and folder icon visibility
---
Release Notes:
- Made the Git Panel aware of icon themes.
- Added the ability to render file type icons in the Git panel.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Previously, if you wanted to have a button that contains icons on both
edges, you'd need to use a `ButtonLike` component, which takes any
children. Meanwhile, the `Button` would only take one icon, where you
could control its position through the `IconPosition` enum. This has
always felt unnecessarily limiting. So, this PR removes this limitation
by adding two new methods to the button: `start_icon` and `end_icon`.
In the meantime, I have also been bothered by the unnecessary
indirection in the `IconButton` due to the existence of the `ButtonIcon`
component. So I figured I could also completely eliminate that by adding
some of its methods directly to the `IconButton` and in the Button, just
using a regular `Icon` component.
---
## Before
```rust
Button::new("id", "Label")
.icon(IconName::Plus)
.icon_position(IconPosition::Start)
.icon_size(IconSize::Small)
.icon_color(Color::Muted)
```
## After
```rust
Button::new("id", "Label")
.start_icon(Icon::new(IconName::Check))
.end_icon(Icon::new(IconName::ChevronDown).size(IconSize::XSmall))
```
This should have no visual impact to the UI.
Release Notes:
- N/A
Remove the BreadcrumbText struct from workspace and use the existing
HighlightedText struct from the language crate instead. The per-segment
font field is replaced by returning an optional Font alongside the
segments from the breadcrumbs() method, since the font was always
uniform across all segments of a given item.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Follow up to https://github.com/zed-industries/zed/pull/49807
This PR fixes the merge conflict notification by making it appear only
once per a given set of conflicted paths, as opposed to showing every
time the `ConflictsUpdated` or `StatusesChanged` even would fire.
Release Notes:
- N/A
BufferEvent::Edited had no way to distinguish local edits from remote
(collaboration) edits. This caused edit prediction behavior to fire on
the guest's editor when the host made document changes.
Release Notes:
- Fixed edit predictions triggering on collaboration guests when the
host edits the document.
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
This PR adds a "Resolve with Agent" button in each merge conflict block,
as well as "Resolve Conflicts with Agents" button on a notification for
resolving conflicts across all the files that have any. When clicking on
either of these buttons, the agent panel opens up with a template prompt
auto-submitted. For the first case, the specific content of the merge
block is already attached as context for the agent to act quickly, given
it's a local and small context. For the second case (all conflicts
across the codebase), the prompt just indicates to the agent which files
have conflicts and then it's up for the agent to see them. This felt
like a simpler way to go as opposed to extracting the content for all
merge conflicts across all damaged files.
Here's how the UI looks like:
<img width="550" height="1964" alt="Screenshot 2026-02-21 at 11 04@2x"
src="https://github.com/user-attachments/assets/96815545-ba03-40e5-9cb0-db0ce9588915"
/>
---
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Git: Added the ability to quickly resolve merge conflicts with the
agent.
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
This will help with test times (in some cases), as nextest cannot figure
out whether a given rdep is actually an alive edge of the build graph
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Add a `git::RestoreAndNext` action that restores the diff hunk at the
cursor and advances to the next hunk. In the git diff view, the default
restore keybinding (`cmd-alt-z` on macOS, `ctrl-k ctrl-r` on
Linux/Windows) is remapped to this action so users can quickly restore
hunks in sequence. Also refactor `go_to_hunk_before_or_after_position`
to accept a `wrap_around` parameter, eliminating duplicated
hunk-navigation logic in `do_stage_or_unstage_and_next` and
`restore_and_next`.
Release Notes:
- Added a `git: restore and next` action that restores the diff hunk at
the cursor and moves to the next one. In the git diff view, the
default restore keybinding (`cmd-alt-z` on macOS, `ctrl-k ctrl-r` on
Linux/Windows) now triggers this action instead of `git: restore`.
---------
Co-authored-by: Afonso <4775087+afonsograca@users.noreply.github.com>
Adds the ability to delete a git worktree directly from the worktree
picker, inspired by the existing branch delete functionality.
(`cmd-shift-backspace` on macOS, `ctrl-shift-backspace` on
Linux/Windows).
Screenshot:
<img width="1288" height="466" alt="Screenshot 2026-02-24 at 16 01 05"
src="https://github.com/user-attachments/assets/6ca5048d-63fa-4295-a578-358904bb92eb"
/>
Release Notes:
- Added the ability to delete a git worktree from the worktree picker
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
Follow up on: https://github.com/zed-industries/zed/pull/49519
This PR reworks how Zed calculates diff num stats by moving the
calculation to the `RepositorySnapshot` layer, instead of the
`GitPanel`. This has a couple of benefits:
1. Snapshot recalculations are already set up to recompute on file
system changes and only update the affected files. This means that diff
stats don't need to manage their own subscription or states anymore like
they did in the original PR.
2. We're able to further separate the data layer from the UI. Before,
the git panel owned all the subscriptions and tasks that refreshed the
diff stat, now the repository does, which is more inline with the code
base.
3. Integration tests are cleaner because `FakeRepository` can handle all
the data and calculations of diff stat and make it accessible to more
tests in the codebase. Because a lot of tests wouldn't initialize the
git panel when they used the git repository.
4. This made implementing remote/collab support for this feature
streamline. Remote clients wouldn't get the same buffer events as local
clients, so they wouldn't know that the diff stat state has been updated
and invalidate their data.
5. File system changes that happened outside of Zed now trigger the diff
stat refresh because we're using the `RepositorySnapshot`.
I added some integration tests as well to make sure collab support is
working this time. Finally, adding the initial diff calculation to
`compute_snapshot` didn't affect performance for me when checking
against chromium's diff with HEAD~1000. So this should be a safe change
to make.
I decided to add diff stats on the status entry struct because it made
updating changed paths and the collab database much simpler than having
two separate SumTrees. Also whenever the UI got a file's status it would
check its diff stat as well, so this change makes that code more
streamlined as well.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing.
- [x] Done a self-review taking into account security and performance
aspects.
Release Notes:
- N/A
Closes#48434
In Dev Containers, failed git operations were surfaced with a generic
failure message, while the useful git output (stderr/stdout) was not
reliably available to users.
This happened because in devcontainers the git operation errors go
through an RPC layer and then got wrapped with `anyhow::Context` (e.g.
“sending pull request”); the toast displayed only that outer context via
`to_string()`, masking the underlying git stderr message.
This change ensures the full git operation output is preserved and
surfaced via Zed’s “See logs” flow in Dev Containers, matching the
information you get when running the same git command in a terminal.
### What you should expect in the UI
- You will see a generic toast like “git pull failed” / “git push
failed”.
- When clicking on the toast’s “See logs”, the log tab now contains the
full git error output (e.g. non-fast-forward hints, merge conflict
details, “local changes would be overwritten”, etc.), which previously
could be missing/too generic.
---
## Manual testing
Run inside a Dev Container and ensure git auth works (SSH keys/agent or
HTTPS credentials).
1. **Dirty-tree pull failure**
- Make remote ahead by 1 commit (push from another clone).
- Locally modify the same file without committing.
- In Zed: **Pull**
- **Expect:** toast “git pull failed” + **See logs** shows “local
changes would be overwritten…” (or equivalent).
2. **Non-fast-forward push failure**
- Ensure remote ahead.
- Locally create 1 commit.
- In Zed: **Push**
- **Expect:** toast “git push failed” + **See logs** shows “rejected
(non-fast-forward)” + hint to pull first.
3. **Merge-conflict pull failure**
- Create conflicting commits on the same lines (one local commit, one
remote commit).
- In Zed: **Pull**
- **Expect:** toast “git pull failed” + **See logs** shows conflict
output (“CONFLICT…”, “Automatic merge failed…”).
Release Notes:
- Fixed devcontainer git failure toasts so they show the actual git
error
---------
Co-authored-by: KyleBarton <kjb@initialcapacity.io>
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Fixed a bug where files would still be marked as having git conflicts
after resolving them.
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
This does not yet allow for finding task <-> entity cycles
unfortunately, but at least it does catch entity <-> entity cycles for
the time being
Release Notes:
- N/A *or* Added/Fixed/Improved ...
This is a staff only toggle for now, since the consequences of
activating it are not obvious and quite dire (tokens costs 6 times
more).
Also, persist thinking, thinking effort and fast mode in DbThread so the
thinking mode toggle and thinking effort are persisted.
Release Notes:
- Agent: The thinking mode toggle and thinking effort are now persisted
when selecting a thread from history.
Paving the way to remove `ExcerptId`. Done in this PR:
- Unshipped the stack trace view
- Get rid of `push_excerpts`
- Get rid of some callers of `remove_excerpts`
We still need to remove some calls to `remove_excerpts` and other APIs,
especially in `randomly_edit_excerpts` and collaboration.
Release Notes:
- The stack trace multibuffer view has been removed.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This PR adds the small UI change of `git diff --numstat` to the git
panel so you can see the number of additions/deletions per file. There
is an option in the settings UI for this under `git_panel`.`diff_stats`.
This option is set to `false` by default.
<!-- initial version <img width="1648" height="977" alt="Screenshot
2026-02-18 at 18 42 47"
src="https://github.com/user-attachments/assets/b8b7f07c-9c73-4d06-9734-8f1cf30ce296"
/> -->
<img width="1648" height="977" alt="Screenshot 2026-02-18 at 21 25 02"
src="https://github.com/user-attachments/assets/73257854-6168-4d12-84f8-27c9e0abe89f"
/>
Release Notes:
- Added git diff stats to git panel entries
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>
- Enabled opening the Git Graph, with the corresponding commit detail
drawer open, from the commit view
- Redesigned the commit view's header and toolbar to allow addition of
the Git Graph icon button
- Redesigned icons for the Git Graph and commit view
https://github.com/user-attachments/assets/8efef60a-0893-4752-9b40-838da21ceb54
---
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A (_Git Graph is still feature flagged, so no release notes for
now_)
Closes#48383
An alternative approach would be to use `min_w` instead of `w`, but that
would result in inconsistent widths across the three tabs in the git
picker, causing layout jumps when switching between them. It might be
more appropriate to simply increase the width directly.
|Before|After|
|--|--|
|<img width="932" height="290" alt="CleanShot 2026-02-22 at 02 01 20@2x"
src="https://github.com/user-attachments/assets/a0868cf5-86a0-4375-9cf5-6728a6411ff1"
/>|<img width="970" height="274" alt="CleanShot 2026-02-22 at 02 03
50@2x"
src="https://github.com/user-attachments/assets/acee111c-06ff-48d1-b1c7-c118bdddfcf9"
/>|
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Fixed footer buttons clipped in stash picker when vim mode is enabled
on macOS
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
- Made hover/active styles, as well as clicks, work for the entire row,
capture the graph element, too (needed to make some manual hover and
other states management to pull that off)
- Used the existing `Chip` component for the branch chip instead of a
local recreation
- Adjusted spacing and sizing of commit detail panel, including button
labels truncation and tooltip content
- Added diff stat numbers for the changed files, to match the commit
view
- Standardized the commit avatar component across the git graph, the
commit view, and the file history view
- Added scrollbar to the changed files uniform list
- Removed author name display redundancy (kept only email)
- Made the commit detail UI have a min-width
<img width="750" height="1964" alt="Screenshot 2026-02-23 at 11 31@2x"
src="https://github.com/user-attachments/assets/d1433bd8-5edb-4829-882b-52b1bffbd6db"
/>
---
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
Remove both `git::LoadMoreHistory` and `git::ViewCommitFromHistory`
actions as although both actions were registered in the workspace, they
don't actually have effect when run.
This appears to have been leftover from
https://github.com/zed-industries/zed/pull/42441 , possibly the initial
implementation on how to open a commit and load more commits when the
file history view was open, which is now handled with `Button.on_click`
callbacks instead of relying on actions.
Closes#49288
Release Notes:
- Removed unused git actions – `git: load more history` and `git: view
commit from history`
Use title case everywhere.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Use title case for UI labels
---------
Signed-off-by: Sakthi Santhosh Anumand <mail@sakthisanthosh.in>
Co-authored-by: Kunall Banerjee <hey@kimchiii.space>
Closes#49746
Previously, the `LinkFinder` looked at all of the lines, which sometimes
includes links unrelated to the pull request, like a post quantum
cryptography warning that links to
[this](https://www.openssh.org/pq.html) article.
Release Notes:
- When searching for pull request links in git output, only lines that
start with `remote:` are searched.
For inverted diff APIs like `hunks_intersecting_base_text_range`, we
need a snapshot of the main buffer to use as context to compare hunk
anchors, convert anchors to points, etc. Previously, we were always
using a snapshot of the main buffer at the time when the diff was
calculated. This worked well for the hunks of the primary `BufferDiff`,
but it's not valid when the diff also has a secondary set of hunks,
because those hunks are recalculated on their own schedule--so it's
possible for the hunks of the secondary diff to contain anchors that are
newer than the original buffer snapshot that was taken at the time the
primary diff hunks were last calculated. This caused a panic when using
these anchors with the original buffer snapshot.
This PR fixes the issue by using the same approach for inverted diffs as
for non-inverted diffs at the multibuffer level: we take a snapshot of
the main buffer at the time when we snapshot the diff state (including
the diff itself), guaranteeing that that snapshot will be new enough to
resolve all the anchors included in both the primary diff and the
secondary diff.
Closes ZED-54J
Release Notes:
- Fixed a panic that could occur when using the branch diff in split
view mode.
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
This PR adds the diff stat numbers to the `git: branch diff` view
toolbar.
<img width="550" height="1964" alt="Screenshot 2026-02-20 at 10 58@2x"
src="https://github.com/user-attachments/assets/0fc63b64-ce6e-417a-92b5-8008f2561a8f"
/>
---
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Git: Added diff stat numbers to the Branch Diff (`git: branch diff`)
view.
This PR makes the "Review Diff" button show up only if the multibuffer
_isn't_ empty and if AI is enabled. It was previously just checking for
the AI setting.
Release Notes:
- N/A
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Add `agent_worktree_directory` to `GitSettings` for configuring where
agent worktrees are stored (default: Zed data dir). Remove `Copy` derive
from `GitSettings`/`GitContentSettings` (incompatible with String field)
and fix downstream `.as_ref().unwrap()` call sites.
Define `AgentGitWorktreeInfo` (branch, worktree_path, base_ref) and add
it to `DbThread` + `DbThreadMetadata` for persistence and session list
display.
Closes AI-33
Release Notes:
- N/A
This PR adds a button in the `git: branch diff` view that allows to
quickly and easily send the entire diff to your last used agent for a
review. What this does is automatically submits a (pre-written and
generic) prompt to the last agents you were using in the agent panel
with the whole content of your diff.
<img width="750" height="1964" alt="Screenshot 2026-02-18 at 3 35@2x"
src="https://github.com/user-attachments/assets/493d8cf4-4815-4b01-91a0-6a39ad6219fe"
/>
Release Notes:
- Added a "Review Branch" button in the `git: branch diff` view so that
the whole diff can be quickly sent for review to an agent.
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
This PR removes onboarding modals for features that were announced, at
this point, a long time ago: Git v1, Debugger, and Agent Panel v1. This
cleans up the actions list a bit when you search for "onboarding". I
left the ACP and Claude Code ones, though; they were the two more recent
ones, but we should be able to remove them soon enough, too.
Release Notes:
- N/A
Replaces a bunch of `impl FnMut` parameters with `&mut dyn FnMut` for
functions where this is the sole generic parameter.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Before this PR we wouldn't always serialize workspaces when a
mutliworkspace adds/removes a workspace. This PR fixes this by adding a
test and calling serialization in remove
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
This PR adds a button in the Git Panel to open the `git: branch diff`
view. The button only shows if the staging area is clean/no changes and
if the branch is not main/master. I've been using this action so much
these days and we should expose it on the UI so it's more discoverable.
<img width="500" height="1736" alt="Screenshot 2026-02-16 at 6 30@2x"
src="https://github.com/user-attachments/assets/0b037811-2167-419f-b63f-9bdb12e4352e"
/>
Release Notes:
- N/A
This change improves performance of project diff in that:
* scrolling in split view for very large diffs (think chromium repo with
`git reset HEAD~1000`) is now very smooth on macOS and fairly smooth on
Linux
* switching from split to unified is very smooth on macOS, and fairly
smooth on Linux
There still remains the case of (severe) hangs when switching from
unified to split however, but it will be addressed in a follow-up PR.
Anyhow, here's the screenshot of the Instruments.app capture of opening
chromium repo in Zed in split view, scrolling a little, moving to
unified, scrolling some more, and moving back to split. Prior to this
change, split -> unified would cause a severe hang, whereas now it's a
hang and thus feels much smoother already (without Instruments profiling
is barely visible). Unified -> split severe hangs are still there but
don't last as long.
<img width="2301" height="374" alt="Screenshot 2026-02-16 at 5 46 23 PM"
src="https://github.com/user-attachments/assets/f687f8d4-cffd-47f1-ada1-f6c4d3ac3cd4"
/>
Release Notes:
- Improved project diff performance when opening very large
diffs/repositories.
Release Notes:
- Added agent panel restoration. Now restarting your editor won't cause
your thread to be forgotten.
---------
Co-authored-by: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com>
Co-authored-by: Eric Holk <eric@zed.dev>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Co-authored-by: Cameron Mcloughlin <cameron.studdstreet@gmail.com>
- Fix panics caused by reusing cached matches for the wrong side
- Highlight matches on the side that was searched only
- Clear matches in non-searched editor when initiating a new search
Release Notes:
- N/A
---------
Co-authored-by: Eric <eric@zed.dev>
Co-authored-by: Jakub <jakub@zed.dev>
Ensure that `git_ui::stash_picker::StashList.handle_show_toast` emits a
`DismissEvent` so that, when the user confirms they wish to view a stash
entry, the modal is actually dismissed and does not block the user's
view.
Release Notes:
- Fixed issue where viewing a stash entry would not dismiss the modal
It's happeningggggg
Release Notes:
- Changed the Agent Panel so that the Active Thread is restored on
restart.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Co-authored-by: Richard Feldman <richard@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Searching (and related vim stuff like `*`/`n`/`N`) now work in the LHS
of a
split diff.
Also fixes the bug with indent guides being visible through the spacer
checkerboard pattern.
Release Notes:
- N/A
Currently we always compute breadcrumbs and sticky headers on every
editor paint which is not cheap to do especially in bigger files, moving
this off to be computed on event handling where they change and then
caching them can save serveral milliseconds per render in bigger files.
This also puts matching brackets refreshing and document highlights on a
background task, as this tends to block the main task for prolonged time
as well.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#48195
Filter out `remote_info` when viewing stashes by adding `.filter(|_|
self.stash.is_none())`.
Release Notes:
- Fixed "View on GitHub" button incorrectly appearing when viewing
stashes
The indent guide computation was using visible list indices directly to
access entries, instead of mapping through `logical_indices` first. This
caused incorrect depths to be read from hidden entries when a folder was
collapsed, resulting in stray vertical lines extending to unrelated folders.
Closes#48189
Release Notes:
- Fixed a visual bug in the Git Panel where collapsing a folder in tree
view would cause indent guide lines to incorrectly extend to unrelated
folders below it.
GitHub's commit API endpoint is rate limited to 60 requests/hour for
unauthenticated users. This causes avatar loading to fail after toggling
blame a few times.
This PR uses GitHub's CDN avatar endpoint
`https://avatars.githubusercontent.com/u/e?email={email}&s=128` instead,
which doesn't count against API rate limits. The author email is already
available from local git data (blame output), so
no API calls are needed.
- When author email is available, constructs the CDN URL directly (zero
API calls)
- Falls back to existing API-based behavior when email is unavailable
- Adds unit tests for URL construction
Closes#47590
## Test plan
- [x] `./script/clippy` passes
- [x] `cargo test -p git_hosting_providers` passes (89 tests including 3
new ones i added)
- [ ] Manual test: Open a file, toggle git blame, verify avatars load
without hitting rate limits
Release Notes:
- Fixed GitHub avatar rate limiting in git blame by using CDN endpoint
instead of API calls (#47590)
This branch:
1. teaches `--diff `command line option to to recurse into folders if
provided.
2. Adds a `MultiDiffView` that shows _all_ changed files in a single,
scrollable view.
This is necessary to provide a smooth user experience for `jj` and Zed
users who wish to use Zed as their jj difftool.
I'm not fully sure how this change interacts with
https://github.com/zed-industries/zed/pull/44936, or what plans y'all
have in mind.
Here's a screenshot of the resulting behavior:
<img width="1090" height="950" alt="Screenshot 2025-12-17 at 9 10 52 AM"
src="https://github.com/user-attachments/assets/8efd09b4-974f-4059-9f94-539c484c6d4a"
/>
I setup zed to handle jj diffs by adding the following to my jj config:
```toml
[aliases]
zdiff = ["diff", "--tool", "zed"]
[merge-tools.zed]
program = "/Users/dbarsky/Developer/zed/target/debug/cli"
# omit diff-invocation-mode to keep the default (JJ passes two dirs)
diff-args = [
"--zed", "/Users/dbarsky/Developer/zed/target/debug/zed",
"--wait",
"--new",
"--diff",
"$left",
"$right",
]
```
Release Notes:
- `--diff`, if provided with folders instead of files, will recurse into
those directories.
- Added a `MultiDiffView`, which will show all changed files within a
single, scrollable view.
**AI Disclosure**: Pretty much all of this code was written using Codex
with GPT-5.1-Codex. I edited by hand and tested this.
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
We were using primary/secondary in some places which is just
unnecessarily confusing.
Release Notes:
- N/A
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Basically just replaced `SharedString::new("` with
`SharedShring::new_static("` which removes the allocation to `Arc<str>`.
Unfortunately this can't be enforced at compile time without trait
specialization which is only available on nightly. You could assert that
`TypeId`'s differ, but `TypeId` only exists at runtime.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
When working in a workspace with multiple repositories, the git panel
provides a repository picker to switch between them. However, there was
no visual indication of which repositories have uncommitted changes:
users had to either select each repository individually or check the
project panel where modified directories are highlighted.
This change adds git status icons to the repository picker, allowing
users to see at a glance which repositories contain changes (modified,
added, deleted, or conflicted files). The icons use the same visual
language already established for file status throughout the git panel.
Additionally, the repository picker now matches the branch picker's
styling for visual consistency:
- Added "Repositories" header
- Aligned popover width and positioning
- Added scrollbar
- Added check icon next to currently selected repo
- Added selected branch under repo list item
- Sort by display name is now case insensitive
Before:
<img width="1200" height="815" alt="Screenshot 2026-01-27 at 11 43 55"
src="https://github.com/user-attachments/assets/12c1008b-4724-44bf-80c9-e9ad97755090"
/>
After:
<img width="1761" height="1196" alt="Screenshot 2026-01-27 at 14 07 52"
src="https://github.com/user-attachments/assets/cd778f42-ade0-4da0-9732-2d8631c04124"
/>
Branch picker for style reference:
<img width="1200" height="815" alt="Screenshot 2026-01-27 at 11 44 03"
src="https://github.com/user-attachments/assets/369b0d29-8fed-4293-98c2-52c2d780fe9a"
/>
Release Notes:
- Git: Improved the project picker in the panel by also displaying the
GIt status icon on them, to clearly indicate which repos have changes.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
- **title_bar: Extract platform_title_bar from title_bar**
- **file_finder no longer depends on search and agent_servers no longer
depend on language_models**
Release Notes:
- N/A
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
The rate limiter's semaphore guard was being held for the entire
duration of a turn, including during tool execution. This caused
deadlocks when subagents tried to acquire permits while parent requests
were waiting for them to complete.
## The Problem
In `run_turn_internal`, the stream (which contains the `RateLimitGuard`
holding the semaphore permit) was kept alive throughout the entire loop
iteration - including during **tool execution**:
1. Parent request acquires permit
2. Parent starts streaming, consumes response
3. Parent starts executing tools (subagents)
4. **Stream/guard still held** while tools execute
5. Subagents try to acquire permits → blocked because parent still holds
permit
6. Deadlock if all permits are held by parents waiting for subagent
children
## The Fix
Two changes were made:
1. **Drop the stream early**: Added an explicit `drop(events)` after the
stream is fully consumed but before tool execution begins. This releases
the rate limit permit so subagents can acquire it.
2. **Removed the `bypass_rate_limit` workaround**: Since the root cause
is now fixed, the bypass mechanism is no longer needed.
Note: no release notes because subagents are still feature-flagged, and
this rate limiting change isn't actually observable without them.
Release Notes:
- N/A
This PR implements a UI for the side-by-side diff, using blocks to align
the two sides and adding a coherent `SplitEditorElement`.
Release Notes:
- N/A
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
This PR improves the performance of the `CopyButton` component by
tracking the copied state locally through a `CopyButtonState` struct
instead of making an OS call every time the component re-renders. Also
pushing a slight improvement here by resetting the state after two
seconds so as to make the check mark go away after you clicked to copy.
Release Notes:
- N/A
## Problem
When subagents use the `edit_file` tool, it creates an `EditAgent` that
makes its own model request to get the edit instructions. These "nested"
requests compete with the parent subagent conversation requests for rate
limiter permits.
The rate limiter uses a semaphore with a limit of 4 concurrent requests
per model instance. When multiple subagents run in parallel:
1. 3 subagents each hold 1 permit for their ongoing conversation streams
(3 permits used)
2. When all 3 try to use `edit_file` simultaneously, their edit agents
need permits too
3. Only 1 edit agent can get the 4th permit; the other 2 block waiting
4. The blocked edit agents can't complete, so their parent subagent
conversations can't complete
5. The parent conversations hold their permits, so the blocked edit
agents stay blocked
6. **Deadlock**
## Solution
Added a `bypass_rate_limit` field to `LanguageModelRequest`. When set to
`true`, the request skips the rate limiter semaphore entirely. The
`EditAgent` sets this flag because its requests are already "part of" a
rate-limited parent request.
(No release notes because subagents are still feature-flagged.)
Release Notes:
- N/A
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
The recently-introduced unified Git picker was previously only available
if you reached for the branch, worktree or stash pickers through the
keybinding. Now, if you click on the title bar's branch button, you'll
also be able to quickly view the worktree and stash pickers.
Release Notes:
- N/A
While at it, annotate more functions that are potentially related to
language parsing in buffers.
Also, on macOS, in order to actually have callstack frames properly
recorded by Tracy, you need to manually run `dsymutil` on the binary.
Release Notes:
- N/A
<img width="611" height="102" alt="Screenshot 2026-01-15 at 4 18 30 PM"
src="https://github.com/user-attachments/assets/ba422cbb-4607-47c7-94c7-77752d7b4479"
/>
When viewing a branch diff (e.g., 'Changes since origin/main'), the
toolbar was hidden because `ProjectDiffToolbar` filters for
`DiffBase::Head` only. This meant users couldn't send review comments to
the Agent panel from the branch diff view.
Now there's a new `BranchDiffToolbar` which:
- Only activates for branch diff views (`DiffBase::Merge`)
- Shows only the 'Send Review to Agent' button (not stage/unstage
controls)
- Only appears when there are review comments (same behavior as the
existing toolbar)
(No release notes because this is still feature-flagged.)
Release Notes:
- N/A
This PR removes the code for the legacy plans.
No more users will be on this plan as of January 17th, so it's fine to
land these changes now (as they won't be released until the 21st).
Closes CLO-76.
Release Notes:
- N/A
Happy New Years! This PR is a second take at
https://github.com/zed-industries/zed/pull/38127 (cc @ConradIrwin)
This PR is significantly less complicated than the last attempt: while
we still keep our data on the `NavigationHistory` object, we no longer
tightly integrate it with the existing back/forward "browser history."
Instead, we keep our own stack of `(origin, target)` pairs (in a struct
to make it easy to extend with e.g., tag names in the future).
The PR is split into two separable commits. Most of the implementation
is in the second commit, which:
- Defines the stack data structure
- Implements `pane::GoToOlderTag` and `pane::GoToNewerTag` in terms of
the stack
- Hooks into `navigate_to_hover_links` to push tag stack entries
This last bit is the most fiddly. The core challenge is that we need to
keep track of the `origin` location and calculate the `target` location
across three codepaths that might involve creating a new editor and/or
splitting the pane. One thing in particular I found difficult was that
an editor's `nav_history` (an `ItemNavHistory`) seems to be populated
asynchronously. Instead of relying on it, I decided in this code to make
my own `ItemNavHistory`. I briefly tried to refactor the code in
question, but it seemed like it would significantly increase the scope
of the change.
I prefer this all-in-one tracking centered around
`navigate_to_hover_links ` to the `start/finish` approach taken in
b69a2ea200
because I find it easier to convince myself that the right data is being
populated at the right times. Of course, let me know if you think
there's a better solution.
Closes#14206
Release Notes:
- ??? I don't know what to write here! Suggestions welcome
Closes#46142
Release Notes:
- Fixed AI commit message button in Git panel being hidden instead of
disabled when no AI provider is configured. The button now remains
visible with a tooltip explaining how to enable the feature.
Screenshot:
<img width="90%" alt="Screenshot 2026-01-10 at 18 16 12"
src="https://github.com/user-attachments/assets/6af9c845-7857-40e1-bfb5-3118f1af8360"
/>
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Doesn't support editing or deleting comments yet, but inputs work:
<img width="797" height="881" alt="Screenshot 2026-01-14 at 11 51 36 AM"
src="https://github.com/user-attachments/assets/746e085b-a919-475a-b804-ee0377e40a0b"
/>
<img width="698" height="178" alt="Screenshot 2026-01-14 at 11 47 51 AM"
src="https://github.com/user-attachments/assets/3edac0e8-62e5-4af5-a324-df2bd293f3ca"
/>
<img width="695" height="695" alt="Screenshot 2026-01-14 at 11 47 58 AM"
src="https://github.com/user-attachments/assets/64795ffd-62b4-48ea-a46c-7724221095d7"
/>
### Features implemented:
- **Local comment storage**: Comments are stored per-hunk in the Editor,
with chronological ordering
- **Expandable comments section**: Shows "N Comments" header that can
expand/collapse
- **Inline editing**: Click edit to transform a comment row into an
editable text field with confirm/cancel buttons
- **Delete functionality**: Remove individual comments
- **Send Review to Agent**: Toolbar button with badge showing comment
count, batch-submits all comments across all files/hunks to the Agent
panel
- **User avatars**: Shows the current user's avatar (from their Zed
account) next to comments, falls back to Person icon when not logged in
- **Visual tests**: Added tests for one comment, multiple comments
expanded, and comments collapsed
Note that this is behind a feature flag, so no release notes yet.
Release Notes:
- N/A
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: David Baldwin <baldwindavid@gmail.com>
This PR introduces a project dropdown when working with multiple
folders/projects in one workspace. Here are some interaction details
that I hope improves the UX of working on this scenario significantly:
- The dropdown shows the currently "active" project, which is determined
by:
- Either the file you're currently editing
- Or the file you have just recently switched to
- Some example cases:
- If you are focused on file from project A but switch to project B in
the titlebar, nothing happens. However, as soon as you type on the file
from project A, the title bar will update and your active project will
return to being project A.
- If you're focused on file from project A and change tabs to a file
from project B, the title bar will update, showing project B as the
active one.
- The content you'll see in the branch picker will correspond to the
currently active project
- It's still possible to reach the "Recent Projects" picker through the
project dropdown
- It's possible to do all interactions (trigger dropdown, select active
project, and remove project from workspace) with the keyboard
https://github.com/user-attachments/assets/e2346757-74df-47c5-bf4d-6354623b6f47
Note that this entire UX is valid only for a multiple folder workspace
scenario; nothing changes for the single project case.
Release Notes:
- Workspace: Improved the UX of working with multiple projects in the
same workspace through introducing a project dropdown that more clearly
shows the currently active project as well as allowing you to change it.
Adds a very simple diff review button behind a feature flag, which
appears in the gutter of people who have the flag (currently just me;
it's not even enabled for staff, since it doesn't do anything yet).
Mostly this PR just adds the feature flag, the button, and tests.
Release Notes:
- N/A
This PR creates a unified picker for all the Git-related pickers:
branch, worktree and stash. The main motivation for this is to bring
awareness and ease of access for the worktree and stash pickers that
were previously (and arguably) hidden amidst the sea of commands in the
command palette. As worktrees in particular become more relevant for
AI-related flows, having an easier way to reach for its picker will be
beneficial.
Note that the actions/commands remain the same; you can still look for
`git: worktree` or `git: view stash`. The difference is that these
actions will take you to the unified picker with the correct
corresponding active view.
https://github.com/user-attachments/assets/99d1cd6f-a19d-47d3-9bca-d7257e7ed5b8
Release Notes:
- Git: Unify the branch, worktree, and stash pickers into one, making it
easier to find and access them from one another.
This happens when a user's default branch has different remote and local
versions on their system. Because we would get a diff using just a
branch name without including it's remote name as well
This is a better default because it's far less confusing from a user's
perspective to debug what's going on.
Release Notes:
- git: Fix BranchDiff showing incorrect diffs when default local branch
is out of sync with the remote default branch
This PR adds some clean up to the worktree picker: making sure that
worktree names render just one line, even when they might have multiple
lines (that was making each line item break for me), removing
superfluous icons, and making the footer controls more consistent with
the branch picker, where the buttons change to "Create..." if you're in
a state where the only match is the one to create a new worktree.
https://github.com/user-attachments/assets/e63aa8c9-b5a0-443d-a2ab-7759daed10d1
Release Notes:
- Git: Fixed some UI bugs in the worktree picker as well as improved the
UX for creating worktrees based off of the current or default branch.
The `vim` crate's tests depend on `git_ui`, which transitively depends
on `recent_projects` with `test-support` enabled. This causes
`recent_projects` to include RemoteConnectionOptions::Mock` variant
handling. However, `git_ui` was not enabling its `test-support` feature,
causing compilation failures when the Mock variant was expected but not
available.
This commit enables the `test-support` feature for both `git_ui` and
`title_bar` dev-dependencies in the `vim` crate, ensuring the Mock
variant is consistently available during testing.
Release Notes:
- N/A
Also improves the commit view to use the same status-based buffer header
visual overrides as the project diff as a driveby.
Fixes https://github.com/zed-industries/zed/issues/45735
Release Notes:
- git: Binary files are no longer shown in garbled form when viewing an
old commit.
The tree view effectively always sorts by status, not by path.
Release Notes:
- Fixed incorrect ordering of paths in the project diff when using the
git panel's tree view.
Additionally this extracts more functionality into the RunnableVariant which is renamed to GpuiRunnable.
Release Notes:
- N/A
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
Co-authored-by: Cole Miller <cole@zed.dev>
Breadcrumb visual reorchestration which makes a couple of key changes:
- Breadcrumbs are now displayed in file headers for multibuffer views.
Singleton buffers are unchanged.
- Multibuffer views now have collapse/expand all buttons available in
the toolbar
- Search in multibuffer views now takes up less space, by occupying the
primary toolbar location erstwhile taken up by breadcrumbs
<img width="1721" height="823" alt="Screenshot 2025-12-22 at 4 15 41 PM"
src="https://github.com/user-attachments/assets/38e924f7-fe9e-4c83-84fb-2eee98137f43"
/>
<img width="1722" height="762" alt="Screenshot 2025-12-22 at 4 15 51 PM"
src="https://github.com/user-attachments/assets/ccc98ca3-75ce-4aca-bceb-890817b0f04d"
/>
Release Notes:
- Moved breadcrumbs to file headers in multibuffer views
- Added collapse/expand all options for multibuffer views
- Improved use of space for multibuffer search by taking the place of
the former breadcrumb toolbar location
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Closes#42217
Release Notes:
- Added/Fixed/Improved ...
added "Create Pull Request" Command when searching on the command
Palette
For more details, please refer to the issue, thank you.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Follow-up to #46001
That initial fix partly addressed the issue for diffs managed by the
`GitStore`, but not for other diffs (e.g. those managed by the
`ActionLog` or `CommitView`). The underlying issue is that we switched
to using a `Buffer` to represent the diff base text, and when updating
the diff we were calling `set_text` on this buffer and not waiting for
reparsing to finish. When the base text was represented by a series of
independent `BufferSnapshot`s, this wasn't an issue because we would
parse the base text in the background as part of computing the diff
update. This PR fixes the issue by waiting on reparsing to finish after
each call to `set_text`.
Release Notes:
- N/A
This PR reworks the (still feature-gated) side-by-side diff view to use
a different approach to representing the multibuffers on the left- and
right-hand sides.
Previously, these two multibuffers used identical sets of buffers and
excerpts, and were made to behave differently by adding a new knob to
the multibuffer controlling how diffs are displayed. Specifically, the
left-hand side multibuffer would filter out the added range of each hunk
from the excerpts using a new `FilteredInsertedHunk` diff transform, and
the right-hand side would simply not show the deleted sides of expanded
hunks. This approach has some problems:
- Line numbers, and actions that navigate by line number, behaved
incorrectly for the left-hand side.
- Syntax highlighting and other features that use the buffer syntax tree
also behaved incorrectly for the left-hand side.
In this PR, we've switched to using independent buffers to build the
left-hand side. These buffers are constructed using the base texts for
the corresponding diffs, and their lifecycle is managed by `BufferDiff`.
The red "deleted" regions on the left-hand side are represented by
`BufferContent` diff transforms, not `DeletedHunk` transforms. This
means each excerpt on the left represents a contiguous slice of a single
buffer, which fixes the above issues by construction.
The tradeoff with this new approach is that we now have to manually
synchronize excerpt ranges from the right side to the left, which we do
using `BufferDiffSnapshot::row_to_base_text_row`.
Release Notes:
- N/A
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: HactarCE <6060305+HactarCE@users.noreply.github.com>
Co-authored-by: Miguel Raz Guzmán Macedo <miguel@zed.dev>
Co-authored-by: Anthony <anthony@zed.dev>
Co-authored-by: Cameron <cameron@zed.dev>
Closes https://github.com/zed-industries/zed/issues/45630
Remote host location alone is not enough to distinguish between remote
worktrees: different remote projects open in different windows will have
the same remote host location and _will_ have the same `WorktreeId`.
Thus, require an associated `WorktreeStore` with all
`WorktreeId`-related trust questions, and store those IDs based on the
store key.
Release Notes:
- Fixed worktree trust handling of multiple projects on the same remote
host
There were several places adding a copy icon button, so thought of
encapsulating the logic to copy a given string into the clipboard (and
other small details like swapping the icon and tooltip if copied) into a
component, making it easier to introduce this sort of functionality in
the future, with fewer lines of code.
All it takes (for the simplest case) is:
```rs
CopyButton::new(your_message)
```
<img width="600" height="714" alt="Screenshot 2025-12-29 at 10 50@2x"
src="https://github.com/user-attachments/assets/e6949863-a056-4855-82d8-e4ffb5d62c90"
/>
Release Notes:
- N/A
Release Notes:
- git: Added the ability to copy a commit's SHA in the commit view.
---------
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
The failure would happen if the current version of the file was open as
an editor. This happened because the git blob and current version of the
buffer would have the same `ProjectPath`.
The fix was adding a new `DiskState::Historic` variant to represent
buffers that are past versions of a file (usually a snapshot from
version control). Historic buffers don't return a `ProjectPath` because
the file isn't real, thus there isn't and shouldn't be a `ProjectPath`
to it. (At least with the current way we represent a project path)
I also change the display name to use the local OS's path style instead
of being hardcoded to Posix, and cleaned up some code too.
Release Notes:
- N/A
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: xipengjin <jinxp18@gmail.com>
Closes#26424
Supersedes #35328
Originally, `git::blame` uses its own `ParsedCommitMessage` as the
source for the commit information, including the PR section. This
changes unifies this with `git::repository` and `git_ui::git_panel` by
moving this and some other commit-related structs to `git::commit`
instead, and making both `git_ui::blame_ui` and `git_ui::git_panel` pull
their information from these structs.
Release notes :
- (Let's Git Together) Fixed the commit tooltip in the git panel not
showing information like avatars.
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
This PR ensures truncation works for the file paths, which should set up
the stage for when the new GPUI `truncation_start` method lands
(https://github.com/zed-industries/zed/pull/45122) so that we can use
for them. In the process of doing so and figuring it out why it wasn't
working as well before, I noticed some opportunities to clean up some UI
code: removing unnecessary styles, making the file easier to navigate
given all of the different UI conditions, etc.
Note: You might notice a subtle label flashing that comes with the label
truncation and that's a standalone GPUI bug that's also visible in other
surface areas of the app. I don't think it should block these changes
here as it's something we should fix on its own...
Release Notes:
- N/A
I could not find any related issue, but at least I want to use the git
panel like this :)
Being used to `lazygit`, this PR makes navigation of the git panel more
similar to the CLI tool.
Instead of selecting -> enter'ing for skimming each file, I just want to
move between the files in the git panel and have the diff multibuffer
advance to the appropriate file. This also adheres to the behavior of
the outline panel, which I like better.
If the multibuffer is not active, it behaves same as before (just
selecting the file in the panel, nothing else).
I did not modify existing `menu::Select*` actions in case anybody still
prefers previous behavior.
https://github.com/user-attachments/assets/2d1303d4-50c8-4500-ab3b-302eb7d4afda
Release Notes:
- Improved navigation of the git panel, by advancing the "Uncommitted
Changes" multibuffer to the current selected file. To restore the old
behavior, you can bind `up` and `down` to `menu::SelectPrevious` and
`menu::SelectNext` under the `GitPanel` context in your keymap.
Co-authored-by: Cole Miller <cole@zed.dev>
Closes #ISSUE
Problem:
- The status bar’s pending keystroke indicator (shown next to --NORMAL--
in Vim mode) didn’t clear when focus moved to another context, e.g.
hitting g in the editor then clicking the Git panel. The keymap state
correctly canceled the prefix, but observers that render the indicator
never received a “pending input changed” notification, so the UI kept
showing stale prefixes until a new keystroke occurred.
Fix:
- The change introduces a `pending_input_changed_queued` flag and a new
helper `notify_pending_input_if_needed` which will flushes the queued
notification as soon as we have an App context. The
`pending_input_changed` now resets the flag after notifying subscribers.
Before:
https://github.com/user-attachments/assets/7bec4c34-acbf-42bd-b0d1-88df5ff099aa
After:
https://github.com/user-attachments/assets/2264dc93-3405-4d63-ad8f-50ada6733ae7
Release Notes:
- Fixed: pending keybinding prefixes on the status bar now clear
immediately when focus moves to another panel or UI context.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#45033
This bug happened because the deletion icon would use the selected entry
index to choose what branch to delete. This works for all cases except
when hovering on an entry, so the fix was passing in the entry index to
the deletion button on_click handler.
I also disabled the deletion button from working if a branch is HEAD,
because it's an illegal operation to delete a branch a user is currently
on.
Finally, I made WeakEntity<Workspace> a non-optional field on
`BranchList` because a workspace should always be present, and it's used
to show toast notifications when a git operation fails. The popover view
wouldn't have a workspace before, so users wouldn't get error messages
when a git operation failed in that view.
Release Notes:
- git: Fix bug where branch list deletion button would delete the wrong
branch