From f73c34eb2d1a24703367e96fe1958b40155e3bc2 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 17 Feb 2017 21:57:24 +0100 Subject: [PATCH] git: revert selected ranges --- extensions/git/package.json | 5 ++++ extensions/git/package.nls.json | 1 + extensions/git/src/commands.ts | 48 ++++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 2cfb5e83b27..7a4111aaad0 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -80,6 +80,11 @@ "title": "%command.stageSelectedRanges%", "category": "Git" }, + { + "command": "git.revertSelectedRanges", + "title": "%command.revertSelectedRanges%", + "category": "Git" + }, { "command": "git.unstage", "title": "%command.unstage%", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index c830eb7ff20..b4cb85e4de8 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -6,6 +6,7 @@ "command.stage": "Stage", "command.stageAll": "Stage All", "command.stageSelectedRanges": "Stage Selected Ranges", + "command.revertSelectedRanges": "Revert Selected Ranges", "command.unstage": "Unstage", "command.unstageAll": "Unstage All", "command.unstageSelectedRanges": "Unstage Selected Ranges", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 5c943b96418..c96aaf9dd8a 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -5,7 +5,7 @@ 'use strict'; -import { Uri, commands, scm, Disposable, SCMResourceGroup, SCMResource, window, workspace, QuickPickItem, OutputChannel, computeDiff, Range } from 'vscode'; +import { Uri, commands, scm, Disposable, SCMResourceGroup, SCMResource, window, workspace, QuickPickItem, OutputChannel, computeDiff, Range, WorkspaceEdit, Position } from 'vscode'; import { Ref, RefType } from './git'; import { Model, Resource, Status, CommitOptions } from './model'; import * as staging from './staging'; @@ -270,6 +270,52 @@ export class CommandCenter { await this.model.stage(modifiedUri, result); } + @command('git.revertSelectedRanges') + async revertSelectedRanges(): Promise { + const textEditor = window.activeTextEditor; + + if (!textEditor) { + return; + } + + const modifiedDocument = textEditor.document; + const modifiedUri = modifiedDocument.uri; + + if (modifiedUri.scheme !== 'file') { + return; + } + + const originalUri = modifiedUri.with({ scheme: 'git', query: '~' }); + const originalDocument = await workspace.openTextDocument(originalUri); + const diffs = await computeDiff(originalDocument, modifiedDocument); + const selections = textEditor.selections; + const selectedDiffs = diffs.filter(diff => { + const modifiedRange = diff.modifiedEndLineNumber === 0 + ? new Range(modifiedDocument.lineAt(diff.modifiedStartLineNumber - 1).range.end, modifiedDocument.lineAt(diff.modifiedStartLineNumber).range.start) + : new Range(modifiedDocument.lineAt(diff.modifiedStartLineNumber - 1).range.start, modifiedDocument.lineAt(diff.modifiedEndLineNumber - 1).range.end); + + return selections.every(selection => !selection.intersection(modifiedRange)); + }); + + if (selectedDiffs.length === diffs.length) { + return; + } + + const basename = path.basename(modifiedUri.fsPath); + const message = localize('confirm revert', "Are you sure you want to revert the selected changes in {0}?", basename); + const yes = localize('revert', "Revert Changes"); + const pick = await window.showWarningMessage(message, { modal: true }, yes); + + if (pick !== yes) { + return; + } + + const result = staging.applyChanges(originalDocument, modifiedDocument, selectedDiffs); + const edit = new WorkspaceEdit(); + edit.replace(modifiedUri, new Range(new Position(0, 0), modifiedDocument.lineAt(modifiedDocument.lineCount - 1).range.end), result); + workspace.applyEdit(edit); + } + @command('git.unstage') async unstage(uri: Uri): Promise { const resource = resolveGitResource(uri); -- GitLab