Skip to content

git: Add partial committing - #55179

Open
AidanV wants to merge 8 commits into
zed-industries:mainfrom
AidanV:partial-commit
Open

git: Add partial committing#55179
AidanV wants to merge 8 commits into
zed-industries:mainfrom
AidanV:partial-commit

Conversation

@AidanV

@AidanV AidanV commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator

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
  • Tests cover the new/changed behavior
  • Performance impact has been considered and is acceptable

Closes #45295

Release Notes:

  • Adds action for staging/unstaging selected lines ToggleStagedSelectedLines

  • Adds keybind to Windows for staging/unstaging hunks ctrl-alt-y. I am not sure why this wasn't already set. I do not have a windows machine, so I would appreciate some confirmation on this.

  • This PR does not make any UX decisions for how this feature will be used besides providing an action for it. This just provides the infrastructure to be able to make the correct UX decision in a follow up PR.

  • Known limitation: Identical lines without staging additional surrounding context can cause the line not under the cursor to be staged. This is fixable, but I think that that should be its own PR.

recording_20260429_14-44-05.mp4

@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Apr 29, 2026
@github-actions github-actions Bot added the community champion Issues filed by our amazing community champions! 🫶 label Apr 29, 2026
@zed-community-bot zed-community-bot Bot added the guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions label Apr 29, 2026
@SomeoneToIgnore SomeoneToIgnore added the area:integrations/git Git integration feedback label Apr 29, 2026
@AidanV

AidanV commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator Author

Apologies for the size of this PR. Many of the changes are closely connected. Happy to pair/walk through it.

@AidanV
AidanV force-pushed the partial-commit branch 3 times, most recently from 5de6541 to 98d53a9 Compare May 26, 2026 01:24
@janlarres

Copy link
Copy Markdown

Thanks for working on this! I just have one comment:

Instead of having to memorize yet another keybinding depending on context I think it would make sense to base the behaviour on whether there is a selection: if there is one then the existing keybinding only stages the selection, and if there isn't then it stages the current hunk just as before. This should also obviate the need for a drop-down menu on the Stage button. That would feel a lot more natural to me.

@AidanV
AidanV marked this pull request as draft June 13, 2026 22:40
@paolobenve

Copy link
Copy Markdown

why isn't this PR merged?

@AidanV
AidanV force-pushed the partial-commit branch 2 times, most recently from 5866b7b to bb1ef4d Compare June 26, 2026 04:57
@re1sub

re1sub commented Jul 2, 2026

Copy link
Copy Markdown

Is this feature abandoned?

@paolobenve

paolobenve commented Jul 2, 2026 via email

Copy link
Copy Markdown

@AidanV

AidanV commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator Author

I am close to finishing this, just busy.

@paolobenve

paolobenve commented Jul 2, 2026 via email

Copy link
Copy Markdown

@AidanV
AidanV marked this pull request as ready for review July 3, 2026 03:37
@AidanV

AidanV commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

@janlarres I took your advice and got rid of the other keybinding by doing partial staging if there is a selection. However, I think getting this behavior to be always intuitive is a little tricky, and I am curious to hear what you and others think. The main point of contention is figuring out when deletions that are collapsed should be staged. The behavior that I went with is that if the selection goes across the top of the hunk, then the deletions should be staged. I think this behavior is okay but not perfect, as it is not super obvious to the user that they did not stage the whole hunk if they select all of the lines (see video below).

I think this could be resolved with a visual change to the gutter so it doesn't look fully staged when collapsed (but is that enough? And what should that look like, I included a sketch below). Another, imperfect workaround is staging the deleted lines whenever all visible lines of a hunk are selected (but what if a user stages the first half, realizes they have only staged the first half, and then stages the second half? We end up back where we started: the hunk looks fully staged but isn't. Or what if they want to only stage the added lines, then staging the deleted lines is unexpected behavior).

I kept the drop-down. I like still being able to stage a specific hunk regardless of the current state of my cursor, and there should be a way for the user to partial stage without using a keybinding.

Current behavior:

recording_20260705_22-42-15.mp4

Example visual gutter change:
2026-07-05-225024_hyprshot

@janlarres

Copy link
Copy Markdown

@AidanV That's an interesting question. Intuitively I would think that selecting all of the lines in a hunk should work the same as staging the hunk as a whole, but you're right that that leads to ambiguity if someone stages a hunk piecemeal.

I'm currently mostly using LazyGit, which doesn't have this issue because modified lines are never collapsed but shown as individual added and deleted lines. LazyGit also has separate "hunk" and "line" modes instead of allowing selection of lines, and depending on the mode <space> stages either the current hunk or the current line. Zed already has a command to expand all hunks, maybe this could be integrated into a similar mode so that you're either in the default "hunk" mode or switch to a "line" mode where all the hunks are expanded, and the "stage" commands apply either to the current selection or to the current line if there is no selection? I'm not sure how feasible that is but it seems to me that it would solve the problems you're describing.

If the above idea is not feasible then a differently-coloured gutter like you described would at least make the ambiguities more obvious. It would even be helpful together with the above idea for when you switch back to "hunk" mode.

@AidanV

AidanV commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator Author

#46541 Is quite the merge conflict unfortunately. However, this is a complimentary change and should make this feature better in the long run. I am currently working through the necessary rewrite.

@AidanV
AidanV marked this pull request as draft July 11, 2026 03:24
@AidanV
AidanV force-pushed the partial-commit branch 4 times, most recently from 53d3698 to c9d4a32 Compare July 18, 2026 08:14
@AidanV

AidanV commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator Author

I finished resolving the merge conflict, and I removed the new keybinding and the drop-down UI feature. This means that after this PR lands the only way of interacting with this feature will be through dispatching the ToggleStagedSelectedLines action. We can improve the UX in follow-up PRs. The core functionality works well and increasing the scope of this PR to include discovering the correct UX decisions would drastically increase the length of review time.

Additionally, this feature is not yet implemented on the new 'view unstaged/staged' multibuffers. I am calling it out of scope, and it should be an easy follow up PR.

@AidanV
AidanV marked this pull request as ready for review July 18, 2026 08:49
@jakeleventhal

Copy link
Copy Markdown

@AidanV you should add this to context menu as well like vs code

right click "stage selected lines" and "unstage selected lines"

AidanV added 8 commits August 24, 2026 23:02
This was a bug in the integration test that was uncovered by correcting
the logic for `OverlapsWithSecondaryHunk` and `HasSecondaryHunk`.
Previously, partially staged deletions were incorrectly treated as
`HasSecondaryHunk`. The correction for partially staged deletions to
display as `OverlapsWithSecondaryHunk` is required for partial staging.

In this specific test, "TWO"'s deletion is staged, but "two"'s addition
is not staged leading to this edge case triggering.
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 community champion Issues filed by our amazing community champions! 🫶 guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Commit partial changes / Line-by-line staging

7 participants