Commit Graph
360 Commits
Author SHA1 Message Date
b421755e5d Fix settings schema missing extension-provided LSP settings on remote (#62355)
## Objective

Fixes an issue where language servers provided by extensions are not
included in the settings schemas served by remote servers. When
connecting to a remote server via the
`open_remote_project_with_existing_connection` flow (dev servers,
multi-workspace reopen, git worktree picker), setup-N servers never
received any extension sync, so their schemas omitted extension-provided
language servers, breaking language support for remote development.

## Solution

Three changes ensure that language servers provided by extensions are
included in the settings schemas served by remote servers:

1. **Register connections opened via
`open_remote_project_with_existing_connection` with the extension
store**: dev servers, multi-workspace reopen, and the git worktree
picker now register their connections with the extension store so that
extensions are synced to those servers. Previously only the
`open_remote_project` flow did this, so setup-N servers never received
any extension sync and their schemas omitted extension language servers.

2. **Emit `ExtensionsInstalledChanged` from `HeadlessExtensionStore`
after sync and install complete**: this allows the remote process to
invalidate its cached settings schemas. The local `ExtensionStore`
already emitted this event; without it, the remote schema cache stayed
stale for the lifetime of the server process.

3. **Include available LSP adapters in the project settings schema**:
this matches the user settings schema (this was fixed for `settings` in
#46766 but never applied to `project_settings`).

## Testing

- Manually verified that after connecting to a remote server via the
`open_remote_project_with_existing_connection` flow (including dev
servers and the git worktree picker), extension language servers appear
in the schema served by the remote server.
- Verified that `ExtensionsInstalledChanged` is emitted after sync and
install complete, and that the remote schema cache is correctly
invalidated and rebuilt.
- Verified that the `project_settings` schema includes the available LSP
adapters, matching the behavior of the user settings schema.
- Reviewers should focus on the multi-workspace reopen and git worktree
picker flows (the two previously unregistered flows) to confirm that
extension language servers are correctly synced and appear in the
schema.

## 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
**Server / Project** — before the fix
<img width="1061" height="749" alt="image"
src="https://github.com/user-attachments/assets/d6c5459f-58fb-4769-a701-f6fb317adc37"
/>
**Local**
<img width="1119" height="449" alt="image"
src="https://github.com/user-attachments/assets/fb30a1e2-74f0-4439-a25f-1022ed164074"
/>

---

Release Notes:

- Fixed an issue where language servers provided by extensions were
missing from settings schemas served by remote servers.

---------

Co-authored-by: vancez <vancez@users.noreply.github.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 17:09:28 +00:00
c684a6a537 Add LSP call hierarchy modal (#53239)
<img width="1128" height="953" alt="image"
src="https://github.com/user-attachments/assets/b2017c0a-e25a-49d7-9342-d074014d085c"
/>

Closes #14203

Release Notes:
- Initial Call Hierarchy support in Zed

---------

Co-authored-by: Alexey Olshanskiy <gh@aohoy.dev>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 16:21:41 +00:00
09440c85cb lsp: Add client support for LSP 3.18 markdown diagnostic messages (#61030)
LSP 3.18 allows servers to send [`MarkupContent` diagnostic
messages](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#diagnostic),
guarded by the client capability
`textDocument.diagnostic.markupMessageSupport`.

- Advertise `markup_message_support` only while pull diagnostics are
enabled because `textDocument.diagnostic` is the pull-model capability.
  LSP 3.18 currently has no equivalent capability for push diagnostics:

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#diagnosticClientCapabilities
  https://github.com/microsoft/language-server-protocol/issues/2246
- Handle `string | MarkupContent` messages in both push and pull
diagnostic paths: markdown-kind messages populate the existing
`Diagnostic::markdown` field (rendered in hover popovers and the
diagnostics panel), plaintext-kind markup remains plain text, and plain
string messages keep going through the adapter's
`diagnostic_message_to_markdown`.
- Preserve server-provided markup for code actions sent back to the
originating server, avoid forwarding markup diagnostics to other
servers, and render diagnostic metadata without altering the
server-provided markdown.
- Carry the markup kind over RPC via a new optional
`LspDiagnostic.markup_message_kind` proto field so remote/collab
projects round-trip `MarkupContent` messages.

Depends on the lsp-types change that turns `Diagnostic.message` into a
`DiagnosticMessage` enum (`string | MarkupContent`):
https://github.com/zed-industries/lsp-types/pull/15
Once merged, Cargo.toml can point to the upstream commit.

Note that Zed already rendered some plain-string diagnostics as Markdown
through language-specific adapter hooks, including `rust-analyzer`. This
adds protocol-level support for diagnostics explicitly sent as LSP 3.18
`MarkupContent`, while preserving the existing adapter fallbacks.

As a result, this does not introduce a new diagnostics rendering
pipeline.
Server-provided Markdown is routed through the existing
`Diagnostic::markdown` path, with small fixes to handle Markdown-only
updates and block content correctly.

## Showcase

Example from [JETLS.jl](github.com/aviatesk/JETLS.jl) (a Julia language
server):

> Before
<img width="924" height="160" alt="Screenshot 2026-07-15 at 16 05 40"
src="https://github.com/user-attachments/assets/b19fe9e3-50e3-44e4-9b4d-ac8bd438d3d6"
/>

> After
<img width="924" height="160" alt="Screenshot 2026-07-15 at 14 13 05"
src="https://github.com/user-attachments/assets/359c3382-118d-4fa6-aa91-6bd3661d3d28"
/>

---

Release Notes:

- Added support for rendering LSP 3.18 Markdown diagnostic messages from
language servers.

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2026-08-27 12:55:42 +00:00
Jacob WolfandSmit Barmase 3ba893e4ac editor: Add file permalink support to tabs and the Project Panel (#62177)
# Objective

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

## Solution

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

## Testing

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

## Self-Review Checklist:

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

## Showcase



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

---

Release Notes:

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

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-08-26 18:21:33 +00:00
Kirill Bulatov f36284a155 Bump dependencies to dedupe the crate graph (#63231)
Deduplicates crates with different versions from the graph, drops unused
features.

`cargo tree -d duplicate` listing: 160 -> 112 lines.

<details>
<summary>Deduplicated list</summary>

```
base64 (v0.22.1, v0.21.7 -> v0.22.1)
convert_case (v0.11.0, v0.10.0, v0.8.0 -> v0.11.0, v0.10.0)
core-foundation (v0.10.0, v0.9.4 -> v0.10.0)
cssparser (v0.36.0, v0.35.0 -> v0.37.0, v0.36.0)
fancy-regex (v0.18.0, v0.16.2 -> v0.19.0)
fixedbitset (v0.5.7, v0.4.2 -> v0.5.7)
h2 (v0.4.12, v0.3.27 -> v0.4.12)
heck (v0.5.0, v0.4.1, v0.3.3 -> v0.5.0, v0.4.1)
html5ever (v0.39.0, v0.35.0 -> v0.39.0)
hyper (v1.7.0, v0.14.32 -> v1.7.0)
hyper-rustls (v0.27.9, v0.24.2 -> v0.27.9)
mach2 (v0.6.0, v0.5.0, v0.4.3 -> v0.6.0, v0.5.0)
markup5ever (v0.39.0, v0.35.0 -> v0.39.0)
phf (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3)
phf_codegen (v0.13.1, v0.11.3 -> v0.13.1)
phf_generator (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3)
phf_macros (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3)
phf_shared (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3)
prost (v0.12.6, v0.9.0 -> v0.14.4)
prost-build (v0.12.6, v0.9.0 -> v0.14.4)
prost-derive (v0.12.6, v0.9.0 -> v0.14.4)
prost-types (v0.12.6, v0.9.0 -> v0.14.4)
rustix (v1.1.4, v0.38.44 -> v1.1.4)
rustls (v0.23.40, v0.21.12 -> v0.23.40)
rustls-native-certs (v0.8.3, v0.6.3 -> v0.8.3)
rustls-pemfile (v2.2.0, v1.0.4 -> v2.2.0)
rustls-webpki (v0.103.13, v0.101.7 -> v0.103.13)
security-framework (v3.5.1, v2.11.1 -> v3.5.1)
socket2 (v0.6.3, v0.5.10 -> v0.6.3)
string_cache (v0.9.0, v0.8.9 -> v0.9.0)
string_cache_codegen (v0.6.1, v0.5.4 -> v0.6.1)
strum (v0.28.0, v0.27.2 -> v0.28.0)
strum_macros (v0.28.0, v0.27.2 -> v0.28.0)
tendril (v0.5.1, v0.4.3 -> v0.5.1)
tokio-rustls (v0.26.4, v0.24.1 -> v0.26.4)
tungstenite (v0.28.0, v0.27.0 -> v0.28.0)
web_atoms (v0.2.6, v0.1.3 -> v0.2.6)
which (v6.0.3, v4.4.2 -> v8.0.5)
```

</details>


Release Notes:

- N/A
2026-08-26 14:33:13 +00:00
Kirill BulatovandBennet Bo Fenner 6c6673e4a5 Fix shallow diffs causing a lot of computations (#63024)
For repositories with shallow mode enabled, before, Zed instantly loaded
diff changes which could be very large and CPU-demanding:


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

Now, we show the following state instead of loading:

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

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


Release Notes:

- Fixed shallow diffs causing a lot of computations

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-08-26 14:33:08 +00:00
PriyadharshanandChristopher Biscardi f652da59e8 Added Tracked , Staged options to stash (#62254)
# Objective

Closes #62252 

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

## Images

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

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






## Solution

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

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

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

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

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

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

## Testing

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

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

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

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

## Self-Review Checklist:

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

Release Notes:

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

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-08-18 05:36:16 +00:00
Kirill Bulatov c1dab7a0d3 Support blaming parent revisions (#62614)
Closes https://github.com/zed-industries/zed/discussions/42583

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


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


Release Notes:

- Supported blaming parent revisions
2026-08-14 20:24:13 +00:00
Kirill Bulatov 851bf3d499 Make file scanner less eager in non-git-tracked directory trees (#62583)
Fixes https://github.com/zed-industries/zed/issues/35780
Collab schema migration PR:
https://github.com/zed-industries/cloud/pull/3422
The corresponding database schema migration has been created in the
Cloud repo and applied to the production database.

Before, Zed scanned each and every entry in the tree down from the
directory it was opened in, except gitignored files and scan exclusions.
The approach is unchanged, if Zed detects it was open inside a git
repository: e.g. the directory open in Zed contains `.git` directory.

For the rest of the projects, 2 optimizations are made:

* Limit the depth of file scan traversal.
Now, `file_scan_depth` (default `5`) restricts Zed from traversing any
directory that has same number or more segments in its file path.


Such directories behave similar to gitignored directories: their
contents is not available in file finder, project search and project
panel, but can be lazily traversed when the directory is expanded (e.g.
project panel expands it or a nested file is open by path via terminal,
etc.)

To indicate that to the users, a status entry is shown firs time the
limitation is hit in the project:

<img width="858" height="133" alt="image"
src="https://github.com/user-attachments/assets/7da6cfbb-98b4-4cc3-bf2a-8902a9597a15"
/>

* During the scan, any git repositories that are not direct children of
the directory open in Zed (depth >= 2), are traversed and indexed
normally, but their git metadata is never fetched eagerly.

Only when Zed opens a buffer from that repo the git metadata is fetched
and applied.

All that combined now uses a way more moderate amount of CPU and RAM
when opening `~`:

<img width="1717" height="368" alt="Screenshot 2026-08-13 at 17 43 53"
src="https://github.com/user-attachments/assets/ec83e2a9-f7cc-452b-8eb7-af158284ca4e"
/>

File scan inclusions and exclusions are considered still for such
projects.
Set `file_scan_depth` to `0` to enable old behavior.
The setting is supported in the project settings, so custom values can
be set based on the project's structure.

---

Release Notes:

- Fixed Zed using a lot of memory and CPU in large, non-git-tracked,
directory trees
2026-08-13 17:07:06 +00:00
PriyadharshanandChris Biscardi 1d8ba864ae Add optional message support to git stash (#62439)
Show a modal when invoking the stash action to allow users to provide an
optional custom message for the stash entry.

Closes #62430 


# Image

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

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



# Objective

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

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

## Solution

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

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

Implementation:

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

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

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

## Testing

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

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

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

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

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

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

## Self-Review Checklist:

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


---

Release Notes:

- Added an optional stash message prompt when stashing changes
`

---------

Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
2026-08-11 04:38:21 +00:00
Mikayla MakiandBen Kunkle 0500fd9ee9 git: Add diff_base setting for showing changes since the default branch (#61501)
# Objective

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

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

Closes FR-135

## Solution

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

Tradeoffs / known limitations:

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

## Testing

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

## Self-Review Checklist:

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

---

Release Notes:

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

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-07-31 19:57:13 +00:00
Smit Barmase 737f3384f0 git_ui: Add option to commit with --no-verify (#61529)
Follow-up to #61185, which moved hook execution from Zed into `git
commit` itself. There was previously no way to skip hooks from the UI;
#59846 and #56318 attempted to add one on top of the old behavior. This
PR adds support on top of the new implementation.

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

Release Notes:

- Added a “Skip Hooks” commit option that skips pre-commit and
commit-msg hooks.
2026-07-23 15:45:21 +00:00
Tautik AgrahariandKirill Bulatov 756e764b90 project: Track inlay hint / code lens / document symbol registrations by ID (#55340)
extends the precedent set by #43703 (thanks @reflectronic) so that
`textDocument/inlayHint`, `textDocument/codeLens`, and
`textDocument/documentSymbol` correctly track multiple dynamic
registrations by id. previously each register call overwrote the slot on
`ServerCapabilities`, and unregister either silently did nothing
(inlayHint, documentSymbol — no match arm) or wiped the entire
capability (codeLens). now each method keeps its own id-keyed map on
`DynamicRegistrations`; the field on `ServerCapabilities` is cleared
only when the last registration is removed.

textDocument-sync notifications (`didChange`/`didSave`/`willSave`) are
deliberately out of scope — their fan-out semantics are ambiguous in the
spec and were flagged on @smitbarmase's earlier exploration in #36876.

verified with `cargo check -p project -p lsp -p editor`, `cargo test -p
project --test integration -- multi_registration` (3/3 passing), and
`cargo fmt -p project`.

closes part of #37838.

Release Notes:

- Improved support for language servers that dynamically register inlay
hints, code lens, or document symbols multiple times.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-07-23 07:53:30 +00:00
Om Chillureanddino 52944fa0dd Support loading Git commit templates when remote (#55490)
## Summary

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

## Changes

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

## Self-Review Checklist

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

## Testing notes — why no automated test

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

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

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

#### Closes #55265

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

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

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-07-22 12:01:29 +00:00
Shuhei KadowakiandKirill Bulatov 8b2baadb09 lsp: Show request durations in RPC messages (#61018)
Language server performance issues can be difficult to diagnose because
request timings are not shown alongside the corresponding JSON-RPC
traffic. Annotate responses in the "LSP Logs / RPC Messages" view with
their end-to-end duration, making it easier to identify slow methods,
latency outliers, and cancellation behavior in the language server
process launched by Zed.

Capture timestamps at the transport boundary, correlate decoded request
IDs separately by direction, preserve timing across cancellation, bound
stale request tracking, and forward host-measured durations to remote
clients.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and relxability
- [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

<details>
<summary>Example trace</summary>

```
// Send:
{"jsonrpc":"2.0","id":61,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":378,"character":3}}}

// Receive (took 7.698042ms):
{"jsonrpc":"2.0","id":61,"result":[]}

// Send:
{"jsonrpc":"2.0","id":62,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":378,"character":3},"end":{"line":378,"character":3}},"context":{"diagnostics":[]}}}

// Receive (took 5.632167ms):
{"jsonrpc":"2.0","id":62,"result":[{"title":"Show macro expansion for `@static`","command":{"title":"Show macro expansion for `@static`","command":"jetls.openMacroExpansion","arguments":["jetls-macro-expansion:/macro-expanded.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609"]}},{"title":"Expand all macros in this top-level form","command":{"title":"Expand all macros in this top-level form","command":"jetls.openMacroExpansion","arguments":["jetls-macro-expansion:/macro-expanded.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609&mode=toplevel"]}},{"title":"Show inferred type annotations","command":{"title":"Show inferred type annotations","command":"jetls.openTypeAnnotation","arguments":["jetls-type-annotation:/type-annotated.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609"]}}]}

// Send:
{"jsonrpc":"2.0","id":63,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":379,"character":3}}}

// Receive (took 3.473792ms):
{"jsonrpc":"2.0","id":63,"result":[]}

// Send:
{"jsonrpc":"2.0","id":64,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":379,"character":3},"end":{"line":379,"character":3}},"context":{"diagnostics":[]}}}

// Receive (took 4.472375ms):
{"jsonrpc":"2.0","id":64,"result":[{"title":"Show macro expansion for `@static`","command":{"title":"Show macro expansion for `@static`","command":"jetls.openMacroExpansion","arguments":["jetls-macro-expansion:/macro-expanded.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609"]}},{"title":"Expand all macros in this top-level form","command":{"title":"Expand all macros in this top-level form","command":"jetls.openMacroExpansion","arguments":["jetls-macro-expansion:/macro-expanded.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609&mode=toplevel"]}},{"title":"Show inferred type annotations","command":{"title":"Show inferred type annotations","command":"jetls.openTypeAnnotation","arguments":["jetls-type-annotation:/type-annotated.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609"]}}]}

// Send:
{"jsonrpc":"2.0","id":65,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":380,"character":0}}}

// Receive (took 1.186541ms):
{"jsonrpc":"2.0","id":65,"result":[]}

// Send:
{"jsonrpc":"2.0","id":66,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":380,"character":0},"end":{"line":380,"character":0}},"context":{"diagnostics":[]}}}

// Receive (took 2.552708ms):
{"jsonrpc":"2.0","id":66,"result":[]}

// Send:
{"jsonrpc":"2.0","id":67,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":401,"character":0}}}

// Receive (took 1.490084ms):
{"jsonrpc":"2.0","id":67,"result":[]}

// Send:
{"jsonrpc":"2.0","id":68,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":401,"character":0},"end":{"line":401,"character":0}},"context":{"diagnostics":[]}}}

// Receive (took 2.819125ms):
{"jsonrpc":"2.0","id":68,"result":[]}

// Send:
{"jsonrpc":"2.0","id":69,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":400,"character":0}}}

// Receive (took 3.501375ms):
{"jsonrpc":"2.0","id":69,"result":[]}

// Send:
{"jsonrpc":"2.0","id":70,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":399,"character":0}}}

// Receive (took 2.903333ms):
{"jsonrpc":"2.0","id":70,"result":[]}

// Send:
{"jsonrpc":"2.0","id":71,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":399,"character":14}}}

// Receive (took 3.166ms):
{"jsonrpc":"2.0","id":71,"result":[{"range":{"start":{"line":389,"character":19},"end":{"line":389,"character":22}},"kind":3},{"range":{"start":{"line":399,"character":11},"end":{"line":399,"character":14}},"kind":2}]}

// Send:
{"jsonrpc":"2.0","id":72,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":399,"character":14},"end":{"line":399,"character":14}},"context":{"diagnostics":[]}}}

// Receive (took 3.169625ms):
{"jsonrpc":"2.0","id":72,"result":[{"title":"Show inferred type annotations","command":{"title":"Show inferred type annotations","command":"jetls.openTypeAnnotation","arguments":["jetls-type-annotation:/type-annotated.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=15676&stop=16556"]}}]}

// Send:
{"jsonrpc":"2.0","id":73,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":399,"character":14}}}

// Receive (took 1.234396208s):
{"jsonrpc":"2.0","id":73,"result":{"contents":{"kind":"markdown","value":"```julia\n(local) ret :: Compiler.RTEffects  # Core.PartialStruct(Compiler.RTEffects, Any[Any, Any, Compiler.Effects, Core.Const(nothing)])\n```\n"},"range":{"start":{"line":399,"character":11},"end":{"line":399,"character":14}}}}

// Send:
{"jsonrpc":"2.0","id":74,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":399,"character":14}}}

// Receive (took 11.429875ms):
{"jsonrpc":"2.0","id":74,"result":{"contents":{"kind":"markdown","value":"```julia\n(local) ret :: Compiler.RTEffects  # Core.PartialStruct(Compiler.RTEffects, Any[Any, Any, Compiler.Effects, Core.Const(nothing)])\n```\n"},"range":{"start":{"line":399,"character":11},"end":{"line":399,"character":14}}}}

// Send:
{"jsonrpc":"2.0","id":75,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":401,"character":0}}}

// Receive (took 1.098667ms):
{"jsonrpc":"2.0","id":75,"result":[]}

// Send:
{"jsonrpc":"2.0","id":76,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":401,"character":0},"end":{"line":401,"character":0}},"context":{"diagnostics":[]}}}

// Receive (took 4.117459ms):
{"jsonrpc":"2.0","id":76,"result":[]}
```

</details>

---

Release Notes:

- Improved LSP Logs by showing request durations alongside RPC
responses, making slow language server behavior easier to diagnose.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-07-21 16:55:55 +00:00
Sathwik Chirivelli fdedc0c2b7 branch_picker: Add remote icons and fix edge cases (#61215)
# 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.
2026-07-20 04:00:48 +00:00
Xiaobo LiuandCole Miller 0c2cf8b508 project: Add remote support for adding paths to .gitignore (#56368)
Release Notes:

- Fixed remote support for adding paths to .gitignore



The problem solved by this PR is: when opening a remote project,
right-clicking a new file in the git panel and clicking "Add to
.gitignore" does not work.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-07-18 21:39:15 +00:00
Sathwik Chirivelli 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
2026-07-18 19:02:25 +00:00
Smit Barmase 5f624dbe96 git: Fix operations timing out and commit-msg hook being skipped (#61185)
Closes #44926
Closes #43157
Closes #29903

We have an askpass 17s timeout that races against Git operations and
results in "Connecting to host timed out". It came along in #25953 when
we extracted askpass out of remoting, where it was used for SSH.

I think, for SSH connection, no prompt and no connection after 17
seconds means the host is unreachable, so the timeout is a reliable
signal there. But for Git, silence is pretty normal. Cases like hook
running, pack transferring, an ssh-agent waiting on a fingerprint are
all senarios where we should not be dependent on timeout which kills
these healthy operations.

#43285 worked around this for commits by running the pre-commit hook
manually and passing `--no-verify` to `git commit`. But, there are more
problems to address, which I reproduced on my machine:

1. A slow `post-commit` hook fails, since `--no-verify` doesn't skip it.
2. A slow `pre-push` hook fails too, and a workaround like #43285 needs
a lot more handling. See
https://github.com/zed-industries/zed/pull/42946#issuecomment-3550570438.
3. This is the tough one: due to `--no-verify`, we are also skipping the
`commit-msg` hook. There is no direct way to call that hook since, Git
hands this hook its in-progress message file, commits whatever the hook
leaves in it, and aborts if the hook exits non-zero. Reproducing that
outside `git commit` means reimplementing that.
4. An ssh-agent waiting for user approval fails after the timeout, like
if you have 1Password set up.
5. It doesn't solve large fetches. Fetching
`git@github.com:torvalds/linux.git` just dies at the 17s timeout
mid-download.

This PR fix keep the timeout only on the SSH transport and drop it for
Git, which is less of a behavior change and more of a restoring its
original scope. If Git in a terminal doesn't time out, we shouldn't
either. This way, we let Git handle all types of hooks, which solves the
hooks issue along with the timeout issue. _This follows how VS Code does
it. It does not have any kind of timeout on git child process, and hooks
are handled by Git itself._

Edit: I also think working towards way to cancel long going operations
is better way forward. See
https://github.com/microsoft/vscode/issues/171353.

Hooks still don't run for untrusted repositories, the existing
`core.hooksPath=/dev/null` clamp covers that. The `RunGitHook` proto
handler is kept for compatibility with older remote clients.




Release Notes:

- Fixed git operations failing with a misleading "Connecting to host
timed out" error when they took longer than 17 seconds (large fetches,
slow hooks, or waiting on agent-based authentication like 1Password
Touch ID).
- Fixed `commit-msg` hooks being silently skipped on commit.
2026-07-17 13:38:09 +00:00
DinoandYara 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>
2026-07-16 09:41:21 +00:00
Ben Kunkle d224ea86e8 Add a bespoke LSP request path for edit prediction context (#60947)
Closes EP-193

Edit prediction context collection previously reused the editor
goto-definition / goto-type-definition path, which resolves every LSP
result into a `LocationLink` — opening a buffer per target (worktree
creation, buffer registration, anchor conversion) before edit prediction
gets a chance to filter. On remote projects the host additionally
created a peer-visible buffer per link and the client waited on each
one.

This adds a bespoke request path that returns raw results first and only
does the expensive work for results that survive filtering:

- New `EditPredictionDefinition { path: ProjectPath, range:
Range<Unclipped<PointUtf16>> }` boundary type. LSP wire types never
leave `lsp_command.rs`; the workspace-only filter and URI→`ProjectPath`
resolution happen while normalizing the LSP response, before any buffer
exists, so the type encodes the workspace-only invariant.
- New `GetEditPredictionDefinitions` /
`GetEditPredictionTypeDefinitions` LSP commands and proto messages.
Responses carry only path + UTF-16 range — the host never calls
`create_buffer_for_peer` and the client never waits on remote buffers.
- One public API: `Project::edit_prediction_definitions(buffer,
position, include_type_definitions, cx)` fires both LSP requests
concurrently and returns a merged, deduped list ("not capable" = empty).
The definition/type-definition split was never used downstream, so
`CacheEntry` now holds a single list and the fetch pipeline runs one
task per identifier.
- `edit_prediction_context` dedupes raw results before opening buffers;
survivors open via `project.open_buffer(ProjectPath)` (skipping the
invisible-worktree/yarn machinery of `open_local_buffer_via_lsp`, and
working identically on remote projects), then clip → anchor →
`MAX_TARGET_LEN`.
- Removes the `workspace_only` flag from `GetDefinitions` /
`GetTypeDefinitions`: edit prediction was its only user. The editor path
always sent `false`, which proto3 doesn't encode, so normal
goto-definition requests are wire-identical; old peers still sending
`true` get unfiltered results (graceful degradation). The proto field
numbers are `reserved`.

Tested with a local test proving filtering precedes buffer opening (an
out-of-workspace target never spawns a worktree, an oversized target is
excluded from related files) and a collab test proving the remote
round-trip returns correct paths/ranges without opening buffers on the
client.

Release Notes:

- N/A
2026-07-15 01:54:27 +00:00
Tyler BenfieldandSmit Barmase 8e863013b4 Fix remote worktree picker hides "Create from origin/main" option (#59134)
This passes the `include_remote_name` flag through the remote
`GetDefaultBranch` RPC instead of dropping it at the client/host
boundary. That lets remote repositories resolve default branches as
`origin/main` when needed, so worktree creation uses a valid remote
branch name instead of falling back to `main`.

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

Closes #59121

Release Notes:

- Fixed remote worktree creation from the default branch when the
default branch requires its remote name.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-10 12:11:57 +00:00
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>
2026-07-07 06:55:29 +00:00
Anant GoelandAnthony Eid f023a7e4a3 Fix worktree grouping for bare checkouts (#59968)
Summary

- Track whether a worktree root is itself a linked Git worktree.
- Use that metadata when computing project group keys so bare checkout
worktrees group under the repository identity path.
- Propagate the metadata through remote worktree protocols and add
local/remote regression coverage.

Background

Bare checkout layouts can place linked worktrees under the repository
identity directory, e.g. `/monty/.bare` with worktrees like
`/monty/feature-a`. We were treating those linked worktree paths as
separate project identities, which caused the sidebar to move agent
threads under the active worktree instead of the shared repository
group.
We also exclude adding this to collab intentionally, we can open a
different PR for that if we need to.

Closes #59910
Closes AI-431

Test Plan

- `cargo fmt --package project --package worktree --package
remote_server --package workspace --package collab --package proto`
- `git --no-pager diff --check`
- `cargo test -p project test_project_group_key -- --nocapture`
- `cargo test -p remote_server test_remote_root_repo_common_dir --
--nocapture`
- `cargo test -p worktree remote_worktree -- --nocapture`
- `cargo test -p workspace
test_remote_project_root_dir_changes_update_groups -- --nocapture`
- `cargo check -p collab`

Self-Review Checklist:

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

Release Notes:

- Fixed agent thread/sidebar grouping for Git worktrees backed by bare
checkouts.

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
2026-07-02 18:14:11 +00:00
Marshall Bowers 5531777b7b collab: Add username to User (#60097)
This PR adds the `username` field to `User` and `proto::User`.

Closes CLO-949.

Release Notes:

- N/A
2026-06-29 15:06:18 +00:00
Kirill Bulatov fe2c2f4000 Fix code lens not being resolved in remote workflows (#59999)
Follow-up to https://github.com/zed-industries/zed/pull/54100
Closes https://github.com/zed-industries/zed/issues/59122

Original PR overlooked that the resolve was not handled from the remote
hosts at all...
Also, fixes the re-fetch of code lens not taking new language servers
into account: before, it exit early whilst now it actually re-fetches
the lens for the new servers.

Before:

<img width="1728" height="1084" alt="before"
src="https://github.com/user-attachments/assets/9ee8205b-084b-4409-9abc-18c4ddb9c4e9"
/>

After:

<img width="1728" height="1084" alt="after"
src="https://github.com/user-attachments/assets/16ad76dc-25e1-4257-80dc-b5aeabc9a4ef"
/>


Release Notes:

- Fixed code lens not being resolved in remote workflows
2026-06-28 14:44:44 +00:00
Marshall Bowers 7c91706a11 Unship shared threads (#59981)
This PR unships shared threads.

The feature is not used much and is getting in the way, at this point.

These are only ever made available to staff.

The corresponding database schema migration has been created in the
Cloud repo and applied to the production database.

Release Notes:

- N/A
2026-06-26 20:50:37 +00:00
Piotr OsiewiczandClaude Opus 4.8 f743291f1c collab: Revert livekit changes (#59733)
- **Revert "livekit: Preserve tokens on channel rejoin (#59388)"**
- **Revert "call: Log LiveKit connection info refresh outcomes in retry
loop (#59205)"**
- **Revert "audio: Fix phantom presence in channels (#59195)"**
- **proto: Reserve RejoinRoomResponse field 4 after revert**

We've observed a spike of phantom collaborator issues after this fixes.
This sucks and I'm quite unhappy about it.

# Objective

- Describe the objective or issue this PR addresses.
- If you're fixing a specific issue, use "Fixes #X" for each issue as
[described in the GitHub
docs](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword).

## Solution

- Describe the solution used to achieve the objective above.

## Testing

- Did you test these changes? If so, how?
- Are there any parts that need more testing?
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

## 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

> This section is optional. If this PR does not include a visual change
or does not add a new user-facing feature, you can delete this section.

- Help others understand the result of this PR by showcasing your
awesome work!
- If this PR includes a visual change, consider adding a screenshot,
GIF, or video
- A before/after comparison is very useful for changes to existing
features!

While a showcase should aim to be brief and digestible, you can use a
toggleable section to save space on longer showcases:

<details>
  <summary>Click to view showcase</summary>

My super cool demos here

</details>

---

Release Notes:

- N/A

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 09:13:28 +00:00
Lukas Wirth 42edf2fea1 Implement telemetry for the remote server (#59692)
# Objective

Telemetry events generated **on a remote server** were silently dropped,
and all remote telemetry that *was* reported got attributed to the local
client's OS.

## Solution

This PR makes server-originated events flow to the telemetry pipeline
and attributes them to the actual remote host (connection type, OS,
version, architecture), plus adds a transport-agnostic connection event.

## Additional Notes

This removes the "SSH Project Opened" event and replaces it with a
"Remote Connection Established" one that has more structured info and is
also more useful in where it gets invoked.

The server unconditionally sends back telemetry to the client, the
client is then responsible for filtering on whether telemetry is enabled
by the user or not as the server does not have knowledge of those
settings itself.

Release Notes:

- N/A
2026-06-23 05:53:33 +00:00
Richard Feldman fdebc23ccc Prevent archival of manually-created worktrees (#58275)
This fixes archive cleanup for agent threads so Zed only removes
worktrees it explicitly created, rather than treating every linked
worktree under the configured managed directory as safe to delete. When
Zed creates a worktree, it now records it in the local database along
with the creation time of the worktree's git metadata directory
(`.git/worktrees/<name>/`). Archive planning requires that record, and
right before deleting anything, Zed re-stats the directory and compares
creation times: if the worktree was removed and recreated outside Zed
(or the time can't be read at all), deletion is skipped and the stale
record is dropped. Every failure mode fails safe by leaving the
directory untouched.

For remote (SSH) projects, the stat runs on the remote host via a new
`GitWorktreeCreatedAt` request. Worktrees created by a different Zed
install (another release channel, or another machine connecting to the
same host) have no record in the local database and are therefore never
auto-archived, which is the intended conservative behavior.

Closes https://github.com/zed-industries/zed/issues/57155

Closes AI-352

Release Notes:

- Fixed archiving an agent thread incorrectly deleting manually-created
git worktrees.
2026-06-16 15:36:59 +00:00
130a9d31d7 audio: Fix phantom presence in channels (#59195)
# Objective

You know that feeling? You join the channel, crack a banger joke to
break the ice - yet, nobody laughs. Worse yet, you're swarmed with Slack
messages like "Piotr, we can't hear you". After a while you realize that
maybe it's for the best as the joke was not as good as you've initially
thought, but still: it's possible to get into a state where other
participants see you as muted. You don't hear anybody. Bummer.

That's what happened when we were hoping to pair with @dinocosta today.
I could not hear him. However, he had some logs to share which indicated
that while collab thought he's in the room with me, live-kit was
rejecting his token as it was revoked.

What clanker helped us figure out is that there's a race-y code path
where if you disconnect from a given room abruptly, collab can put you
in a limbo.
<details><summary>Clanker's idea of what's going on</summary>
<p>
Found the whole story. Here's what those logs mean and where the bug
surface is.

What's happening

The error at room.rs:1809 is the detach_and_log_err on the task spawned
by spawn_room_connection (crates/call/src/call_impl/room.rs:1754-1810).
So this is the initial livekit::Room::connect call failing — the LiveKit
SDK internally retried 3 times (that's the retrying... (1/3) lines), got
401 invalid token: revoked every time, gave up, and the error propagated
out of the ? at line 1762 and was logged-and-dropped.

The "revoked" comes from the collab server: leave_room_for_session
(crates/collab/src/rpc.rs:4091-4095) calls
live_kit.remove_participant(livekit_room,
session.user_id().to_string()), and LiveKit Cloud treats a removed
participant's token as revoked. Crucially, the LiveKit identity is just
the user id, not the connection id, while the DB-side
leave_room(connection_id) is per-connection. leave_room_for_session
fires from three places:

1. Explicit leave (rpc.rs:1666)
2. connection_lost, after RECONNECT_TIMEOUT expires (rpc.rs:1342)
3. Stale-connection cleanup when re-joining a channel (rpc.rs:3401)

So there's a race: an old connection's delayed cleanup (path 2) can fire
after the same user has rejoined the room on a new connection and been
issued a fresh token — and remove_participant(room, user_id)
kicks/revokes the user's current LiveKit participant, because the
identity is shared across connections. Quick restart of Zed, two
instances, or a reconnect that straddles the server's RECONNECT_TIMEOUT
all set this up.

Client-side consequences (this connects to your first question)

When that initial connect fails:

- this.live_kit stays None and this.diagnostics is never created — lines
1780-1791 only run on success. So in this failure mode CallDiagnostics
doesn't exist at all; the "stats never overridden" path I described
earlier isn't even reached.
- There is no retry and no token refresh. The failure is
detach_and_log_err'd and that's the end of it. The user stays in the
room at the collab level (status is still Online, they appear in the
channel), but with no audio and no way to recover short of leaving and
rejoining.
- Even a collab-level reconnect doesn't help: RejoinRoomResponse
(crates/proto/proto/call.proto:58) carries no live_kit_connection_info,
and rejoin() never calls spawn_room_connection — the LiveKit connection
is established exactly once, in Room::new, with the token from the
original join response.

So the user-visible symptom is: you're "in" the call, everyone sees you,
but you can't hear or be heard, and there's no error surfaced in the UI
— just this log line.

If you want to fix it, the two angles are server-side (make
leave_room_for_session skip the LiveKit removal when the user still has
a live connection in that room, or scope LiveKit identities
per-connection) and client-side (treat a failed spawn_room_connection as
fatal-but-recoverable: surface it, and have rejoin request fresh
connection info instead of silently carrying on). Happy to dig into
either if you want.


</p>
</details> 

So tl;dr: our token was swapped out underneath us. One way to "fix" it
was to just go into another channel, but that was a bummer.

We have a good and reliable repro for it though: `kill -9 $ZED_PID`
followed by an attempt to rejoin the same channel within 30s would
consistently put us in that state.
Put another way: you panic and thus do not send a clean "leave room"
message to LK. if you rejoin the channel within 30s (after restarting),
LK will invalidate the very token you're attempting to use (as it cleans
up old tokens).

It may also happen without crashing, but that's the most reliable way to
repro the issue. Long story short your LK token gets tainted and you
can't share the audio anyhow.

## Solution

The fix is both client and server-side.

On client's side, we now retry the reconnection with a back-off and we
grab a fresh token off of reconnect attempts.
On server's side, we share the current token on room reconnect attempts.

We've also tweaked the call diagnostics to not use `unwrap_or_default`
so much: it was hard for us to tell that we're in a totally bogus state
and we've only reached that conclusion based on source code analysis. We
now show some generic "ok you're in a borked state pls report a bug"
message instead.

## Testing

We added tests that present the flacky scenario. We've also tried to
setup an infra to test the new behaviour, but sadly, local LK instance
seems to revoke tokens more leniently than the prod..
OTOH, we are quite confident that once new collab is deployed, we'll be
able to mince the new tokens and life is going to be good. Even when
running against the current prod instance we could see that our code
changed the behaviour for the better, as now we'll actually try to use a
new token if one is provided by collab. For that to happen we need to
redeploy though.


## Self-Review Checklist:

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


Release Notes:

- Fixed a race condition that caused collab users to not receive/send
any audio to their peers.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
Co-authored-by: Dino <dino@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-06-12 12:54:29 +00:00
Bennet Bo Fennerandzed-zippy[bot] 0b0436dda5 acp: Indicate when agent is downloading (#57710)
Release Notes:

- agent: Indicate when ACP servers are downloading

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-06-02 09:40:28 +00:00
Xin Zhao cf5bdcb9a9 lsp: Register available LSP adapters locally when in remote development (#54915)
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 #49178

The context for this change is covered in #49178. Some language server
adapters are lazily registered; in remote development or collab
sessions, the local client fails to register these adapters, may causing
certain LSP features to function incorrectly. This PR is intended to
address that.

Release Notes:

- N/A
2026-06-01 06:32:55 +00:00
chenmiandLukas Wirth 760f479696 Remove stale SSH LSP log entries after server restarts (#55299)
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 #55287

This fixes the SSH remote case where restarting a language server left a
stale entry in the LSP Logs panel.

The root cause was that the remote client learned about the replacement
language server, but never received an explicit removal update for the
previous server id. As a result, the old status and log-store entry
remained visible even though only the new server continued producing
logs.

Tested with:
- `cargo test -p collab --test collab_tests
remote_editing_collaboration_tests::test_ssh_restarting_language_server_replaces_remote_status
-- --exact`

Release Notes:

- Fixed stale duplicate entries in the LSP Logs panel after restarting
an SSH remote language server.

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-05-31 19:17:28 +00:00
Kirill Bulatov 8d4499341e Support LSP document links (#56011)
Closes https://github.com/zed-industries/zed/issues/33587


https://github.com/user-attachments/assets/bbaea8a9-402e-485b-800e-2f4486142956

Release Notes:

- Supported LSP document links (enabled by default, use
`"lsp_document_links": false` to turn it off)
2026-05-26 07:09:47 +00:00
Mikhail PertsevandCole Miller f7088b3f8a git: Recover branch refs when metadata lookup fails (#57285)
cc @cole-miller 

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 branch enumeration when a broken Git ref prevents commit
metadata from being read.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-05-25 14:29:46 +00:00
Ben Kunkle ab007980ef ep: Don't open unnecessary files during context collection (#57318)
Self-Review Checklist:

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

Closes #ISSUE

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-05-20 22:42:31 +00:00
Smit Barmase 2ef5304e89 git_ui: Add force delete for unmerged branches (#55927)
Git's `-d` flag deletes a branch only if it's fully merged into its
upstream or HEAD - this is what we were using before, which caused the
"not fully merged" error. The `-D` flag force deletes a branch even with
unmerged changes (equivalent to `--delete --force`).

### Before

Deleting an unmerged branch failed with a "not fully merged" error
toast.

### After

- Deleting an unmerged branch prompts for confirmation to force delete
- Delete button tooltip shows "Hold alt to force delete" hint
- Holding **alt** turns the delete icon red and tooltip changes to
"Force Delete Branch"
- Force delete keybinding: `cmd-alt-shift-backspace`

Release Notes:

- Added confirmation prompt when deleting unmerged git branches, with
option to force delete.
- Added alt+click on delete button to force delete a branch immediately.
2026-05-06 20:08:42 +00:00
26b9e07fa8 git_graph: Add remote support (#55788)
Follow up: https://github.com/zed-industries/zed/pull/55167,
https://github.com/zed-industries/zed/pull/54468

This is the final PR for adding remote support on the git graph. It uses
the client stream request support added in #55167 to add support for the
initial graph data request. I also fixed a bug where
`GitGraph::FullyLoaded` repository event was never emitted.

Self-Review Checklist:

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

Closes ##53040

Co-authored-by: Remco Smits \<djsmits12@gmail.com\>

Release Notes:

- git_graph: Add remote support

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-05-05 21:44:06 +00:00
Anthony Eidandcameron 7a60f55db2 git_graph: Add remote support for search operations (#55167)
### Motivation 

This is the second of three PRs to add remote/collab support for the git
graph and is a follow-up to #54468. I'm adding remote support for the
search because it's not user accessible without the initial graph fetch
having remote support, so it allows us to merge this without having to
add full remote support. Collab guest support will be added in a
follow-up PR.

#### Summary

For large repos, searching can take a while to fully stream in all
matched results. For example, running a basic search on the Linux repo
took over 10s for me. Because of that, we want to stream search results
in chunks to downstream users to keep the time-to-first-match low. After
this change, the first chunk gets sent back after ~50ms on the Linux
repo from receiving the request.

In order to accomplish that, I added a new proto client API that allows
for a request to map to n responses. e.g.

```/dev/null/example.rs#L1-1
client.add_entity_stream_request_handler(Self::handle_search_commits);
```

Note: The proto API isn't supported over collab yet, that will be
another PR

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 #ISSUE

Release Notes:

- N/A

---------

Co-authored-by: cameron <cameron.studdstreet@gmail.com>
2026-05-04 16:38:14 +00:00
boaz-h cb4281662f Fix creating branch with base in remote (#55387)
To support branch create with base branch, added extra optional field in
GitCreateBranch proto.

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 #43985

Release Notes:

- git:  Fixed remote branch creation based on default branch
2026-05-02 22:26:50 +00:00
Max Brunsfeld 17c284803f Improve bare repo support (#55153)
Fixes https://github.com/zed-industries/zed/issues/54830

This fixes a bugs where
* when there's no main worktree, we treated the first linked worktree as
main
* the titlebar and sidebar showed two different things when opening a
linked wortree directly

When there's no main worktree, our "project group key" will be the bare
repo path. For displaying this to the user, we try to present something
meaningful:
* If the bare repo is `foo.git`, we'll say "foo"
* If the bare repo is "bar/.bare", we'll "bar"

Release Notes:

- Fixed bugs in Zed's sidebar and titlebar when editing in git worktrees
created from bare repositories.
2026-04-29 13:16:37 +00:00
05f474361d git: Replace file history view with git graph (#50288)
## Summary

This PR replaces the git file history view with the git graph view that
doesn't render the graph canvas. This has several advantages

1. Benefits from the graphs performance and lazy loading
2. Gets the graph's search for free
3. Resizable columns
4. The commit information panel
5. Is persistent 
6. Cleans up a lot of code

The one con of this change is the graph doesn't have support
remote/collab support yet, but that is a WIP and should be merged within
a week.

Also, the git graph now propagates errors to the UI, which is the last
thing on the graph's stable launch todo list!

Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Release Notes:

- N/A *or* Added/Fixed/Improved ...

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>
2026-04-24 02:51:19 +00:00
Anthony Eid 08029066e6 git: Fix remote branch picker not showing branches (#54575)
This sends `branch_list` in live `UpdateRepository` messages so
downstream repository snapshots stay in sync and the remote branch
picker can populate correctly. Collab DB replay for join/reconnect will
follow in a separate change.

This fixes a bug where the branch picker wouldn't show any branches in
remote environments

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 #54530

Release Notes:

- git: Fix remote branch picker not showing any branches
2026-04-22 20:26:43 -04:00
Anthony EidandRemco Smits e311f9df9a git_graph: Add remote support for commit data handler (#54468)
### Motivation

To support remote Git graph usage, we need remote support for the Git
APIs that the graph depends on. This PR adds remote support for
`CommitDataHandler` (the `git cat-file --batch` process manager),
allowing remote Git graph consumers to fetch visible commit data without
polling.

#### Summary

The Git graph separates the UI and data layers so the UI can continue
rendering while commit data is fetched in the background. This change
extends that model to remote repositories by allowing
`GitStore::fetch_commit_data(sha: Oid, await_result: bool, cx: &mut
Context) -> &CommitDataState` to await remote commit loading.

For simplicity, the `Starting` variant was removed from
`CommitDataState`. `CommitDataState::Loading(Option<...>)` now stores
`Some(...)` when `await_result == true` is passed to
`fetch_commit_data`. This allows the data layer to await commit loading
without polling, and only when explicitly requested.

I also removed the `Graph` prefix from `CommitData`-related types
because this API is general-purpose and not limited to the graph. Longer
term, I hope to replace `Repository::show` with the commit data
functionality, since it already provides built-in caching.

#### Bug Fixes

- Fix stale `Loading(...)` entries that survive enqueue failure or
handler shutdown.
- Fix commit data handler bookkeeping so `pending_requests`,
`completion_senders`, and `CommitDataState` remain consistent.
- Fix remote commit-data loading so the data layer can await results
instead of polling.

#### Testing

- Add property tests for commit data fetching.
- Add a collab integration test that verifies batched remote commit-data
fetching.

#### Follow Up

In a follow-up, I want to replace the `Repository::show` backend with
the commit data handler and remove `CommitDetails` from the codebase as
a cleanup and maintenance pass. The commit data handler already provides
caching and is a better long-term path for commit metadata access.

I may also want to allow the `CommitData` type to propagate errors to
callers.

For the Git graph, the remaining work is remote search and initial data
fetching.

Self-Review Checklist:

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

Release Notes:

- N/A

---------

Co-authored-by: Remco Smits <djsmits12@gmail.com>
2026-04-22 16:11:51 -04:00
Anthony Eid 5c770a5560 agent: Support remote archive thread git operations (#54001)
### Summary

This PR implements remote support for git store operations that the
sidebar's archive thread checkpoint/restore featured relied on. This was
the second to last blocker for remote usage of this feature.

I also made a shared backend between `update_ref` and `delete_ref`
called `edit_ref` because they run the same git command and this allowed
for some code unification.

#### Remote Git Operations 
- `Repository::update_ref`
- `Repository::delete_ref`
- `Repository::repair_worktrees`
- `Repository::create_archive_checkpoint`
- `Repository::restore_archive_checkpoint`


#### Follow up

`agent_ui::thread_worktree_archive::find_or_create_repository` needs to
be made aware of the remote machine that the repository it's searching
for is on. Once that is completed, we can get the correct repo when
archiving a remote thread and the flow should work without any problems.

Self-Review Checklist:

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

Release Notes:

- N/A
2026-04-15 19:55:37 +00:00
Danilo LealandNathan Sobo 4a41cc4bf0 agent_ui: Improve the new thread worktree UX (#53941)
Closes https://github.com/zed-industries/zed/issues/53262

- Remove the ability to pick a branch from the agent panel; delegate
this to the title bar picker
- Make the worktree creation earger, just as you selected whether you
want to create it from main or current branch
- Remove flicker when creating a new worktree and switching to a
previously existing one
- Improve some UI stuff: how we display that a worktree is
creating/loading, the branch and worktree icons, etc.
- Fixed a bug where worktrees in a detached HEAD state wouldn't show up
in the worktree pickers

A big part of the diff of this PR is the removal of everything involved
with the `StartThreadIn` enum/the set up involved in only creating the
worktree by the time of the first prompt send.

Release Notes:

- Agent: Improved and simplified the UX of creating threads in Git
worktrees.
- Git: Fixed a bug where worktrees in a detached HEAD state wouldn't
show up in the worktree picker.

---------

Co-authored-by: Nathan Sobo <nathan@zed.dev>
2026-04-15 03:47:19 +00:00
9b2d9fe537 sidebar: Better handling for threads in remote workspaces (#53451)
This PR greatly improves our handling of remote threads in the sidebar.

One primary issue was that many parts of the sidebar were only looking
at a thread's path list and not its remote connection information. The
fix here is to use `ProjectGroupKey` more consistently throughout the
sidebar which also includes remote connection information.

The second major change is to extend the MultiWorkspace with the ability
to initiate the creation of remote workspaces when needed. This involved
refactoring a lot of our remote workspace creation paths to share a
single code path for better consistency.

Release Notes:

- (Preview only) Fixed remote project threads appearing as a separate
local project in the sidebar

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2026-04-09 06:56:28 +00:00
Anthony Eidandcameron 555a0a4985 agent_panel: Add new thread git worktree/branch pickers (#52979)
This PR allows users to create a new thread based off a git worktree
that already exists or has a custom name. User's can also choose what
branch they want the newly generated worktree to be based off of.

The UI still needs some polish, but I'm merging this early to get the
team using this before our preview launch. I'll be active today and
tomorrow before launch to fix any nits we have with the UI.

Functionality of this feature works! And I have a basic test to prevent
regressions


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 #ISSUE

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: cameron <cameron.studdstreet@gmail.com>
2026-04-07 05:21:47 -04:00
Richard FeldmanandAnthony Eid 4b17369db2 Add allow_empty commits, detached worktree creation, and new git operations (#53213)
Extend the git API with several new capabilities needed for worktree
archival and restoration:

- Add `allow_empty` flag to `CommitOptions` for creating WIP marker
commits
- Change `create_worktree` to accept `Option<String>` branch, enabling
detached worktree creation when `None` is passed
- Add `head_sha()` to read the current HEAD commit hash
- Add `update_ref()` and `delete_ref()` for managing git references
- Add `stage_all_including_untracked()` to stage everything before a WIP
commit
- Implement all new operations in `FakeGitRepository` with functional
commit history tracking, reset support, and ref management
- Update existing call sites for the new `CommitOptions` field and
`create_worktree` signature

Part 1 of 3 in the persist-worktree stack. These are nonbreaking API
additions with no behavioral changes to existing code.

Release Notes:

- N/A

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
2026-04-06 21:31:59 +00:00