Skip to content

Commit

Permalink
Adds confirm to undo if there are uncommitted changes
Browse files Browse the repository at this point in the history
Refs #2746
  • Loading branch information
eamodio committed Dec 11, 2023
1 parent fcd498b commit 83ef923
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- Adds an inline _Open All Changes_ command to commits, stashes, and comparisons in the views
- Changes _Open All Changes_ & _Open All Changes with Working Tree_ commands to use the new multi-diff editor when enabled
- Requires VS Code `1.85` or later and `multiDiffEditor.experimental.enabled` to be enabled
- Adds a confirmation prompt when attempting to undo a commit with uncommitted changes
- Adds a _[Show|Hide] Merge Commits_ toggle to the _Contributors_ view

### Changed
Expand Down
48 changes: 46 additions & 2 deletions src/git/actions/commit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Commands, GlyphChars } from '../../constants';
import { Container } from '../../container';
import type { ShowInCommitGraphCommandArgs } from '../../plus/webviews/graph/protocol';
import { showRevisionPicker } from '../../quickpicks/revisionPicker';
import { executeCommand, executeEditorCommand } from '../../system/command';
import { executeCommand, executeCoreGitCommand, executeEditorCommand } from '../../system/command';
import { configuration } from '../../system/configuration';
import { findOrOpenEditor, findOrOpenEditors, openChangesEditor } from '../../system/utils';
import { GitUri } from '../gitUri';
Expand All @@ -23,7 +23,13 @@ import { deletedOrMissing } from '../models/constants';
import type { GitFile } from '../models/file';
import { GitFileChange } from '../models/file';
import type { GitRevisionReference } from '../models/reference';
import { getReferenceFromRevision, isUncommitted, isUncommittedStaged, shortenRevision } from '../models/reference';
import {
getReferenceFromRevision,
getReferenceLabel,
isUncommitted,
isUncommittedStaged,
shortenRevision,
} from '../models/reference';

type Ref = { repoPath: string; ref: string };
type RefRange = { repoPath: string; rhs: string; lhs: string };
Expand Down Expand Up @@ -771,6 +777,44 @@ export async function openOnlyChangedFiles(commitOrFiles: GitCommit | GitFile[])
}));
}

export async function undoCommit(container: Container, commit: GitRevisionReference) {
const repo = await container.git.getOrOpenScmRepository(commit.repoPath);
const scmCommit = await repo?.getCommit('HEAD');

if (scmCommit?.hash !== commit.ref) {
void window.showWarningMessage(
`Commit ${getReferenceLabel(commit, {
capitalize: true,
icon: false,
})} cannot be undone, because it is no longer the most recent commit.`,
);

return;
}

const status = await container.git.getStatusForRepo(commit.repoPath);
if (status?.files.length) {
const confirm = { title: 'Undo Commit' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`You have uncommitted changes in the working tree.\n\nDo you still want to undo ${getReferenceLabel(
commit,
{
capitalize: false,
icon: false,
},
)}?`,
{ modal: true },
confirm,
cancel,
);

if (result !== confirm) return;
}

await executeCoreGitCommand('git.undoCommit', commit.repoPath);
}

async function confirmOpenIfNeeded(
items: readonly unknown[],
options: { cancelButton?: string; confirmButton?: string; message: string; threshold: number },
Expand Down
21 changes: 3 additions & 18 deletions src/plus/webviews/graph/graphWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
openFilesAtRevision,
openOnlyChangedFiles,
showGraphDetailsView,
undoCommit,
} from '../../../git/actions/commit';
import * as ContributorActions from '../../../git/actions/contributor';
import * as RepoActions from '../../../git/actions/repository';
Expand All @@ -46,7 +47,6 @@ import type {
import {
createReference,
getReferenceFromBranch,
getReferenceLabel,
isGitReference,
isSha,
shortenRevision,
Expand All @@ -67,7 +67,6 @@ import {
executeActionCommand,
executeCommand,
executeCoreCommand,
executeCoreGitCommand,
registerCommand,
} from '../../../system/command';
import { configuration } from '../../../system/configuration';
Expand Down Expand Up @@ -2539,24 +2538,10 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph

@debug()
private async undoCommit(item?: GraphItemContext) {
const ref = this.getGraphItemRef(item);
const ref = this.getGraphItemRef(item, 'revision');
if (ref == null) return Promise.resolve();

const repo = await this.container.git.getOrOpenScmRepository(ref.repoPath);
const commit = await repo?.getCommit('HEAD');

if (commit?.hash !== ref.ref) {
void window.showWarningMessage(
`Commit ${getReferenceLabel(ref, {
capitalize: true,
icon: false,
})} cannot be undone, because it is no longer the most recent commit.`,
);

return;
}

return void executeCoreGitCommand('git.undoCommit', ref.repoPath);
await undoCommit(this.container, ref);
}

@debug()
Expand Down
18 changes: 2 additions & 16 deletions src/views/viewCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { GitUri } from '../git/gitUri';
import { deletedOrMissing } from '../git/models/constants';
import { matchContributor } from '../git/models/contributor';
import type { GitStashReference } from '../git/models/reference';
import { createReference, getReferenceLabel, shortenRevision } from '../git/models/reference';
import { createReference, shortenRevision } from '../git/models/reference';
import { showContributorsPicker } from '../quickpicks/contributorsPicker';
import {
executeActionCommand,
Expand Down Expand Up @@ -840,21 +840,7 @@ export class ViewCommands {
private async undoCommit(node: CommitNode | FileRevisionAsCommitNode) {
if (!node.isAny('commit', 'file-commit')) return;

const repo = await this.container.git.getOrOpenScmRepository(node.repoPath);
const commit = await repo?.getCommit('HEAD');

if (commit?.hash !== node.ref.ref) {
void window.showWarningMessage(
`Commit ${getReferenceLabel(node.ref, {
capitalize: true,
icon: false,
})} cannot be undone, because it is no longer the most recent commit.`,
);

return;
}

await executeCoreGitCommand('git.undoCommit', node.repoPath);
await CommitActions.undoCommit(this.container, node.ref);
}

@log()
Expand Down

0 comments on commit 83ef923

Please sign in to comment.