f652da59e8d4c75a9bcba00e426643eb876fbb11
529
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f652da59e8 |
Added Tracked , Staged options to stash (#62254)
# Objective Closes #62252 The Git Panel could only stash *everything* — `Stash All` runs `git stash push --include-untracked`, sweeping tracked edits and untracked files into a single entry. There was no way to stash a subset, so the common workflows of "park my tracked edits but keep my new scratch files" and "park what I've staged and keep working on the rest" required dropping to the terminal. ## Images <img width="389" height="358" alt="Screenshot 2026-08-10 at 3 10 50 PM" src="https://github.com/user-attachments/assets/18e4c943-e320-4802-ada8-59e54bf4cefd" /> <img width="504" height="462" alt="Screenshot 2026-08-10 at 3 10 37 PM" src="https://github.com/user-attachments/assets/783237eb-980d-47bc-a0f5-17b03a23a60c" /> ## Solution Add two stash variants alongside `Stash All`, surfaced in the Git Panel's overflow menu based on how the list is currently grouped, so the menu mirrors the sections the user can actually see: | Group By | Stash entries offered | | --- | --- | | None | Stash All | | Tracked & Untracked | Stash All, **Stash Tracked** | | Staged & Unstaged | Stash All, **Stash Staged** | - **`git::StashTracked`** stashes tracked changes and leaves untracked files in place. It reuses the existing pathspec plumbing (`Repository::stash_entries`), filtering the status list down to the paths to stash. - **`git::StashStaged`** stashes the index only, leaving unstaged changes in place. This *cannot* be expressed as a pathspec — a partially staged file would have its unstaged hunks stashed too — so it needs git's own `--staged` flag. That meant a new `GitRepository::stash_staged` backend method and an `optional bool staged` field on `proto::Stash` so remote projects work too. Both actions are unbound by default and are dispatchable from the command palette when the panel is focused. One subtlety worth calling out for review: `Stash Tracked` filters on `FileStatus::is_created()`, not `is_untracked()`. Staging a new file flips it from `Untracked` to `Tracked { Added }`, but the panel still lists it under **Untracked** — using `is_untracked()` meant staged-new files were silently stashed. `is_created()` is the same predicate the panel uses to build that section (`git_panel.rs`), so the menu item and the list can no longer disagree. This branch also includes a separate commit adding **per-section staging** (`git::StageSection` / `git::UnstageSection`) — right-click a file to stage or unstage every entry in its section. Happy to split that into its own PR if preferred. ## Testing Manually tested on macOS against a scratch repo with a mix of states: modified tracked files, untracked files, and untracked files that had been staged. - `Stash Tracked` with tracked edits + untracked files → only tracked edits stashed; untracked files remain. - `Stash Tracked` with untracked files **staged** → they remain, staged. This was broken in an earlier revision and drove the `is_created()` fix above. - `Stash Staged` with one file staged and another modified-but-unstaged → only the staged file is stashed; the unstaged edit and untracked files survive. - `Stash Pop` round-trips both cases back to the original state, with no conflicts. - Menu contents and disabled states verified in all three Group By modes. - Per-section staging covered by a new unit test, `test_stage_section_scopes_to_selected_section`. Not covered by automated tests: the stash actions themselves. `FakeGitRepository` leaves every stash method `unimplemented!()`, so stash behavior isn't reachable from GPUI tests today — consistent with the existing untested `StashAll`. Adding fake-repo stash support looks like a worthwhile follow-up but felt out of scope here. Reviewers on non-macOS platforms: nothing here is platform-specific. Note that `Stash Staged` requires **git 2.35+** (Jan 2022) for `git stash push --staged`; older git surfaces a clear error toast rather than failing opaquely. The remote path (`proto::Stash.staged`) has not been exercised against a live collab session. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Added `Stash Tracked` and `Stash Staged` options to the Git Panel, letting you stash only tracked changes or only staged changes. --------- Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com> |
||
|
|
8fd8efd105 |
git_ui: Fix Trash Untracked Files with many files (#61602)
Release Notes: - Fixed Trash Untracked Files bailing out early with many selected files when trashing one file failed. --------- Co-authored-by: Cole Miller <cole@zed.dev> |
||
|
|
1d8ba864ae |
Add optional message support to git stash (#62439)
Show a modal when invoking the stash action to allow users to provide an optional custom message for the stash entry. Closes #62430 # Image <img width="1622" height="1106" alt="Screenshot 2026-08-10 at 9 14 00 PM" src="https://github.com/user-attachments/assets/0d26dac2-919d-4bb1-b6a7-433ceff18955" /> <img width="1622" height="1106" alt="Screenshot 2026-08-10 at 9 14 11 PM" src="https://github.com/user-attachments/assets/896b68ff-999f-4ec9-a6a4-e0e7a6867286" /> # Objective Zed's stash action runs `git stash push --quiet --include-untracked --` with no `-m`, so every stash is labelled with git's auto-generated `WIP on <branch>: <sha> <subject>`. That text describes the commit you were sitting on, not what you stashed — so two stashes taken from the same commit are indistinguishable. This undercuts the stash picker (`git::ViewStash`), which lists entries as `#<index>: <message>` and fuzzy-searches over exactly that string. The search box already exists; there is just nothing meaningful to search, because every candidate is a variation of the same auto-generated line. ## Solution `git::StashAll` now opens a single-line modal ("Optionally provide a stash message") before stashing. - Confirming with text passes `--message <text>` to `git stash push`. - Confirming with the field empty omits the flag entirely, keeping git's default description — so the prompt is a one-keystroke pass-through and existing muscle memory still works. - Cancelling aborts the stash, so the prompt doubles as a confirmation step. Implementation: - `StashMessageModal` (`Editor::single_line`) in `git_panel.rs`, toggled from `GitPanel::stash_all`. `menu::Confirm` trims the input and maps empty to `None`. - `message: Option<String>` threaded through `Repository::stash_all` → `stash_entries` → `GitRepository::stash_paths`. The flag is appended before the `--` separator so a message is never parsed as a pathspec. - New `message` field on the `Stash` proto message, so remote and collab projects behave identically. One non-obvious detail: the modal is opened via `cx.defer_in` rather than inline. `git::StashAll` is registered on the workspace (`git_ui.rs`) as well as on the panel element, and `Workspace::register_action` dispatches while `Workspace` is leased — so opening the modal inline re-enters that update and hits GPUI's `double_lease_panic`. This only reproduces when focus is *outside* the Git Panel, which makes it easy to miss. `Option<String>` rather than `String` is deliberate: `--message ""` produces a blank stash description, which is strictly worse than git's default. ## Testing Manually verified the modal in a local build on macOS: the prompt appears on `git::StashAll`, accepts a message, and the named entry shows up in the stash picker. Also verified at the git level by replaying the exact argument vector `stash_paths` builds against a scratch repo with mixed staged / unstaged / untracked changes: | Case | Result | |---|---| | `stash push --quiet --include-untracked --message "my named stash" -- <paths>` | `stash@{0}: my named stash`; worktree clean, untracked file included | | same, without `--message` | `stash@{0}: <sha> <subject>` — git's default text | | `--message "x" --` with no paths (clean repo) | exit 0, no stash created — the empty pathspec does **not** stash everything | `cargo fmt --check` clean, `./script/clippy -p git -p fs -p project -p git_ui` passes with `--deny warnings`, and the existing suites pass (`cargo test -p project -p git_ui`, 436 tests). Worth a reviewer's attention: trigger `git::StashAll` with focus in the **editor** rather than the Git Panel. That routes through the workspace action registration and is the case the `cx.defer_in` deferral exists to keep from panicking. No new automated tests — the behavior is testable with the existing `git_panel.rs` harness (`init_test`, `GitPanel::new`) if reviewers would prefer coverage over a manual check. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments — n/a, no unsafe added - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior — no new tests; see Testing - [x] Performance impact has been considered and is acceptable — one extra process argument; no new work on any hot path --- Release Notes: - Added an optional stash message prompt when stashing changes ` --------- Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com> |
||
|
|
077d3c3581 |
git_panel: Add collapsable sections (#62441)
# Objective - Make Git Panel grouping sections collapsible so users can hide sections they are not currently interested in. - Support collapsible sections when grouping changes by tracking and by staging. - Provide a clear visual indicator showing whether each section is expanded or collapsed. ## Solution - Added per-section collapsed state to the Git Panel. - Made grouping headers clickable to toggle their section between expanded and collapsed. - Added chevron indicators that point down when expanded and right when collapsed. - Applied the behavior to both flat and tree views. - Kept the stage/unstage checkbox independent from the header collapse interaction. - Ensured a previously collapsed Tracked section does not hide files after switching to Group by None. ## Testing - Ran `rustfmt --edition 2024 crates/git_ui/src/git_panel.rs --check`. - Ran `cargo check -p git_ui`. - Ran `cargo test -p git_ui`: - 129 tests passed - 0 tests failed - Ran `git diff --check`. - Attempted `./script/clippy -p git_ui` twice. It produced no lint diagnostics but did not finish compiling the release, all-targets, all-features dependency graph within the available timeout. - Manually verify by selecting both grouping modes in the Git Panel and clicking each section header in flat and tree views. Confirm that: - The section contents are hidden and restored. - The chevron updates to reflect the current state. - Clicking the stage/unstage checkbox does not collapse the section. - Switching to Group by None does not leave tracked files hidden. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase https://github.com/user-attachments/assets/77ec4c88-4a6d-4e49-ac9f-ddbf80e724ca --- Release Notes: - Improved Git Panel organization by allowing grouped change sections to be collapsed |
||
|
|
4043c82956 |
git_panel: Add copy path actions to the context menu (#62352)
# Objective When developing remotely, when I close the uncommitted changes tab, I need some time to load before I can copy the path. Or have to switch to the project panel to find the specific file. All of this is annoying, so I added a copy path action to the git panel's context menu and key bindings consistent with the project panel. ## Solution Already described in the Objective section. ## Testing I wrote a unit test and tested it manually. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase <img width="411" height="535" alt="showcase" src="https://github.com/user-attachments/assets/a17e7633-eb92-4737-aa30-958fe58bb99f" /> <img width="717" height="427" alt="showcase" src="https://github.com/user-attachments/assets/d067e892-17de-4527-ac20-16cad6f38015" /> --- Release Notes: - Added "Copy Path" and "Copy Relative Path" actions to the Git Panel's context menu |
||
|
|
3692029a80 |
Bump rustc to 1.97 (#62395)
Release Notes: - N/A |
||
|
|
4be749399d |
git_panel: Fix focus navigation across Changes and History (#62215)
# Objective Fix several Git panel focus issues: - Directional navigation could not move focus into the History tab. - History focus state was not updated when the panel received focus. - Switching back to Changes could leave focus on the panel instead of the commit editor. Fixes #62211 ## Solution - Use the Git panel root as the activation focus target when History is active. - Reuse the panel's focus handle for focus events. - Use the appropriate activation target when switching tabs. ## Testing - Add a regression test `test_history_tab_pane_navigation_focuses_rendered_panel` for navigating between the editor and History. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase after fix: [2026-08-05 22-45-38.webm](https://github.com/user-attachments/assets/fdb3f87a-f1af-4ae1-95f7-0d61acfb3095) --- Release Notes: - Fixed directional focus navigation into the Git panel's History tab. |
||
|
|
01961bef59 |
Speed up cargo build -p zed compilation (#62059)
Splits the crate graph.
Before, the compilation graph: `editor → picker_preview → search →
project_panel → open_path_prompt → recent_projects → title_bar →
collab_ui → zed`
After, the compilation graph: `editor → picker_preview → search →
agent_ui → sidebar → zed`
With sccache disabled and project fully built, `touch
crates/editor/src/editor.rs` and `cargo build -p zed` took time
Before (
|
||
|
|
0500fd9ee9 |
git: Add diff_base setting for showing changes since the default branch (#61501)
# Objective Let git indicators — the editor gutter, file colors, and `git::Diff` — show all changes on the current branch relative to its merge base with the default branch, instead of only uncommitted changes. Supersedes #60398; thanks to @samuelcolvin for the original implementation and motivation. Closes FR-135 ## Solution - New `git.diff_base` setting (`"head"` | `"default_branch"`), applied live and toggleable per session from the editor controls menu ("Diff Against Default Branch"). - Statuses come from a real merge-base-to-worktree tree diff (`git diff --merge-base`), so local edits that revert branch changes correctly show as unchanged. - `GitStore` shares one `DiffBufferList` per repository with the Branch Diff view; `repo_snapshots` and `project_path_git_status` keep returning index/worktree truth, while display surfaces use separate `display_*` APIs. - `BufferDiff` now records what its base is (`DiffBaseKind`); hunks whose base isn't HEAD are read-only in the gutter — stage/restore buttons and keybindings are inert, so committed work can't be silently rewritten. - `git::Diff` follows the setting; new `git::DiffHead` always opens the HEAD diff; `git::BranchDiff` is renamed `git::DiffBranch` (deprecated alias kept). Tradeoffs / known limitations: - Hunk-level staging is unavailable while in `default_branch` mode (whole-file staging via the git panel still works). Staging just the uncommitted sub-ranges of a branch hunk is a follow-up. - Remote hosts running an older server ignore the new `GetTreeDiff.includes_worktree` proto field and degrade to committed-changes-only branch diffs. - Repositories with no resolvable default branch fall back to HEAD-relative behavior; a failed first resolution retries on the next branch-list change. ## Testing - Real-git-repo tests for the merge-base-to-worktree diff's edge cases: files recreated after index deletion, committed deletions recreated on disk, and symlinks. - GPUI tests for status semantics (a branch change reverted on disk shows clean), `git::Diff` routing, live setting changes, and read-only hunk enforcement (restore/stage leave buffer and index untouched). ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Git: Added a `git.diff_base` setting (`"head"` or `"default_branch"`) that makes the editor gutter, file colors, and diff view show all changes on the current branch since its merge base with the default branch, instead of only uncommitted changes. --------- Co-authored-by: Ben Kunkle <ben@zed.dev> |
||
|
|
b9e8d99a71 |
git: Do not re-compute git_access for .git/ changes (#60503)
This builds on #59521 and addresses @dinocosta's comment https://github.com/zed-industries/zed/pull/59521#pullrequestreview-4563460240 Looking at it again, I think https://github.com/zed-industries/zed/pull/59521/commits/e7ed02cc4963868632ba97a1fb09f1b398d3b22b was too conservative. Re-running the access check on every commit, stage, or checkout, doesn't really make sense. Access depends on `.git` ownership/permissions and on the global `safe.directory` config. File writes in `.git/` can actually never change the access. The only case where this access can change is an external command that changes the ownership or permission of the folder. That sounds like a quite rare edge case and I'm not 100% sure whether all file watchers even currently correctly trigger events for ownership changes. @dinocosta Let me know what you think. Release Notes: - Improved Git Panel performance by avoiding redundant repository access checks. Co-authored-by: dino <dinojoaocosta@gmail.com> |
||
|
|
ecac6c00a6 |
Fix zoomed panels closing when focus moves within the panel (#59439)
Closes FR-139 Most focus-lost issues that close the agent panel in Zen mode stem from panels returning a transient child editor's focus handle from `Focusable::focus_handle`. The Zen-mode check closes the zoomed panel when the focused element is not a descendant of the panel's focus handle, so any focus movement inside the panel that landed outside that child editor looked like the panel losing focus. This PR separates the two roles that handle was serving: - `Focusable::focus_handle` now always returns a stable handle tracked at the panel's root element, used for containment checks (Zen-mode auto-close, `toggle_panel_focus`, dock focus subscriptions). - The new `Panel::activation_focus_handle` returns what should receive focus when the panel is activated (e.g. a filter/commit/message editor) and must be a focus-tree descendant of the root handle. All "focus the panel" callsites in workspace/dock now use it. Migrated panels: `AgentPanel` (including thread views and the toolbar title editor), `CollabPanel`, `GitPanel`, `OutlinePanel`, and `TerminalPanel` (previously delegated to the active pane, so focus in a non-active pane dropped containment). `CollabPanel` activation falls back to the panel root when signed out or collaboration is disabled, since the filter editor isn't rendered in those states. Also fixes duplicate element ids for tool calls with multiple content blocks. Tests: a regression test that clicks tool-call output and focuses the thread title editor while zoomed (both previously closed Zen mode), and a dock-level test asserting the activation handle receives focus on panel activation while the panel root reports containment. Release Notes: - Fixed zoomed panels (e.g. the agent panel in Zen mode) closing unexpectedly when focus moved to elements inside the panel, such as tool call output or the thread title editor. |
||
|
|
1c244c194b |
git_panel: Use specific label and prompt for reverting deleted file (#61554)
# Objective I expected a different label for reverting a file deletion like Zed already has for reverting a file creation. ## Solution This PR implements a new label and prompt. VS Code also shows a different prompt while keeping the label static but I think it makes more sense to let both adapt. ## Testing Just deleted a file and checked menu label and prompt. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [ ] Performance impact has been considered and is acceptable ## Showcase <img width="363" height="139" alt="image" src="https://github.com/user-attachments/assets/6be7e5b9-7250-449e-9cba-ea5a2099dd3a" /> <img width="349" height="240" alt="image" src="https://github.com/user-attachments/assets/d87d5b4b-ff29-4976-8078-314c94a71896" /> --- Release Notes: - Git Panel: Added specific label and prompt to context menu for reverting a deleted file |
||
|
|
04e53be020 |
git_ui: Ensure discarding tracked changes respects staging state (#61608)
Closes #56020 Release Notes: - Fixed Discard Tracked Changes discarding unstaged files --------- Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
737f3384f0 |
git_ui: Add option to commit with --no-verify (#61529)
Follow-up to #61185, which moved hook execution from Zed into `git commit` itself. There was previously no way to skip hooks from the UI; #59846 and #56318 attempted to add one on top of the old behavior. This PR adds support on top of the new implementation. Adds a “Skip Hooks” toggle to the commit menus in the Git panel and commit modal, with a corresponding command-palette action. When enabled, the next commit runs with `git commit --no-verify`, skipping pre-commit and commit-msg hooks. The toggle clears after a successful commit or when switching repositories, but remains enabled when a commit fails so it can be retried. Release Notes: - Added a “Skip Hooks” commit option that skips pre-commit and commit-msg hooks. |
||
|
|
52944fa0dd |
Support loading Git commit templates when remote (#55490)
## Summary Fixes the git commit template not loading in remote (SSH) projects. The `load_commit_template_text` method in `git_store.rs` was a no-op for `RepositoryState::Remote`, always returning `Ok(None)`. This patch adds a `LoadCommitTemplate` RPC so the client can ask the remote host to read its `commit.template` git config and return the file contents — mirroring the existing `GetBlobContent` pattern. ## Changes - **`crates/proto/proto/git.proto`** — new `LoadCommitTemplate` / `LoadCommitTemplateResponse` messages. - **`crates/proto/proto/zed.proto`** — registered envelope IDs 449/450. - **`crates/proto/src/proto.rs`** — wired up message priority, request pairing, and entity-message routing. - **`crates/project/src/git_store.rs`** — added `handle_load_commit_template` on the host side; replaced the `Ok(None)` no-op on the remote side with the RPC call. ## Self-Review Checklist - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments — *no unsafe code added* - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) — *no UI changes* - [ ] Tests cover the new/changed behavior — *see "Testing notes" below* - [x] Performance impact has been considered and is acceptable — *one extra RPC on commit panel open for remote projects only; payload is a single optional string* ## Testing notes — why no automated test I did write an integration test (`test_remote_git_commit_template` in `collab/tests/integration/git_tests.rs`, modeled after `test_remote_git_head_sha`) along with the supporting changes to `FakeGitRepositoryState` (adding a `commit_template` field + `set_commit_template_for_repo` setter on `FakeFs`, since the fake hardcoded `load_commit_template` to `None`). The test compiled and the smaller crates (`fs`, `proto`, `project`) checked clean, but `cargo test -p collab --test collab_tests` cold-compile takes a very long time on my machine and I wasn't able to confirm the test actually passed locally. Rather than push a test I hadn't seen pass, I removed it. Happy to add it back in a follow-up PR (or in this one if reviewers prefer) once I can run the collab suite end-to-end — the diff is small and I can share it on request. Verification was done end-to-end manually using a Docker dev container as the SSH remote: #### Closes #55265 Video : [Screencast from 2026-05-02 18-09-03.webm](https://github.com/user-attachments/assets/9cb7f375-57fa-4af3-bde4-871c28f61efc) Release Notes: - Added support for loading git commit template messages in both remote and collab projects. --------- Co-authored-by: dino <dinojoaocosta@gmail.com> |
||
|
|
1f63fef270 |
git_panel: Adjust commit items in the history tab (#61456)
This PR is super small mostly adjusting a few things in the commit item within the history tab: author label truncation, tooltip label/description, and unpushed arrow icon design. Release Notes: - N/A |
||
|
|
870ffffcd8 |
Fix git file context menu focus issue (#61339)
## Objective #61331 Ensure the Git panel receives focus when a file context menu is opened. Previously, focusing the menu immediately could prevent the Git panel from becoming focused. ## Solution Defer focusing the context menu’s focus handle until the next window update cycle. This allows the menu to be established before focus is applied, preserving expected focus behavior in the Git panel. ## Testing - Automated tests were not run. - The change should be manually tested by opening a file context menu from the Git panel and confirming the Git panel remains focused and keyboard interaction with the menu works as expected. - This is a UI focus change and should be verified on supported desktop platforms. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase ### Previously https://github.com/user-attachments/assets/28fb7f9b-3e1f-4939-a8ae-13b33ac0d805 ### Now https://github.com/user-attachments/assets/d85e7459-d260-41bc-955c-37a269be23c1 Release Notes: - Fixed Git panel focus when opening a file context menu |
||
|
|
3e34dcf2a7 |
Keep git panel history entry highlighted while context menu is open (#61354)
Also, unifies the naming of the variable naming for the target entry in both the git graph and git panel history tab. Release Notes: - Improved the git panel's history tab to keep an entry highlighted while its context menu is open |
||
|
|
7113882745 |
git_ui: Restore search in solo diff views (#60936)
## Context Buffer search did not work in file diffs opened from the Git panel because `SoloDiffView` did not expose its embedded editor as searchable. Restoring search also revealed that the primary toolbar clipped several search controls, so the deployed search bar now uses the full-width secondary row for this view. Closes #60659. ## How to Review Three files changed. Read in this order: **`crates/git_ui/src/solo_diff_view.rs`** : `SoloDiffView::as_searchable` now returns its embedded `SplittableEditor`, restoring search for the focused diff side while keeping the editor hidden from global diff-style controls. **`crates/search/src/buffer_search.rs`** : Buffer search now detects when its searchable split editor is intentionally hidden by the containing item. When deployed, this case uses the secondary toolbar row so Toggle Replace, search options, match navigation, and match counts remain visible. Other multibuffer layouts keep their existing primary toolbar location. **`crates/git_ui/src/git_panel.rs`** : The regression test now opens a solo diff through the Git panel, confirms the split editor is searchable, deploys buffer search, verifies the secondary toolbar location, runs a query, and checks that the focused editor receives a search highlight. Manual test after the fix below : [Screencast from 2026-07-14 00-39-04.webm](https://github.com/user-attachments/assets/022ab106-d35a-4a75-98db-8809b86fa58d) ## Self-Review Checklist - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the UI/UX checklist - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed searching in file diffs opened from the Git panel. Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com> |
||
|
|
6f5463ca3c |
git_ui: Disable commit actions during commit message generation (#51727)
Release Notes: - Add disable commit actions during commit message generation --------- Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com> Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
2328aebf25 |
git_panel: Show staged and unstaged diff stats (#60815)
# 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 |
||
|
|
23ee3ba37d |
project_panel: Add remote support for undo/redo system (#59709)
# 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> |
||
|
|
6b6393fb0b |
Split out RelPath into a separate crate (#61029)
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 ... |
||
|
|
1e9a452d5b |
Focus on the history tabs context menu when deploying (#61000)
Release Notes: - N/A |
||
|
|
0188a3a952 |
Surface the git graph context menu in the git panel's history tab (#60713)
This PR refactors the Git Graph’s commit context menu into its own file so it can be reused by both the Git Graph and the Git panel’s History tab. <img width="511" height="566" alt="SCR-20260709-qlxt" src="https://github.com/user-attachments/assets/8f18f22b-21d7-46a0-8ce2-183cf4af86c9" /> Also, includes a "Show in Git Graph" option only shown in the history tab's context menu: https://github.com/user-attachments/assets/2e30648b-2802-4caa-a99e-2d135e2dc539 Release Notes: - Surfaced the git graph context menu in the git panel's history tab. |
||
|
|
27095fe544 |
git_ui: Improve the staged & unstaged grouping in the git panel (#60976)
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_) |
||
|
|
1a06fd4f2b |
Add a bunch of stray design refinement throughout (#60937)
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 |
||
|
|
b220d078bf |
Show tag names in git blame tooltips (#60757)
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> |
||
|
|
1b15ec62e0 |
git_ui: Sanitize file names before rendering (#60862)
# 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. |
||
|
|
606133f50c |
git_ui: Add restore buttons to unstaged diff view (#60639)
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> |
||
|
|
092badbc32 |
git_panel: Add group by staging view option (#59884)
# 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> |
||
|
|
7d3e75a787 |
git_ui: Fix history tab empty and detached HEAD states (#57959)
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> |
||
|
|
042d22ce9c |
git_ui: Use pull request link from push output in push toast (#60522)
## 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> |
||
|
|
846c40cf0d |
Add missing panels to View menu (#60356)
# 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 |
||
|
|
3f74307a26 |
git_ui: Show tags in Git panel history (#60534)
# 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> |
||
|
|
6da34ac148 |
git_graph: Add design adjustments (#60469)
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 |
||
|
|
48192372a0 |
Git partially staged changes (#46541)
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> |
||
|
|
e41a55c3c0 |
Improve diff tabs toolbar design (#60464)
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. |
||
|
|
cd8a09be89 |
git_panel: Scope folder expansion state to sections (#60396)
# 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. |
||
|
|
e3f01a1c88 |
git: Do not recompute git_access on every file change (#59521)
# Objective As mentioned in #59514, the git panel currently runs a full `git status` for checking whether `git` has access to the repository. This was introduced in #43693 and currently runs on every file save which is problematic for large repos where `git status` runs a lot of computation. ## Solution This PR caches the `git_access` on the git panel such that we don't need re-check for git access on every file save. ## Testing I manually verified that the git panel doesn't trigger anymore unnecessary git status commands. **main:** ``` 2026-06-18T00:04:24+01:00 DEBUG [project::git_store] start recalculating diffs for buffer 4294967643 2026-06-18T00:04:24+01:00 DEBUG [project::git_store] finished recalculating diffs for buffer 4294967643 2026-06-18T00:04:24+01:00 DEBUG [project::git_store] start recalculating diffs for buffer 4294967643 2026-06-18T00:04:24+01:00 DEBUG [project::git_store] finished recalculating diffs for buffer 4294967643 2026-06-18T00:04:24+01:00 DEBUG [project.format.local] formatting buffer '"/Users/lgeiger/code/zed/CONTRIBUTING.md"' 2026-06-18T00:04:24+01:00 DEBUG [project.format.local] no changes made while formatting 2026-06-18T00:04:24+01:00 DEBUG [git::repository] Checking for git status in ["CONTRIBUTING.md"] 2026-06-18T00:04:25+01:00 DEBUG [git::repository] Checking for git status in [] ``` ``` /opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager status --porcelain=v1 --untracked-files=all --no-renames -z -- CONTRIBUTING.md /opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager diff --numstat --no-renames HEAD -- CONTRIBUTING.md /opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager config --get commit.template /opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager status --porcelain=v1 --untracked-files=all --no-renames -z -- ``` **This PR:** ``` 2026-06-18T02:47:54+01:00 DEBUG [project::git_store] start recalculating diffs for buffer 4294967656 2026-06-18T02:47:54+01:00 DEBUG [project::git_store] finished recalculating diffs for buffer 4294967656 2026-06-18T02:47:55+01:00 DEBUG [project.format.local] formatting buffer '"/Users/lgeiger/code/zed/CONTRIBUTING.md"' 2026-06-18T02:47:55+01:00 DEBUG [project.format.local] no changes made while formatting 2026-06-18T02:47:55+01:00 DEBUG [git::repository] Checking for git status in ["CONTRIBUTING.md"] ``` ``` /opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager diff --numstat --no-renames HEAD -- CONTRIBUTING.md /opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager status --porcelain=v1 --untracked-files=all --no-renames -z -- CONTRIBUTING.md /opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager config --get commit.template ``` ## 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 /cc @dinocosta --- Release Notes: - Improved Git Panel performance by no longer re-checking repository access on every file change --------- Co-authored-by: dino <dinojoaocosta@gmail.com> |
||
|
|
73d1111d37 |
Fix expanded commit editor (#60368)
This is a simple follow-up to #60331, the commit message in the expanded view got messed up and was being shrunken and centered instead of taking up the full height of the git panel. All it needed was a `.h_full()`: <details> <summary>Click to view showcase</summary> ### Before <img width="652" height="758" alt="file-6d7f3fd7a5de8cff5ea44c0dfbaf0ac5" src="https://github.com/user-attachments/assets/85dca75c-7528-4876-9154-0145272c5029" /> ### After <img width="662" height="761" alt="file-268420a52e7b967fc09d10007d6aa1e5" src="https://github.com/user-attachments/assets/f39ea70b-d0a9-40e6-bb20-20cd3508ad66" /> </details> @danilo-leal ## 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 --- Release Notes: - N/A |
||
|
|
5fb0cdfb15 |
Improve commit container at larger font sizes (#60331)
At larger font sizes (e.g. I have profiles that increase the font sizes when screen sharing) the commit button in the git panel editor does not stay aligned to the bottom-right of the screen, and overlaps the other elements: <details> <summary>Click to show showcase</summary> https://github.com/user-attachments/assets/e73034db-07a6-42d7-b993-9d8091e50b70 Notice the extra clipping of the commit message editor element: <img width="500" alt="image" src="https://github.com/user-attachments/assets/67d59405-57e2-4547-87c2-1c4728515c26" /> </details> This was happening because the floating icons on the right and the footer containing the commit button were positioned absolutely, used pixels instead of responsive rems, and had an offset that was calculated and did not account for changes in user rem size. So I've moved things around to be more "flexy"... basically just removing the absolute positioning and making the elements flush against one another. ## Testing I have tested this manually on macOS 27 beta 2 and Windows 11, both using various light/dark themes, window sizes, commit text, etc. ## 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 Here's a demo at different zoom levels, with and without text, when expanding the commit window, etc. <details> <summary>Click to view showcase</summary> https://github.com/user-attachments/assets/bea82da1-0c7f-4d51-a73b-d4bc4581a2b7 And here's another demo with debug colors for the different elements to see what's going on: https://github.com/user-attachments/assets/12fd3e95-5089-4e34-a84c-c352219ee197 </details> --- Release Notes: - Git Panel: Fixed overlapping elements in commit message container --------- Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> Co-authored-by: Danilo Leal <daniloleal09@gmail.com> |
||
|
|
8510aae0f2 |
git_ui: Add configure and docs links to commit message tooltip (#60357)
When no LLM provider is configured, hovering the disabled "Generate Commit Message" button in the git panel/commit modal previously showed a plain, non-interactive tooltip with no way to act on it. This tooltip now includes two links: - **Configure Provider** — jumps directly to the "LLM Providers" settings sub-page. - **See Docs** — opens `https://zed.dev/docs/ai/llm-providers`. Also adds `IconButton::hoverable_tooltip`, mirroring the existing `.tooltip(...)` forwarding, since `IconButton` didn't previously expose the underlying `ButtonLike::hoverable_tooltip` capability needed for interactive tooltip content. Release Notes: - Improved the commit message tooltip to link directly to LLM provider settings and documentation when no provider is configured. --------- Co-authored-by: Danilo Leal <daniloleal09@gmail.com> |
||
|
|
36a291b0e9 |
agent: Add commit message project rules toggle (#56867)
This follows up on discussion #56551. Right now, when Zed generates a commit message, it includes project rules files like `AGENTS.md`, `CLAUDE.md`, and `.rules` in the prompt alongside the git diff. That can add a lot of extra context for a task that is really just summarizing the changes in a commit. This PR adds an `include_project_rules` option to `agent.commit_message_model`. When it is set to `false`, Zed skips loading project rules when generating commit messages. If the option is omitted, the current behavior stays the same. Example: ```json { "agent": { "commit_message_model": { "provider": "anthropic", "model": "claude-3-5-haiku", "include_project_rules": false } } } ``` I also updated the settings plumbing so this option is only used for commit message generation and defaults to true when not specified. 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: - agent: Added setting to exclude project rules files from commit message generation prompts (`agent.commit_message_include_project_rules`) --------- Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de> |
||
|
|
970e93e881 |
client: Add username to User and start using it (#60107)
This PR adds a `username` field to the `User` and starts using it instead of the `github_login`. Closes CLO-952. Release Notes: - N/A |
||
|
|
585e40a6dc |
git_ui: Preserve in-progress commit message across reconnect (#58180)
Losing the connection on a remote project, or restarting Zed, while editing a git commit message cleared the in-progress text, because the Git panel rebuilds the commit buffer from the repository and discards unsent input. This persists the draft, scoped to the active repository's work directory, in the panel's serialized state and restores it when the panel is rebuilt from that state: at construction when the active repository already matches, and again in `reopen_commit_buffer` once the commit buffer loads. The restore only applies to an empty target buffer whose work directory matches the active repository, so it never replays committed or cleared text and never leaks a draft across repositories. The persisted draft is cleared after a successful commit. 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 Closes #47864 Release Notes: - Fixed in-progress git commit messages being cleared when a remote project reconnects or Zed restarts --------- Co-authored-by: Cole Miller <cole@zed.dev> |
||
|
|
127ea4a6b1 |
git_panel: Focus back on commit editor when expanded (#59901)
Update the focus handle returned by the `GitPanel::focus_handle` method in order to ensure that, if the commit editor is currently expanded, using the `git_panel::ToggleFocus` action will correctly focus back on the expanded editor, rather than on the panel. # Objective When using the expanded commit editor, if one focuses away from the panel and then uses the `git panel: toggle focus` action in order to focus back on the panel, the focus will land on the panel, which is now being rendered behind the commit editor. ## Solution Update the focus handle returned by the `GitPanel` to take into consideration whether the commit editor is expanded and, in that case, return the editor's focus handle instead. ## Testing Tested both manually as well as through a newly introduced test – `git_ui::git_panel::tests::test_focus_handle`. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [ ] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase <details> <summary>Before</summary> https://github.com/user-attachments/assets/0e2647f3-2835-485f-8f01-2128d2de6b8e </details> <details> <summary>After</summary> https://github.com/user-attachments/assets/cc77fae7-e76c-4389-82b0-f4e7ec8258d7 </details> --- Release Notes: - Fixed `git panel: toggle focus` to focus back on the commit editor in case it is expanded. |
||
|
|
9f6279c616 |
git_ui: Disable remote button during operations (#59874)
# Objective This change prevents users from starting multiple Git remote operations at the same time from the Git panel. Fetch, pull, and push can take time, may prompt for credentials, and can update shared repository state, so allowing repeated clicks can create duplicated work, confusing UI feedback, or overlapping Git commands. ## Solution The panel now records when a remote operation is in progress, disables the main remote action button, and shows a clear tooltip such as “Push in progress.” When the async task exits, the state is cleared and the button is re-enabled. This keeps the UI aligned with the operation lifecycle and makes repeated clicks harmless. --- Release Notes: - Git: Improved performance by not allowing multiple remote Git operation to start at the same time. --------- Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com> Co-authored-by: Danilo Leal <daniloleal09@gmail.com> |
||
|
|
ef7fc3c288 |
git_ui: Keep view options menu state fresh (#59744)
# Objective - Keep the Git panel view options menu open when changing view, sort, or group options. - Make the open menu reflect the selected option immediately, including showing the Sort By section as soon as List view is selected. ## Solution - Use a persistent context menu for the Git panel view options menu so selecting an item rebuilds the menu instead of dismissing it. - Track the open menu's view options state locally with `GitPanelViewOptionsMenuState` so checkmarks and conditional sections update before the settings file change is observed. - Continue dispatching the existing Git panel actions so persisted settings and panel updates keep using the current code path. ## 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 - N/A --- Release Notes: - Fixed Git Panel view options menu selections updating only after reopening the menu. |
||
|
|
924be03fcf |
git_panel: Add some design tweaks (#59699)
Small things here: ensuring padding and responsiveness on the header is good, make the global diff stat part of the "view diff" button, and conditionally render the "sort by" filter section in the menu (no need to render it if it's all disabled). Release Notes: - N/A |