git_ui: Improve the staged & unstaged grouping in the git panel - #60976
Conversation
@danilo-leal
As this is not out yet, I am hesitant to make an issue for this. |
|
@chirivelli What I was confused about the +/- thing was that despite the icon we show, the interaction was exactly the same, no? You click on the checkbox/button and the file gets staged and moved to the staged section. Even in partial staging scenarios, the +/- icon buttons didn't do a better/more special job of communicating that... so, to me it just felt like inconsistent UI treatment, given that the main difference between "tracked/untracked" and "staged/unstaged" is that in the former case, files never leave their bucket despite staging status, and in the latter, they do, by definition. |
|
Agreed, the interaction is exactly the same. But for partially staged files checkboxes showing ticked and empty in both sections is confusing (why is the checkbox checked when the file is not completely staged?). The +/- icon buttons doesn't indicate their state, just indicates the action (I'm considering them as neutral). |
I hear that, but I am not sure if having the +/- icon buttons solve this in a dramatically better way, because you'd be still seeing an entry for the same file twice in each bucket, but instead of one with a check and another with no check, one with a plus and another with a minus... Like, it's sort of a similar level of clarity when it comes to communicating its partiality. |
…industries#60976) Follow up to zed-industries#59884 This PR refines how the git panel behaves when grouping changes by staging state, with a focus on making staging workflows predictable and conflict resolution safe. - Renamed the "Group By" menu options to describe what you actually see: **"Tracked & Untracked"** (was "Status") and **"Staged & Unstaged"** (was "Staging"). - When grouping by staged & unstaged, both sections now stay visible even when empty, showing a placeholder message ("No staged changes yet" / "No unstaged changes"). Previously an empty section disappeared entirely, which made the panel layout jump around as you staged and unstaged files, and made it harder to tell at a glance that nothing was staged yet. - Section header controls are now consistent checkboxes everywhere (previously a mix of checkboxes and +/− icon buttons), with "Stage All" / "Unstage All" tooltips. Headers of empty sections render no checkbox and don't react to clicks or hover. I appreciate the debate that happened in the PR linked above about this but I was personally having a hard time understanding what was the difference in interaction given the action was exactly the same, we were just having different UIs, which looked inconsistent. - Arrow-key navigation now skips over section headers and empty-section placeholder rows in both flat and tree view, instead of getting stuck or selecting non-interactive rows — including when jumping to the first or last entry. - In the staged & unstaged grouping, a partially staged file appears in both sections. Each row's checkbox and tooltip now follow the section it's rendered in: rows in Staged always unstage, rows in Unstaged always stage — including via shift-click range operations, which now also support bulk *unstaging* within the Staged section (previously ranges could only stage). The context menu's Stage/Unstage label follows the same rule and stays in sync with in-flight staging operations. - Conflicted files are grouped by whether the current merge marked them conflicted (rather than raw status), so a conflict you've resolved stays visible under "Conflicts" until the merge concludes. On top of that, resolution is now one-way in the UI: - Ticking a conflicted file's checkbox marks it resolved (stages it). Once resolved, the checkbox is disabled with a "Conflict marked as resolved" tooltip — unticking it would silently discard git's record of the unmerged base/ours/theirs versions, a round-trip git can't actually perform. - The same lock applies everywhere the file can be reached: the keyboard toggle, folder checkboxes in tree view, the Conflicts section header (disabled once all conflicts are resolved), "Stage All"/"Unstage All" on the Staged/Unstaged headers, and shift-click range sweeps — none of them will resolve or un-resolve a conflict as a side effect. - The explicit `git: unstage file` action still works as a deliberate escape hatch. --- Here's a video, where you can see I stage and unstage whole files, make a partial staging, and get into a merge-conflict state, where the conflicted files are tagged as resolved: https://github.com/user-attachments/assets/d27ef9c6-5691-45c1-91ab-c3b152aaaa60 --- Release Notes: - N/A _(given the feature hasn't been released yet_)
…industries#60976) Follow up to zed-industries#59884 This PR refines how the git panel behaves when grouping changes by staging state, with a focus on making staging workflows predictable and conflict resolution safe. - Renamed the "Group By" menu options to describe what you actually see: **"Tracked & Untracked"** (was "Status") and **"Staged & Unstaged"** (was "Staging"). - When grouping by staged & unstaged, both sections now stay visible even when empty, showing a placeholder message ("No staged changes yet" / "No unstaged changes"). Previously an empty section disappeared entirely, which made the panel layout jump around as you staged and unstaged files, and made it harder to tell at a glance that nothing was staged yet. - Section header controls are now consistent checkboxes everywhere (previously a mix of checkboxes and +/− icon buttons), with "Stage All" / "Unstage All" tooltips. Headers of empty sections render no checkbox and don't react to clicks or hover. I appreciate the debate that happened in the PR linked above about this but I was personally having a hard time understanding what was the difference in interaction given the action was exactly the same, we were just having different UIs, which looked inconsistent. - Arrow-key navigation now skips over section headers and empty-section placeholder rows in both flat and tree view, instead of getting stuck or selecting non-interactive rows — including when jumping to the first or last entry. - In the staged & unstaged grouping, a partially staged file appears in both sections. Each row's checkbox and tooltip now follow the section it's rendered in: rows in Staged always unstage, rows in Unstaged always stage — including via shift-click range operations, which now also support bulk *unstaging* within the Staged section (previously ranges could only stage). The context menu's Stage/Unstage label follows the same rule and stays in sync with in-flight staging operations. - Conflicted files are grouped by whether the current merge marked them conflicted (rather than raw status), so a conflict you've resolved stays visible under "Conflicts" until the merge concludes. On top of that, resolution is now one-way in the UI: - Ticking a conflicted file's checkbox marks it resolved (stages it). Once resolved, the checkbox is disabled with a "Conflict marked as resolved" tooltip — unticking it would silently discard git's record of the unmerged base/ours/theirs versions, a round-trip git can't actually perform. - The same lock applies everywhere the file can be reached: the keyboard toggle, folder checkboxes in tree view, the Conflicts section header (disabled once all conflicts are resolved), "Stage All"/"Unstage All" on the Staged/Unstaged headers, and shift-click range sweeps — none of them will resolve or un-resolve a conflict as a side effect. - The explicit `git: unstage file` action still works as a deliberate escape hatch. --- Here's a video, where you can see I stage and unstage whole files, make a partial staging, and get into a merge-conflict state, where the conflicted files are tagged as resolved: https://github.com/user-attachments/assets/d27ef9c6-5691-45c1-91ab-c3b152aaaa60 --- Release Notes: - N/A _(given the feature hasn't been released yet_)
Follow up to #59884
This PR refines how the git panel behaves when grouping changes by staging state, with a focus on making staging workflows predictable and conflict resolution safe.
git: unstage fileaction still works as a deliberate escape hatch.Here's a video, where you can see I stage and unstage whole files, make a partial staging, and get into a merge-conflict state, where the conflicted files are tagged as resolved:
Screenshot.2026-07-14.at.11.11.mp4
Release Notes: