Commit Graph
21 Commits
Author SHA1 Message Date
Ruslan SemaginandDanilo Leal b220d078bf Show tag names in git blame tooltips (#60757)
Fetch tag names for commits included in blame data and pass them through
the blame rendering path. Render tag names as chips in the blame hover
tooltip and expanded blame popover. Tag lookup is best-effort, so blame
still renders if tag lookup fails.

> Note: Tag names are currently only fetched for local repositories. For
remote projects (SSH) and collab sessions, blame data travels over the
`BlameBufferResponse` proto message, which doesn't carry tag names yet.

  ## Testing

- `cargo test -p git
test_parse_tag_names_for_lightweight_and_annotated_tags`
  - `cargo check -p git_ui`
  - `cargo check -p editor`
  - `cargo check -p project`

  Manual testing:
  - Opened `git: blame` on a file with a tagged commit.
- Verified tag chips are shown in the blame hover tooltip and expanded
popover.

  ## Self-Review Checklist:

  - [x] I've reviewed my own diff for quality, security, and reliability
  - [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and [icon]

(https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
  - [x] Tests cover the new/changed behavior
  - [x] Performance impact has been considered and is acceptable

  ## Showcase

Before:
<img width="1655" height="660" alt="before"
src="https://github.com/user-attachments/assets/dbefd729-f8df-48a9-8249-83c93518fe76"
/>

After:
<img width="1655" height="660" alt="after"
src="https://github.com/user-attachments/assets/2c1097de-b268-45d9-9d13-0f3e06058603"
/>

---

Release Notes:

- Git: Made tags visible in Git blame tooltips.

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-07-14 01:21:38 +00:00
Eagl61 6208932d3c git: Show submodule changes in commit diffs (#60479)
## Objective

Fix Git Graph showing `0 Changed Files` for commits that modify
submodules.

This happened because submodule entries are gitlinks rather than regular
blobs, so the existing commit diff loading path could not resolve them
correctly.

I ran into this issue previously, and it was confusing because the
commit clearly contained changes, but the UI did not reflect them. If a
commit included many file changes plus a submodule update, the submodule
change was effectively hidden and the UI could still show `0 Changed
Files` for that entry. Since submodules are not used in every
repository, the bug is easy to miss and may go unnoticed for a long
time.

## Solution

- Switched commit diff loading to use Git's raw diff output so submodule
entries are represented explicitly.
- Added parsing for gitlink entries alongside regular file changes.
- Render submodule changes as `Subproject commit <oid>` so they show up
in commit diffs instead of being dropped.

## Testing

- Added a repository test covering commit diffs that include submodule
changes.
- Ran the `git` crate test suite.
- Ran formatting and lint checks.
- Verified the Git UI crate still builds.
- Ran and tested it locally on MacOS.

Reviewer notes:
- The change is limited to commit diff loading and should not affect
normal blob diffs.
- Submodule changes now appear as explicit entries instead of being
counted as zero files.

## Self-Review Checklist:

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

## Showcase

Before:
<img width="200" alt="Screenshot 2026-07-06 at 19 22 57"
src="https://github.com/user-attachments/assets/16efc348-5909-4cb0-8589-b0662923df56"
/>

After:
<img width="200" alt="Screenshot 2026-07-06 at 20 20 11"
src="https://github.com/user-attachments/assets/3201b264-6e61-45de-a9fc-c585f3b54e09"
/>

<img width="200" alt="Screenshot 2026-07-06 at 20 37 57"
src="https://github.com/user-attachments/assets/182ed4e1-9e90-4e33-9136-7626aba31153"
/>

---

Release Notes:

- Fixed Git Graph showing `0 Changed Files` for commits that update
submodules.
2026-07-12 21:19:11 +00:00
Eagl61 45aabb43a8 Show type-changed files in commit diffs (#60422)
# Objective

Zed ignores files marked by Git as type-changed (T), causing commits
containing only these changes to show 0 Changed Files.

For example, commit 86590085000dca2e9dfe967470fa42423ef7ceac changes
crates/eval_utils/LICENSE-GPL from a regular file to a symlink, but Zed
displays no changes.

  ## Solution

Handle TypeChanged files like modified files by loading both their old
and new contents.

  ## Testing

  - Added parser coverage for the T status.
  - Added a repository test for a regular-file-to-symlink change.
  - Ran cargo test -p git.
  - Ran ./script/clippy -p git.
  - Manually verified the example commit 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

Before:
<img width="200" alt="image"
src="https://github.com/user-attachments/assets/277c5938-5c2c-47b7-902d-9061a14c062a"
/>

After:
<img width="200" alt="image"
src="https://github.com/user-attachments/assets/f99d0005-0712-4843-814e-d73b11f64782"
/>

  ———

  Release Notes:

- Fixed type-changed files not appearing in Git Graph and commit views.
2026-07-06 03:15:43 +00:00
Cole Miller 641d5151f2 git: Log some more information when opening a git repository and when git show fails (#51495)
Release Notes:

- N/A
2026-03-13 14:53:14 +00:00
Dino 7b21c3ac2e git: Fix commit message generation in untrusted projects and block external diff (#51323)
When on a untrusted project, if one was to try and use the commit
generation functionality, the command would fail because of the `-c
diff.external` configuration provided in `GitBinary::build_command`, as
git would interpret this as `""` and try to run that command.

This `-c diff.external` is a good safeguard to have on untrusted
repositories because it prevents random commands, configured in
`.git/config` from being run. For example, if one uses `git config
diff.external "touch bananas.txt"` and then run `git diff`, a new
`bananas.txt` file would be created.

However, it was still possible to bypass this safeguard using the
following strategy:

1. Specify a custom diff for a specific file format. For example, for
markdown files, with `printf '*.md diff=pwned\n' > .gitattributes`
2. Update the command run by the `pwned` diff, for example, `git config
diff.pwned.command "touch bananas.txt"`
3. Open Zed and attempt to generate a commit message in an untrusted
repository and check that a new `bananas.txt` file was created

This is only prevented by using the `--no-ext-diff` flag on the `diff`
command, so a new `GitBinary::build_diff_command` has been introduced
which simply wraps `GitBinary::build_command` and adds the
`--no-ext-diff` flag, if necessary.

As a side-effect, this also makes it so that generating a commit message
in an untrusted repository works again, which was accidentally broken on
https://github.com/zed-industries/zed/pull/50649 .

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

Release Notes:

- Fixed commit message generation in untrusted repositories
2026-03-13 15:08:12 +01:00
Anthony Eid 53b6118f3a git: Add trusted worktree support to git integrations (#50649)
This PR cleans up the git command spawning by wrapping everything in
GitBinary instead to follow a builder/factory pattern. It also extends
trusted workspace support to git commands.

I also added a `clippy.toml` configuration to our git crate that warns
against using `Command` struct to spawn git commands instead of going
through `GitBinary`. This should help us maintain the factory pattern in
the future

Before you mark this PR as ready for review, make sure that you have:
- [x] Added solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects

Release Notes:

- git: Add trusted workspace support for Zed's git integration
2026-03-04 12:19:13 +00:00
Jakub KonkaandCole Miller f4aa279898 util: Always use posix_spawn on macOS even with pre_exec hooks (#49090)
Here's some backstory:
* on macOS, @cole-miller and I noticed that since roughly Oct 2025, due
to some changes to latest macOS Tahoe, for any spawned child process we
needed to reset Mach exception ports
(https://github.com/zed-industries/zed/issues/36754 +
https://github.com/RemiKalbe/zed/commit/6e8f2d2ebe5a93753625a3026aeb996de8cb436b)
* the changes in that PR achieve that via `pre_exec` hook on
`std::process::Command` which then abandons `posix_spawn` syscall for
`fork` + `execve` dance on macOS (we tracked it down in Rust's std
implementation)
* as it turns out, `fork` + `execve` is pretty expensive on macOS
(apparently way more so than on other OSes like Linux) and `fork` takes
a process-wide lock on the allocator which is bad
* however, since we wanna reset exception ports on the child, the only
official way supported by Rust's std is to use `pre_exec` hook
* posix_spawn on macOS exposes this tho via a macOS specific extension
to that syscall `posix_spawnattr_setexceptionports_np` but there is no
way to use that via any standard interfaces in `std::process::Command`
* thus, it seemed like a good idea to instead create our own custom
Command wrapper that on non-macOS hosts is a zero-cost wrapper of
`smol::process::Command`, while on macOS we reimplement the minimum to
achieve `smol::process::Command`  with `posix_spawn` under-the-hood

Notably, this changeset improves git-blame in very large repos
significantly.

Release Notes:

- Fixed performance spawning child processes on macOS by always forcing
`posix_spawn` no matter what.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-02-13 20:16:11 +01:00
ac131ad830 git: Unify commit popups (#38749)
Closes #26424
Supersedes #35328

Originally, `git::blame` uses its own `ParsedCommitMessage` as the
source for the commit information, including the PR section. This
changes unifies this with `git::repository` and `git_ui::git_panel` by
moving this and some other commit-related structs to `git::commit`
instead, and making both `git_ui::blame_ui` and `git_ui::git_panel` pull
their information from these structs.

Release notes :

- (Let's Git Together) Fixed the commit tooltip in the git panel not
showing information like avatars.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
2025-12-17 17:31:12 -05:00
Lukas Wirth cd87711395 git: Work around windows command length limit message fetching (#39115)
Release Notes:

- Fix git blame failing on windows for files with lots of blame entries
2025-09-29 15:29:42 +00:00
bae91cee47 Represent relative paths using a dedicated, separator-agnostic type (#38744)
Closes https://github.com/zed-industries/zed/issues/38690
Closes #37353

### Background

On Windows, paths are normally separated by `\`, unlike mac and linux
where they are separated by `/`. When editing code in a project that
uses a different path style than your local system (e.g. remoting from
Windows to Linux, using WSL, and collaboration between windows and unix
users), the correct separator for a path may differ from the "native"
separator.

Previously, to work around this, Zed converted paths' separators in
numerous places. This was applied to both absolute and relative paths,
leading to incorrect conversions in some cases.

### Solution

Many code paths in Zed use paths that are *relative* to either a
worktree root or a git repository. This PR introduces a dedicated type
for these paths called `RelPath`, which stores the path in the same way
regardless of host platform, and offers `Path`-like manipulation APIs.
RelPath supports *displaying* the path using either separator, so that
we can display paths in a style that is determined at runtime based on
the current project.

The representation of absolute paths is left untouched, for now.
Absolute paths are different from relative paths because (except in
contexts where we know that the path refers to the local filesystem)
they should generally be treated as opaque strings. Currently we use a
mix of types for these paths (std::path::Path, String, SanitizedPath).

Release Notes:

- N/A

---------

Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Peter Tripp <petertripp@gmail.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
2025-09-24 18:57:33 -04:00
Alvaro Parker 5e7c173df0 Use \x00 representation instead of literal null characters (#38033)
When working on the git stash picker PR (#35927) I notice that my test
was detected as a binary file on the git diff view and on GitHub. This
was due to the fact that I was using the literal char \0 (instead of a
proper representation like `\x00` or `\u{0000}`) character in my test
strings. This causes problems with git diff and GitHub's diff viewer,
and a reviewer might even assume that the file is corrupted, not
viewable or even malicious.

Looking at the rest of the codebase, only at `crates/git/src/commit.rs`
this character was used, so I replaced it with `\x00` which is a more
common representation of the null character in Rust strings.

It can also be seen that the PR that introduced this code, can't be
viewed properly on Github:
https://github.com/zed-industries/zed/pull/27636/files#diff-31114f0b22306b467482573446f71c638277510b442a10e60dd9a8667ccd93c3

Closes #ISSUE

Release Notes:

- Use `\x00` representation instead of literal null character in strings
to improve compatibility with git diff and GitHub's diff viewer.

Since the file is not viewable from the "Files changed" tab on Github,
this is the changed code:


https://github.com/zed-industries/zed/blob/dcd743aca494ec0217a2d7751150ca9e456012f4/crates/git/src/commit.rs#L66-L74
2025-09-11 23:29:20 -06:00
Kirill Bulatov 6f2725844a Use anyhow more idiomatically (#31052)
https://github.com/zed-industries/zed/issues/30972 brought up another
case where our context is not enough to track the actual source of the
issue: we get a general top-level error without inner error.

The reason for this was `.ok_or_else(|| anyhow!("failed to read HEAD
SHA"))?; ` on the top level.

The PR finally reworks the way we use anyhow to reduce such issues (or
at least make it simpler to bubble them up later in a fix).
On top of that, uses a few more anyhow methods for better readability.

* `.ok_or_else(|| anyhow!("..."))`, `map_err` and other similar error
conversion/option reporting cases are replaced with `context` and
`with_context` calls
* in addition to that, various `anyhow!("failed to do ...")` are
stripped with `.context("Doing ...")` messages instead to remove the
parasitic `failed to` text
* `anyhow::ensure!` is used instead of `if ... { return Err(...); }`
calls
* `anyhow::bail!` is used instead of `return Err(anyhow!(...));`

Release Notes:

- N/A
2025-05-20 23:06:07 +00:00
Max Brunsfeld abc2daf81f Allow viewing past commits in Zed (#27636)
This PR adds functionality for loading the diff for an arbitrary git
commit, and displaying it in a tab. To retrieve the diff for the commit,
I'm using a single `git cat-file --batch` invocation to efficiently load
both the old and new versions of each file that was changed in the
commit.

Todo

* Features
* [x] Open the commit view when clicking the most recent commit message
in the commit panel
  * [x] Open the commit view when clicking a SHA in a git blame column
  * [x] Open the commit view when clicking a SHA in a commit tooltip
  * [x] Make it work over RPC
  * [x] Allow buffer search in commit view
* [x] Command palette action to open the commit for the current blame
line
* Styling
* [x] Add a header that shows the author, timestamp, and the full commit
message
  * [x] Remove stage/unstage buttons in commit view
  * [x] Truncate the commit message in the tab
* Bugs
  * [x] Dedup commit tabs within a pane
  * [x] Add a tooltip to the tab

Release Notes:

- Added the ability to show past commits in Zed. You can view the most
recent commit by clicking its message in the commit panel. And when
viewing a git blame, you can show any commit by clicking its sha.
2025-03-31 23:26:47 +00:00
Piotr Osiewicz d6520954b6 chore: Bump Rust edition to 2024 (#27800)
Follow-up to https://github.com/zed-industries/zed/pull/27791

Release Notes:

- N/A
2025-03-31 20:55:27 +02:00
7ac02d3821 Git on main thread (#26573)
This moves spawning of the git subprocess to the main thread. We're not
yet
sure why, but when we spawn a process using GCD's background queues,
sub-processes like git-credential-manager fail to open windows.

This seems to be fixable either by using the main thread, or by using a
standard background thread,
but for now we use the main thread.


Release Notes:

- Git: Fix git-credential-manager

---------

Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2025-03-12 19:39:30 +00:00
张小白 141fa584cd windows: Set CREATE_NO_WINDOW for commands (#18447)
- Closes: #18371

Release Notes:

- N/A
2024-11-20 16:52:38 -08:00
Piotr Osiewicz 9b464f483b chore: Fix several style lints (#17488)
It's not comprehensive enough to start linting on `style` group, but
hey, it's a start.

Release Notes:

- N/A
2024-09-06 11:58:39 +02:00
dovakin0007 b7ee2a4b07 Fix git commit popup message bracket (#16279) 2024-08-27 15:18:48 -04:00
Thorsten BallandBennet bcfcd39f84 git: Do not log error if repository has no commits (#11163)
This is a follow-up to #10685 which started to hide these errors instead
of displaying them to the user.

But the errors are still noisy and not actionable, so we hide them
instead.

Release Notes:

- Removed error message being logged when `git blame` is run in a
repository without commits.

Co-authored-by: Bennet <bennetbo@gmx.de>
2024-04-29 16:00:29 +02:00
Jason Wen fe2a7b36ff Prevent command prompt from opening when running git blame on windows (#10747)
Release Notes:

- Fixed issue reported in discord where the git blame feature would open
command prompt windows
2024-04-18 16:02:24 -07:00
bd3752ffd2 Add git blame (#8889)
This adds a new action to the editor: `editor: toggle git blame`. When
used it turns on a sidebar containing `git blame` information for the
currently open buffer.

The git blame information is updated when the buffer changes. It handles
additions, deletions, modifications, changes to the underlying git data
(new commits, changed commits, ...), file saves. It also handles folding
and wrapping lines correctly.

When the user hovers over a commit, a tooltip displays information for
the commit that introduced the line. If the repository has a remote with
the name `origin` configured, then clicking on a blame entry opens the
permalink to the commit on the code host.

Users can right-click on a blame entry to get a context menu which
allows them to copy the SHA of the commit.

The feature also works on shared projects, e.g. when collaborating a
peer can request `git blame` data.

As of this PR, Zed now comes bundled with a `git` binary so that users
don't have to have `git` installed locally to use this feature.

### Screenshots

![screenshot-2024-03-28-13 57
43@2x](https://github.com/zed-industries/zed/assets/1185253/ee8ec55d-3b5e-4d63-a85a-852da914f5ba)

![screenshot-2024-03-28-14 01
23@2x](https://github.com/zed-industries/zed/assets/1185253/2ba8efd7-e887-4076-a87a-587a732b9e9a)
![screenshot-2024-03-28-14 01
32@2x](https://github.com/zed-industries/zed/assets/1185253/496f4a06-b189-4881-b427-2289ae6e6075)

### TODOs

- [x] Bundling `git` binary

### Release Notes

Release Notes:

- Added `editor: toggle git blame` command that toggles a sidebar with
git blame information for the current buffer.

---------

Co-authored-by: Antonio <antonio@zed.dev>
Co-authored-by: Piotr <piotr@zed.dev>
Co-authored-by: Bennet <bennetbo@gmx.de>
Co-authored-by: Mikayla <mikayla@zed.dev>
2024-03-28 18:32:11 +01:00