Skip to content

Add VS Code-style "Group by Staging" mode to the git panel - #48668

Closed
PSU3D0 wants to merge 3 commits into
zed-industries:mainfrom
PSU3D0:feat/git-panel-group-by-staging
Closed

Add VS Code-style "Group by Staging" mode to the git panel#48668
PSU3D0 wants to merge 3 commits into
zed-industries:mainfrom
PSU3D0:feat/git-panel-group-by-staging

Conversation

@PSU3D0

@PSU3D0 PSU3D0 commented Feb 7, 2026

Copy link
Copy Markdown

Summary

Adds a VS Code-style "Group by Staging" mode to the git panel, allowing users to see their changes organized into Staged Changes and Changes sections instead of the current Conflicts / Tracked / Untracked grouping.

This is controlled by a new git_panel.group_by setting:

{
  "git_panel": {
    "group_by": "staging"
  }
}

Behavior

  • "status" (default): Preserves the existing grouping — Conflicts, Tracked, Untracked. No behavior change.
  • "staging": Groups entries into "Staged Changes" and "Changes" sections.
    • Partially staged files appear in both sections.
    • Clicking a file under Staged Changes opens a diff showing only what's staged (HEAD → Index).
    • Clicking a file under Changes opens a diff showing only unstaged modifications (Index → Worktree).
    • Toggle between modes via right-click context menu on the git panel header.

Screenshots

image image image

Implementation

New setting (settings_content, git_panel_settings)

  • GitPanelGroupBy enum with Status and Staging variants
  • group_by field on GitPanelSettings, default Status

Git panel grouping (git_panel.rs)

  • Extended Section enum with Staged / Unstaged variants
  • update_visible_entries() classifies files by StageStatus when group_by == Staging
  • section_for_entry() walks backwards from a selected entry to find its section header
  • open_diff() detects whether the clicked entry is in a Staged or Unstaged section and opens the appropriate diff view
  • ToggleGroupByStaging action + context menu entry for toggling

Diff pipeline (branch_diff.rs, git_store.rs, project_diff.rs)

  • New DiffBase::Staged and DiffBase::Unstaged variants
  • BranchDiff::load_buffers() filters files by staging status for the new modes
  • BranchDiff::load_buffer() dispatches to the correct diff loader per mode:
    • StagedGitStore::open_staged_diff() (new) — creates a read-only buffer with index content, diffs against HEAD
    • UnstagedGitStore::open_unstaged_diff() (existing) — diffs index against worktree
    • Head / Merge → existing behavior unchanged
  • ProjectDiff::deploy_with_base() opens or reuses a ProjectDiff for a given DiffBase variant
  • Tab titles: "Staged Changes" / "Unstaged Changes"

Tests

  • 5 git panel tests: basic grouping, partially staged files, tree view mode, header toggling, empty section hiding
  • 3 project diff tests: staged diff content (HEAD→Index), unstaged diff content (Index→Worktree), staged-only file filtering

Release Notes:

  • Added a git_panel.group_by setting. When set to "staging", the git panel groups entries into "Staged Changes" and "Changes" sections (similar to VS Code). Clicking entries in each section shows the appropriate diff — staged changes show HEAD→Index, unstaged changes show Index→Worktree.

PSU3D0 and others added 3 commits February 6, 2026 17:21
Adds a new `git_panel.group_by` setting that controls how entries in the
git panel are grouped. The default value `"status"` preserves the existing
behavior (Conflicts / Tracked / Untracked). The new `"staging"` value
groups entries into 'Staged Changes' and 'Changes' sections, similar to
VS Code's Source Control panel.

Key behaviors:
- Partially staged files appear in both sections
- Clicking a file under 'Staged Changes' opens a HEAD→Index diff
- Clicking a file under 'Changes' opens an Index→Worktree diff
- Toggle via right-click context menu in the git panel header
- Setting persists in user settings.json

Implementation:
- New `DiffBase::Staged` and `DiffBase::Unstaged` variants for
  `BranchDiff` to load the correct diff type per section
- New `open_staged_diff()` on `GitStore` that creates a read-only
  buffer with index content and diffs it against HEAD
- `ProjectDiff::deploy_with_base()` to open/reuse ProjectDiff
  instances for each diff base variant
- Git panel detects which section a clicked entry belongs to and
  opens the appropriate diff view

Closes zed-industries#45295
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Feb 7, 2026
@zed-community-bot zed-community-bot Bot added the first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions label Feb 7, 2026
@fazulk

fazulk commented Mar 20, 2026

Copy link
Copy Markdown

please, we need it

@SomeoneToIgnore SomeoneToIgnore added the area:integrations/git Git integration feedback label Apr 28, 2026
@cole-miller

Copy link
Copy Markdown
Member

Thanks @PSU3D0 for opening a PR--this feature has been added to Zed in #59884 and will be in the next stable release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:integrations/git Git integration feedback cla-signed The user has signed the Contributor License Agreement first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

5 participants