Skip to content

Add "Uncommit changes" option to committed hunk context menu#13177

Open
cbjeukendrup wants to merge 1 commit intogitbutlerapp:masterfrom
cbjeukendrup:commited-hunk-context-menu-uncommit
Open

Add "Uncommit changes" option to committed hunk context menu#13177
cbjeukendrup wants to merge 1 commit intogitbutlerapp:masterfrom
cbjeukendrup:commited-hunk-context-menu-uncommit

Conversation

@cbjeukendrup
Copy link
Copy Markdown
Contributor

Scherm­afbeelding 2026-04-03 om 21.55.54.png

Copilot AI review requested due to automatic review settings April 3, 2026 19:56
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gitbutler-web Skipped Skipped Apr 3, 2026 7:56pm

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an “Uncommit changes” action to the hunk context menu when viewing committed diffs in the Desktop app, enabling uncommitting at the hunk level and keeping UI selection in sync after commit rewrite.

Changes:

  • Pass stackId and commitId into HunkContextMenu from UnifiedDiffView.
  • Add an “Uncommit changes” context menu item for committed hunks and implement the uncommitChanges call + selection update.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
apps/desktop/src/components/diff/UnifiedDiffView.svelte Wires stackId/commitId into the hunk context menu so committed hunks can trigger uncommit.
apps/desktop/src/components/diff/HunkContextMenu.svelte Adds “Uncommit changes” menu item and performs stackService.uncommitChanges, then updates lane selection.

const replacementCommit = replacedCommits.find(([before]) => before === commitId)?.[1];
const selection = uiState.lane(stackId).selection.current;

if (replacementCommit && selection) {
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When updating the lane selection after uncommitChanges, this will overwrite the current uiState.lane(stackId).selection even if the user is currently focused on a different commit in the same lane. Consider only updating the selection when selection.commitId === commitId (similar to how StackService.uncommit() only clears selection when the uncommitted commit matches the current selection), to avoid unexpected navigation jumps.

Suggested change
if (replacementCommit && selection) {
if (replacementCommit && selection && selection.commitId === commitId) {

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might not be a problem in practice, because I recall having seen similar code, and the existence of the HunkContextMenu instance already implies that its commit is the currently selected commit

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is not a bad idea to have.

Some extra context

We've been talking about decoupling selection from preview, since that has creating less-than nice UX around mutations. So, yes, the fact that you can access the HunkContextMenu at all currently implies that the commit in question is selected. But if that changes, we'd still mistakenly update the selection.

Let's err on double checking whether the stale commit was selected before we update the selection.

How to do this though

Let's add that check and update, only not at the component level.
In the StackService class (stackService.svelte.ts) we already have access to the UI State, and in some cases we already take care of updating the selection if necessary (e.g. updateBranchName).
That way, we don't have to deal with updating stale selection everywhere the mutation is called.

(We might still do so for some mutations but that is something to clean-up, rather than an intended pattern)

Please move this if-statement to the contents of uncommitChanges, so that the selection is updated only if the commit in question was already selected.

@estib-vega estib-vega self-assigned this Apr 6, 2026
Copy link
Copy Markdown
Contributor

@estib-vega estib-vega left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding this ❤️. I have no idea why this wasn't already part of the context menu options. Just left a comment on updating the UI state stale selection

const replacementCommit = replacedCommits.find(([before]) => before === commitId)?.[1];
const selection = uiState.lane(stackId).selection.current;

if (replacementCommit && selection) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is not a bad idea to have.

Some extra context

We've been talking about decoupling selection from preview, since that has creating less-than nice UX around mutations. So, yes, the fact that you can access the HunkContextMenu at all currently implies that the commit in question is selected. But if that changes, we'd still mistakenly update the selection.

Let's err on double checking whether the stale commit was selected before we update the selection.

How to do this though

Let's add that check and update, only not at the component level.
In the StackService class (stackService.svelte.ts) we already have access to the UI State, and in some cases we already take care of updating the selection if necessary (e.g. updateBranchName).
That way, we don't have to deal with updating stale selection everywhere the mutation is called.

(We might still do so for some mutations but that is something to clean-up, rather than an intended pattern)

Please move this if-statement to the contents of uncommitChanges, so that the selection is updated only if the commit in question was already selected.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants