Update the way `CollapseSelectedEntry` works such that, if the selected
entry is a file within a directory, it'll find the nearest parent
directory that isn't collapsed and collapse that, moving the selected
entry to that folder as well.
This brings the behavior of the Git Panel closer to what already happens
in the Project Panel today.
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.
# 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
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.
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>
## 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>
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
## 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
# 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.
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
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
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.
## 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>
# Objective
Make the branch picker easier to scan and ensure branch creation and
remote icons behave consistently across All, Local, and Remote filters.
## Solution
- Group local and remote branches under their own headers in the All
filter.
- Place the create-branch option above branch sections when there is no
exact branch-name match.
- Resolve each remote's hosting provider from its URL and show the
provider icon for branches from that remote.
- Include remote URLs in remote-workspace repository responses so
arbitrary remote names work without hardcoding `origin` or `upstream`.
## Edge Cases Fixed
- An exact branch can exist outside the active Local or Remote filter.
The picker now checks all branches before offering to create a duplicate
branch.
- A non-exact search can return fuzzy branch matches and a create
action. The create action now stays at the top, before the Local and
Remote section headers.
- When a filtered search has no branch matches, the create action is
shown without incorrectly placing it under a Local Branches or Remote
Branches header.
- Repositories can use any remote name, not only `origin` and
`upstream`. Provider icons are resolved independently for every
configured remote.
- Remotes hosted on an unknown or unsupported forge use the generic
server icon instead of implying a desktop or a specific provider.
- Remote-workspace repositories carry the same remote-name-to-URL data
as local repositories, so their branch icons follow the same
provider-resolution path.
## Testing
- `cargo check -p git_ui --no-default-features`
- Branch picker test suite (17 tests)
- `git diff --check`
Tested on macOS.
## 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="560" height="522" alt="Screenshot 2026-07-17 at 11 19 27 PM"
src="https://github.com/user-attachments/assets/28d57315-b859-4a8d-86ca-53f9fb513bf5"
/>
The updated branch picker groups local and remote branches, keeps the
create-branch action above those sections, and shows forge-specific
icons for remote branches.
---
Release Notes:
- Improved branch picker filtering, grouping, branch creation
suggestions, and remote-provider icons.
# Objective
When using column Git blame with avatars enabled, blame entries whose
author name is the longest in the buffer can exceed the blame border.
For example, line 10 of `crates/vim/src/visual.rs` is displayed as
follows:
<img width="998" height="121" alt="issue"
src="https://github.com/user-attachments/assets/eff3e1ff-bd1c-42af-ae9b-da8efb0a7c22"
/>
The blame contents exceeds the width.
The root cause is in the blame width calculation:
0c51c7fd24/crates/editor/src/editor.rs (L11583-L11598)
The calculation accounts for the commit SHA, author name, and timestamp.
Other elements, including spacing, margins, and the avatar, are
represented by the fixed `SPACING_WIDTH` constant.
For typical fonts, `ch_advance` is approximately `0.5rem` to `0.6rem`,
so `SPACING_WIDTH` provides approximately `2rem` to `2.4rem` for
non-text content. However, the avatar itself occupies `1rem`:
0c51c7fd24/crates/ui/src/components/avatar.rs (L81)
When avatars are displayed, the entry also contains three `0.5rem` gaps
and also one `0.5rem` right margin:
0c51c7fd24/crates/git_ui/src/blame_ui.rs (L170-L188)
This requires approximately `3.0rem`, which can exceed the space
provided by `SPACING_WIDTH`. When an entry contains both the longest
author name in the buffer and a long timestamp, its content can
therefore exceed the blame border.
## Solution
The simplest fix would be to increase `SPACING_WIDTH`, but that would
still rely on an approximate conversion between editor character widths
and UI dimensions.
Instead, this PR adds a method to the blame renderer for calculating the
non-text width of a blame entry. The editor uses this value together
with the measured text width when calculating the final blame width.
## Testing
Tested locally. A before-and-after comparison is included below.
## 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
| Before | After |
| :--: | :--: |
| <img width="551" height="94" alt="Before"
src="https://github.com/user-attachments/assets/b6741a41-6531-4fae-adaa-f9ae0b298e0f"
/> |<img width="566" height="93" alt="After"
src="https://github.com/user-attachments/assets/e8d75d2a-6b07-43f6-b2a8-bfb76d118611"
/> |
Release Notes:
- Fixed Git blame entries overflowing the gutter when avatars are
displayed.
this pr enables opening a specific line in a diff using zed's cli
Release Notes:
- refactor: add possibility to open specific line in a diff using the
cli
---------
Co-authored-by: Cole Miller <cole@zed.dev>
# Objective
- Show accurate diff stats for each staged and unstaged projection of a
partially staged file in the Git panel.
- This was originally considered for
https://github.com/zed-industries/zed/pull/59884, but was scoped out of
that already-large PR and is being submitted separately as discussed
there.
## Solution
- Collect HEAD-to-index and index-to-worktree diff stats alongside the
existing combined HEAD-to-worktree stats.
- Carry the staged and unstaged stats through repository status
snapshots and remote status serialization.
- Use the stat matching the projected Git panel section while preserving
the combined stat for the other grouping modes.
- Update the fake Git repository and add regression coverage with
deliberately different staged and unstaged counts.
## Testing
- `cargo check -p git_ui`
- `cargo check -p collab`
- `cargo test -p git_ui
test_group_by_staging_section_membership_and_order --lib`
- `cargo test -p project --lib --no-run`
- `cargo fmt --all -- --check`
- `git diff --check`
## 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 diff stats for partially staged files in the Git panel
This PR removes the commit preview popover when hovering over rows in
the git graph. In my humble opinion, I've been finding that having the
hover preview damages the usability/readability of the graph. I can't
properly read each row's content and understand its place on the graph
if everywhere I rest my cursor in a popover appears... Moreover, almost
all of the information we display in the commit preview is already
displayed in the row itsself, and if you'd like to drill down into the
commit description and whatnot, clicking the row opens the commit drawer
and gives you that and even more information (e.g., set of changed
files, etc.).
Release Notes:
- N/A
Follow-up to zed-industries/zed#60721.
The Taffy 0.12 upgrade exposed that the message height limit was applied
to its grid parent while percentage-sized children retained the Markdown
content's intrinsic height. Long messages therefore painted over the
changed-files summary instead of scrolling.
Move the height limit to the scroll container itself, matching the
commit view. Add a GPUI regression test that verifies the viewport stays
bounded, remains scrollable, and does not overlap the changed-files
list.
> On `main`:
<img width="697" height="873" alt="Screenshot 2026-07-17 at 14 59 21"
src="https://github.com/user-attachments/assets/51e6cc0e-aeac-4ad1-a6af-2120efcef901"
/>
---
Release Notes:
- N/A
# Objective
Add remote (SSH) and collaboration support for trashing and restoring
files in the project panel, which in turn enables undo/redo of trash
operations against remote and collab projects.
Relates to #5039.
## Solution
- Updated the project panel undo system to carry `TrashId` instead of
`TrashedEntry`.
- Using `TrashedEntry` could get hairy, as it includes paths, which
wouldn't play too nicely when using, for exapmle, macOS as the client
and Windows as the host. Using a simple identifier is much easier in
this regard and simplifies implementation.
- Enabled the Trash action and context-menu entry on remote projects,
and removed the command palette filter in `ProjectPanel::new` that was
still hiding the action on remote.
- As far as I can tell, there isn't a reliable way to detect whether a
given remote actually supports the OS trash, so we expose the action
everywhere rather than guessing. On a remote without trash support the
action will fail when invoked but this is a conscious tradeoff until we
find a better way to handle this.
- `fs` now tracks trashed files in a `SlotMap<TrashId, TrashedEntry>` on
each `Fs` implementation. Trashed files are referenced by an opaque
`TrashId` instead of passing a `TrashedEntry` around, which avoids
serializing filesystem paths in remote messages.
- Split the old `delete_entry(trash: bool)` API into distinct
`trash_entry`/`trash_file` (returning a `TrashId`) and
`delete_entry`/`delete_file` across `Project`, `Worktree`,
`LocalWorktree` and `RemoteWorktree`.
- This lets us drop the optional trash result (`Option<TrashedEntry>`)
from the delete path and require a `TrashId` from the trash path.
- Added new proto messages (`TrashProjectEntry`,
`TrashProjectEntryResponse`, `RestoreProjectEntry`,
`RestoreProjectEntryResponse`) to let clients request the host to trash
or restore entries.
- This deprecates `DeleteProjectEntry::use_trash`, but the host still
honors it. An older collab peer may request trashing via that flag
instead of the newer `TrashProjectEntry`. If the host ignored it, a
newer host would permanently delete a file the user meant to send to the
trash. The field will be removed in a later PR once all supported peers
use `TrashProjectEntry`.
## Testing
The following tests were introduced to ensure the new behavior is
correctly tested:
* `remote_server::remote_editing_tests::test_remote_trash_restore` –
Tests trashing a project entry in remote
*
`remote_server::remote_editing_tests::test_remote_delete_project_entry_with_trash`
– Test to ensure we continue respecting `DeleteProjectEntry::use_trash`
until it is fully removed
* `project_panel::tests::undo::trash_directory_undo_redo` – Not related
to these changes but a nice to have as we were missing a test ensuring
that trashing and then undoing and redoing it for a directory works as
expected
Besides these, the following scenarios were manually tested against a
remote session on the same machine (macOS):
- Trashing → Undo (Restore) → Redo (Trashing)
- Batch Trashing → Undo (Batch Restore) → Redo (Batch Trashing)
- Rename → Undo (Rename) → Redo (Rename)
- Move → Undo (Move) → Redo (Move)
- Batch Move → Undo (Batch Move) → Redo (Batch Move)
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] 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
- [ ] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Yara <git@yara.blue>
This is necessary to remove some `util` dependencies from crates, as
well as better sharing for our projects. This also includes the WIP
AbsPath abstraction as well as some bug fixes from internal tooling.
Release Notes:
- N/A or Added/Fixed/Improved ...
Follow up to https://github.com/zed-industries/zed/pull/59884
This PR refines how the git panel behaves when grouping changes by
staging state, with a focus on making staging workflows predictable and
conflict resolution safe.
- Renamed the "Group By" menu options to describe what you actually see:
**"Tracked & Untracked"** (was "Status") and **"Staged & Unstaged"**
(was "Staging").
- When grouping by staged & unstaged, both sections now stay visible
even when empty, showing a placeholder message ("No staged changes yet"
/ "No unstaged changes"). Previously an empty section disappeared
entirely, which made the panel layout jump around as you staged and
unstaged files, and made it harder to tell at a glance that nothing was
staged yet.
- Section header controls are now consistent checkboxes everywhere
(previously a mix of checkboxes and +/− icon buttons), with "Stage All"
/ "Unstage All" tooltips. Headers of empty sections render no checkbox
and don't react to clicks or hover. I appreciate the debate that
happened in the PR linked above about this but I was personally having a
hard time understanding what was the difference in interaction given the
action was exactly the same, we were just having different UIs, which
looked inconsistent.
- Arrow-key navigation now skips over section headers and empty-section
placeholder rows in both flat and tree view, instead of getting stuck or
selecting non-interactive rows — including when jumping to the first or
last entry.
- In the staged & unstaged grouping, a partially staged file appears in
both sections. Each row's checkbox and tooltip now follow the section
it's rendered in: rows in Staged always unstage, rows in Unstaged always
stage — including via shift-click range operations, which now also
support bulk *unstaging* within the Staged section (previously ranges
could only stage). The context menu's Stage/Unstage label follows the
same rule and stays in sync with in-flight staging operations.
- Conflicted files are grouped by whether the current merge marked them
conflicted (rather than raw status), so a conflict you've resolved stays
visible under "Conflicts" until the merge concludes. On top of that,
resolution is now one-way in the UI:
- Ticking a conflicted file's checkbox marks it resolved (stages it).
Once resolved, the checkbox is disabled with a "Conflict marked as
resolved" tooltip — unticking it would silently discard git's record of
the unmerged base/ours/theirs versions, a round-trip git can't actually
perform.
- The same lock applies everywhere the file can be reached: the keyboard
toggle, folder checkboxes in tree view, the Conflicts section header
(disabled once all conflicts are resolved), "Stage All"/"Unstage All" on
the Staged/Unstaged headers, and shift-click range sweeps — none of them
will resolve or un-resolve a conflict as a side effect.
- The explicit `git: unstage file` action still works as a deliberate
escape hatch.
---
Here's a video, where you can see I stage and unstage whole files, make
a partial staging, and get into a merge-conflict state, where the
conflicted files are tagged as resolved:
https://github.com/user-attachments/assets/d27ef9c6-5691-45c1-91ab-c3b152aaaa60
---
Release Notes:
- N/A _(given the feature hasn't been released yet_)
This PR adds a series of design improvements to the branch picker,
including:
- Consistent icon used for filter actions
- A keybinding/action to trigger the filter menu with the keyboard
- Filter menu positioning depending on the picker's editor position
- Error display that displays the full label without truncation/tooltip,
and is placed accordingly also depending on the picker's editor position
- List subheader in the search list depending on filtered option
Here's a quick video:
https://github.com/user-attachments/assets/70922daf-fc9f-4d94-bed8-c84d3ea73534
- - -
Release Notes:
- N/A
This PR is a collection of grab bag UI design refinements across the
entire app. Most of them are minor icon fixes/standardizations, spacing,
and sizing tweaks.
The one change that ended up getting a bit bigger than I initially
anticipated is the debugger panel tabs improvements; added a bunch of
tweaks there to make it look slicker. A relevant change is a small
one-line change to the GPUI div element where it wouldn't add drag-over
styles to elements that aren't initially a hitbox target. Given I wanted
to pull off the drop indicator you see on the video below, this turned
out to be needed:
https://github.com/user-attachments/assets/964b456a-eef0-42bb-a433-7dac54ab8ec8
---
Release Notes:
- N/A
Fetch tag names for commits included in blame data and pass them through
the blame rendering path. Render tag names as chips in the blame hover
tooltip and expanded blame popover. Tag lookup is best-effort, so blame
still renders if tag lookup fails.
> Note: Tag names are currently only fetched for local repositories. For
remote projects (SSH) and collab sessions, blame data travels over the
`BlameBufferResponse` proto message, which doesn't carry tag names yet.
## Testing
- `cargo test -p git
test_parse_tag_names_for_lightweight_and_annotated_tags`
- `cargo check -p git_ui`
- `cargo check -p editor`
- `cargo check -p project`
Manual testing:
- Opened `git: blame` on a file with a tagged commit.
- Verified tag chips are shown in the blame hover tooltip and expanded
popover.
## 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:
<img width="1655" height="660" alt="before"
src="https://github.com/user-attachments/assets/dbefd729-f8df-48a9-8249-83c93518fe76"
/>
After:
<img width="1655" height="660" alt="after"
src="https://github.com/user-attachments/assets/2c1097de-b268-45d9-9d13-0f3e06058603"
/>
---
Release Notes:
- Git: Made tags visible in Git blame tooltips.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This PR reworks how multi-select mode is rendered in pickers (only used
by the file finder and text finder).
The "Multi Select" entry previously lived inside the footer's Actions
menu, which was hard to discover and its toggle checkmark misaligned the
menu's keybinding column. This PR changes to an icon button at the
far-roght edge of the search editor, with a tooltip showing the
keybinding to toggle it.
Also made each list item use the actual Checkbox component instead of a
bespoke re-implementation of it. And in doing so, added a few design
improvements to the list item so that it received the checkbox while
preserving proper styles for each interaction state, as well as
displaying the keybinding to select the item or check the item.
Here's a quick video, showing these changes off:
https://github.com/user-attachments/assets/e142f7d1-87ba-4258-844b-953ed06237bd
Release Notes:
- Improved multi-select in the file finder and text finder: the toggle
now lives in the search bar with a `cmd-shift-s` keybinding, and
selection checkboxes render inside list items.
Fixes menu a11y, and adds landmarks with `F6`-navigation.
Also fixes a GPUI bug, and adds debug actions for dumping a11y tree
info.
Since `F6` was already in use by the pause debugger keybind, also
tightens up the debugger keybind context so they require an active
debugger session. When there is one active, `F6` stays as pause
debugger. `ctrl-F6` always works to go to the next landmark.
Also adds an "accessible mode" setting. Currently, this only controls
whether we show all menus all the time, but I suspect it will expand
significantly in the future.
Also adds `.aria_keyshortcuts()` API, but it's not wired up within
accesskit adapters, so is not yet reported to screen readers.
---
Release Notes:
- N/A or Added/Fixed/Improved ...
The branch picker collapses remote branches that are tracked by a local
branch (e.g. `origin/main` when local `main` tracks it). That makes
sense for checkout, where the remote ref is redundant, but it was also
applied to the branch diff base picker, where `main` and `origin/main`
can point to different commits. As a result, once you switched the diff
base from `origin/main` to `main`, there was no way to switch back.
The tracked-remote collapsing is now only applied in checkout mode (no
changed here). The select (diff base) picker lists both local branches
and their remote upstreams.
Release Notes:
- Fixed remote branches (e.g. `origin/main`) not appearing in the branch
diff base picker, making it impossible to switch back after changing the
base to another branch.
# Objective
Make branch filtering consistent and more flexible across the title bar
and Git panel branch pickers.
## Solution
- Replace the remote-only filter toggle with a dropdown for all, local,
and remote branches.
- Preserve the selected filter across branch picker instances.
- Add a ListFilter icon and active-filter indicator.
- Prevent nested filter-menu interactions from dismissing the parent
picker.
- Cycle through all, local, and remote filters with the existing
keyboard shortcut.
## Testing
- Ran `cargo check -p git_ui --tests --no-default-features`.
- Verified formatting with `cargo fmt -p git_ui`.
- Manually checked the filter dropdown from the title bar and Git panel.
## 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
- Filters: All, Local, Remote
- "Cmd + Shift + I" to cycle over the filters
<details>
<summary>New Branch Picker Filter Dropdown</summary>
<img width="1624" height="1030" alt="Screenshot 2026-07-12 at 3 53
30 PM"
src="https://github.com/user-attachments/assets/1323d9c9-f4b9-41ee-ba93-841299872c02"
/>
<img width="1624" height="1030" alt="Screenshot 2026-07-12 at 3 54
35 PM"
src="https://github.com/user-attachments/assets/839345ff-de3b-48f0-b4e7-0f8d27e94204"
/>
</details>
Release Notes:
- Improved branch filtering with local, remote, and all-branch options
in the branch picker.
# Objective
`GitPanel::entry_label` builds file-name labels directly from `git
status` output without calling `.single_line()`. A raw newline in a file
name splits its row across multiple visual lines in the Changes panel.
## Solution
- Add the missing `.single_line()` call in `entry_label`, matching the
behavior in `project_panel.rs`.
## Testing
- Created a git repo with an untracked file whose name contains a
literal newline byte and confirmed the Changes panel now renders it on
one line, collapsing the newline to `⏎` like the project panel already
does.
## 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
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
# Showcase
Before:
<img width="441" height="216" alt="image"
src="https://github.com/user-attachments/assets/921e5aad-01f9-49fd-89b1-f7270e2d203c"
/>
After:
<img width="447" height="206" alt="image"
src="https://github.com/user-attachments/assets/1c09af36-ccf1-434a-be20-0ea2c5d232d5"
/>
Release Notes:
- Fixed file names containing newlines rendering across multiple
lines in the Git Panel.
The unstaged diff view introduced in the partially staged changes commit
only had a Stage button but no Restore option. This adds:
- A per-hunk Restore button in the inline hunk controls (disabled for
new files)
- A Restore button in the toolbar for selected hunks
- A Restore All button in the toolbar to discard all unstaged changes
- A restore method override on UnstagedDiffDelegate for the Restore
action
Release Notes:
- Added restore buttons to the unstaged diff view for discarding
unstaged changes.
# Objective
New unstaged and staged diffs were added in #46541 . However for
unstaged changes, only option available is to stage a change. It would
also be a common use case to restore the changes. (Like how it is done
in uncommitted changes).
## Solution
- A per-hunk Restore button in the inline hunk controls (disabled for
new files)
- A Restore button in the toolbar for selected hunks
- A Restore All button in the toolbar to discard all unstaged changes
- A restore method override on UnstagedDiffDelegate for the Restore
action
## Testing
Tested in locally and ensured both features work
## Self-Review Checklist:
- [ ] 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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
## Showcase
<img width="1141" height="635" alt="Screenshot 2026-07-09 at 9 00 47 AM"
src="https://github.com/user-attachments/assets/b1d3f091-9f1d-49c6-87e6-9efad25e62dd"
/>
## Note
I am still learning rust bit by bit. Please let me know if something is
massively wrong. This is assisted by AI but reviewed by me with best of
my knowledge.
---
Release Notes:
- Added restore buttons to the unstaged diff view for discarding
unstaged changes.
---------
Signed-off-by: Pranav <pranav10121@gmail.com>
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
# Objective
- Add a view option for group by staging.
## Solution
- Add a new option for group_by under git_panel view options, with 2
sections "Staged" and "Unstaged", with buttons (+/-) to stage and
unstage
## Testing
- cargo check -p git_ui
## 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="1679" height="1140" alt="Screenshot 2026-06-25 at 2 09
44 PM"
src="https://github.com/user-attachments/assets/1b605cad-7792-4823-983c-ada41be25504"
/>
---
Release Notes:
- Added group by staging view option
---------
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
This PR fixes a few History tab edge cases in the Git Panel.
For a fresh repo with no commits, the History tab now finishes loading
and shows No commits yet instead
of sitting on Loading… indefinitely or falling into a misleading
empty/error state.
It also fixes detached HEAD history loading. In that case, the Git Panel
asks the backend to load history
from the current commit SHA. The local git backend was accidentally
treating the raw object ID bytes as a
string instead of formatting them as a normal hex SHA, so git log could
fail before returning any
commits. The backend now passes the SHA in the format git expects.
**Repro for empty repo:**
mkdir /tmp/zed-empty-history
cd /tmp/zed-empty-history
git init
zed .
Open Git Panel → History.
Before: History could stay stuck on Loading….
After: History shows No commits yet.
**Repro for detached HEAD:**
mkdir /tmp/zed-detached-history
cd /tmp/zed-detached-history
git init
echo hi > file
git add file
git commit -m initial
git checkout --detach HEAD
zed .
Open Git Panel → History.
Before: History could fail to load commits.
After: History shows the commit history normally.
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:
- Fixed Git history tab states for empty repositories and detached HEAD
history.
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Fixes#53527.
## Summary
- Suggest `untitled.<extension>` when saving an untitled editor buffer
with a selected non-Plain Text language.
- Preserve the existing title-based suggestion for existing files, Plain
Text buffers, and buffers without a language extension.
- Add a regression test for an untitled Rust buffer suggesting
`untitled.rs`.
## Testing
- `mise exec rust@1.95.0 -- cargo fmt --check -p editor`
- `mise exec rust@1.95.0 -- cargo test -p editor
test_suggested_filename_uses_language_extension_for_untitled_buffer
--lib`
## Suggested .rules additions
None.
Release Notes:
- Fixed Save As suggestions for untitled buffers with a selected
language.
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
## Summary
Fixes#60288 and #60454 .
After a push, the push toast's "Create Pull Request" button fails with
`Unsupported remote URL` when the repository's remote is not a plain,
recognized host. This restores the pre-#53913 behavior as a fallback:
use the create-PR/MR link that `git push` itself prints, and only build
a URL from the provider registry when the push output had no link.
## Why this matters
#53913 made the button always appear and changed `create_pull_request`
to reconstruct the PR URL from the remote via
`git::parse_git_remote_url` against the `GitHostingProviderRegistry`.
When the remote is not recognized, parsing returns `None` and the action
errors. This affects self-hosted GitLab/GitHub, an SSH-config host alias
like `git@personal:owner/repo` (the duplicate #60076), and any
non-standard host. Before #53913, the flow used the link git prints in
the push output, which works regardless of host, so this is a regression
for anyone not pushing to a plainly-recognized GitHub URL.
## Solution
`git push` prints a `remote:` line with the hosting provider's
create-PR/MR URL (GitHub: "Create a pull request for '\<branch>' on
GitHub by visiting:", GitLab: "To create a merge request for \<branch>,
visit:", Bitbucket: "Create pull request for \<branch>:"), and we
already hold the push `RemoteCommandOutput`.
- `remote_output.rs`: add `extract_pull_request_url`, which scans the
push stderr for the first `http(s)` URL on a `remote:` line tied to a
create-PR/MR prompt. It ignores unrelated URLs (for example the OpenSSH
post-quantum warning line).
- `git_panel.rs`: capture that URL in `show_remote_output` into
`pending_pull_request_url`, and prefer it in `create_pull_request`,
falling back to the existing provider construction only when the push
output had no link. The cached URL is consumed once (`take()`) and
cleared when the active repo, the active branch/head, or the pending
remote operation changes, so a later `git: Create Pull Request` action
never opens a stale URL from an earlier push.
Recognized GitHub remotes are unaffected: they still get a link from the
push output, with the provider path as the fallback.
## Testing
Unit tests in `remote_output.rs` cover `extract_pull_request_url` for
the GitHub, GitLab, and Bitbucket prompt formats, the no-link case
(returns `None`, so the provider fallback runs), and an output
containing an unrelated URL that must not be mistaken for the PR link.
The existing remote-operation test also asserts the cached URL is
cleared when a new operation starts.
`cargo test -p git_ui remote_output` passes (5 tests). Tested on macOS.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- Fixed "Create Pull Request" button in the toast shown after `git:
push` failing for repositories on unrecognized Git hosts by using the
link printed in the push output.
- Fixed the button shown on the toast after `git: push` for GitLab
branches with an existing merge request. It now shows "View Merge
Request" and links to the existing merge request.
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
# Objective
Ensure that all existing panels have corresponding menu items in the
"View" menu. I was onboarding a friend to Zed yesterday that was having
a hard time figuring out how to interact with the Agent. Although he did
open the "View" menu, I noticed that the Agent panel item was missing
from there, making it hard for new users to discover it exists.
## Solution
* Add both "Agent Panel" and "Git Panel" entries to the menu items for
the "View" app menu.
* Update the action used for the "Terminal Panel" menu item from
`terminal_panel::ToggleFocus` to `terminal_panel::Toggle` to ensure we
display a shortcut for this menu item.
* Another valid option would be to update the default keymap to use
`terminal_panel::ToggleFocus` instead but that would probably break
existing user's expectations that the default shortcut toggles the
terminal panel, instead of toggling its focus.
* Introduce `zed_actions::git_panel` to be able to extract its
`ToggleFocus` action, following the existing pattern.
### Next Steps
It's worth noting that, even though there's now an "Agent Panel" item
mapped to the `assistant::ToggleFocus` action, its default keybinding is
not displayed (at least on macOS), because of the way it's defined as
`cmd-?` . Using `cmd-shift-/` instead doesn't work, so we'll likely have
to update `MacKeyboardMapper` to allow mapping between shifted and
unshifted keys equivalent, that is, when `?` is detected, it is able to
determine that, in the user's layout that is the result of `shift-/`.
## Testing
Manually tested, screenshots can be seen in the "Showcase" section.
## 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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
## Showcase
<details>
<summary>Before</summary>
<img width="488" height="946" alt="CleanShot 2026-07-03 at 14 24 35@2x"
src="https://github.com/user-attachments/assets/58b0497c-2929-4da3-86b6-a2e0ce0c5ca4"
/>
</details>
<details>
<summary>After</summary>
<img width="524" height="1116" alt="CleanShot 2026-07-03 at 14 24 59@2x"
src="https://github.com/user-attachments/assets/8e2c6320-97ad-4620-b595-182f6d0ded81"
/>
</details>
---
Release Notes:
- Added "Agent Panel" and "Git Panel" items to the "View" menu
# Objective
- Make Git Panel History show commit tags so release/version markers are
visible without opening the full Git graph or commit details.
## Solution
- Store commit history entries with both the commit SHA and tag names
from existing git graph data.
- Render tag names as muted chips next to the commit subject.
- Limit visible tags to 3 per commit and show `+N` for additional tags.
## Testing
- Ran `cargo check -p git_ui`.
- Manually verified on Linux with `script/zed-local --stateful .`.
- Confirmed tags appear in Git Panel 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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
Git Panel History now shows commit tags inline as muted chips next to
the commit subject.
---
Release Notes:
- Added tag labels to the Git Panel commit history.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This PR adds adjustments to the tree view, making it more consistent
with all other tree view displays in the app (e.g., displaying indent
guides, removing chevron toggle, etc.), and also fixes an issue where
the commit message scrollbar was scrolling up with the message.
Release Notes:
- N/A
This PR explores the addition of a new feature and UI to improve
visibility into partially staged commits.
Currently, the Git panel shows tracked and untracked changes, but it
does not clearly distinguish between staged and unstaged changes.
As a result, it’s difficult to quickly see which changes are not staged
in the current UI. Both staged and unstaged changes are combined into
the `Uncommitted Changes` multibuffer. This developer experience differs
from other editors, most notably VS Code; which presents separate Staged
Changes and Changes lists.
### Staged and unstaged diffs in multibuffers
This PR introduces an alternative UI for unstaged changes that aligns
with the overall Zed experience. Instead of showing changes on a
per-file basis, staged and unstaged diffs are each displayed in their
own multibuffers, similar to how `Uncommitted Changes` currently works.
For example the following screenshot shows the current `Uncommitted
Changes` on the left, the `Staged Changes` in the middle and the
`Unstaged Changes` buffer on the right for comparison
<img width="1408" height="859"
src="https://github.com/user-attachments/assets/aa709f7a-041d-4cb1-95d6-84c0f5fff688"
/>
### Indicators/interactions
The new multibuffers can be opened in two ways:
1. Via a new `U` chip, which appears when a file has unstaged changes
2. Via new menu options
(See screenshots below for both interaction paths.)
<table>
<tr>
<td style="text-align: center; vertical-align: top;">
<p>via the chip</p>
<img
height="400"
src="https://github.com/user-attachments/assets/3ef69f02-b787-499c-959a-25f50b3728e8"
alt="Via the chip"
/>
</td>
<td style="text-align: center; vertical-align: top;">
<p>via the menu</p>
<img
height="400"
src="https://github.com/user-attachments/assets/f5be8b6d-ccdc-4420-bd29-75570b558016"
alt="Via the menu"
/>
</td>
</tr>
</table>
### Design goals
- minimally intrusive UI changes (small new badge and menu items)
- adhere by Zed'ism (use multibuffer where possible)
- avoid disabling any current interactions (Uncommitted Changes ui is
unchanged)
- avoid introducing an app level view mode (no new settings needed)
### Experience goals
- make it easy to see what changes are not staged
- make it easy to see that a file has unstaged changes (avoid developers
accidently leaving out changes in a commit; a personal issue that I have
when using Zed)
- elegantly handle large file's unstaged changes (follows the same
collapse and expanding seen in `Uncommitted Changes`)
### How to try
- Clone the repo and run `cargo run`
- Make a change to a file and stage it
- Make another change to the file (the `U` indicator will appear)
- Click the `U` to see the unstaged view
### Open questions/rough edges
- [ ] determine if this user experience is useful for others
- [ ] ensure all interactions work as expected (response to all update
cases)
In general I'm really interested in hearing the community's feedback
about this interface, more than happy to make any changes or explore a
different solution!
### Related issue:
- https://github.com/zed-industries/zed/pull/36646
- https://github.com/zed-industries/zed/issues/26560
Release Notes:
- Support partially staged commit multibuffers via a staged and unstaged
changes view.
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cole Miller <cole@zed.dev>
This PR adds a bunch of design improvements to the toolbar of (tab)
views that display diffs: the uncommitted changes, branch diff, and
agent diff tabs. This involves adjusting spacing, sizing, and other
small tweaks across all of these views, including touching up the
divider component API a little bit, adjusting Git icons design, adding
diff stat numbers to the uncommitted changes tab so its consistent with
the others, and more (e.g., moving the split buttons into its own
component to ensure they look the same across all uses). Ended up also
going on a slight de-tour to make all uses of the split button in the
Git panel consistent design-wise.
All in all, this is just tidying up the design of all of these surfaces
that are all relatively similar.
| Branch Diff | Uncommitted Diff | Single-file Diff | Git Panel |
|--------|--------|--------|--------|
| <img width="800" alt="Screenshot 2026-07-06 at 11 25@2x"
src="https://github.com/user-attachments/assets/4ebf87e7-c52d-41d9-9de3-7944125114a1"
/> | <img width="800" alt="Screenshot 2026-07-06 at 11 25 2@2x"
src="https://github.com/user-attachments/assets/51ccd2eb-904b-455a-a708-b4cb50b3a7cb"
/> | <img width="800" alt="Screenshot 2026-07-06 at 11 26@2x"
src="https://github.com/user-attachments/assets/6ae7df68-d1bd-4d36-a250-ba16e43c4e8e"
/> | <img width="800" alt="Screenshot 2026-07-06 at 11 26 2@2x"
src="https://github.com/user-attachments/assets/e032bc60-4551-41f0-b578-90ed305167c2"
/> |
Release Notes:
- Added diff stat numbers to the uncommitted changes view.
# Objective
Prevent collapsing a folder in one Git panel section from also
collapsing the same folder path in other sections.
## Solution
Key directory expansion state by `TreeKey`, which includes both the
section and repository path, instead of by `RepoPath` alone. This also
keeps persisted tree state, stale-state cleanup, and selected-file
reveal behavior section-aware.
## Testing
- Added `test_tree_view_directory_expansion_is_scoped_to_section` to
cover the same folder path under Tracked and Untracked independently.
- `cargo fmt -p git_ui -- --check`
- `git diff --check`
- Attempted `cargo test -p git_ui
test_tree_view_directory_expansion_is_scoped_to_section --lib`, but
dependency compilation could not complete because the local disk ran out
of space. Reviewers can run that command to execute the focused
regression test.
## 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
## Suggested .rules additions
- In the Git panel tree view, key per-row UI state by `TreeKey` rather
than `RepoPath`, because the same directory can appear in multiple
sections.
---
Release Notes:
- Fixed collapsing a folder in one Git panel section also collapsing it
in other sections.
# Objective
Fixes#57766
Allow users to select and copy the text of commit messages from the git
graph details panel.
## Solution
Implements selectable commit message in the detail panel using
`MarkdownElement`s a la `commit_view`.
### Affordances considered and abandoned:
- "copy message" and/or "copy subject" buttons, but the UI here is
already pretty tight and I don't feel confident enough in my design
chops or familiarity with Zed to propose bigger UI changes here.
- Default-collapsed message with expand button, a la `commit_view`. The
use-case of this panel is to get the gist of a commit while moving
somewhat quickly through the graph. One might argue that the subject
line alone is enough for that, but often it isn't and the thought of
having to constantly expand commit messages rather than making the
message immediately visible with scroll felt like it would produce a
repetitious experience.
## Testing
- Adds two unit tests to verify that selection works and is idempotent
## 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
Video demonstrating the functionality:
https://github.com/user-attachments/assets/b910aaa3-2db2-4da8-904b-21b270677ca9
---
Release Notes:
- Show full commit message as markdown in details panel of the git graph