You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
5.0 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. 'use strict';
  2. import { commands, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
  3. import { Container } from '../container';
  4. import { GitCommit, GitService, GitUri } from '../git/gitService';
  5. import { Logger } from '../logger';
  6. import { Messages } from '../messages';
  7. import { ActiveEditorCommand, command, CommandContext, Commands, getCommandUri } from './common';
  8. import { DiffWithCommandArgs } from './diffWith';
  9. import { UriComparer } from '../comparers';
  10. export interface DiffWithWorkingCommandArgs {
  11. commit?: GitCommit;
  12. line?: number;
  13. showOptions?: TextDocumentShowOptions;
  14. }
  15. @command()
  16. export class DiffWithWorkingCommand extends ActiveEditorCommand {
  17. constructor() {
  18. super([Commands.DiffWithWorking, Commands.DiffWithWorkingInDiff]);
  19. }
  20. protected preExecute(context: CommandContext, args: DiffWithWorkingCommandArgs = {}) {
  21. if (
  22. context.command === Commands.DiffWithWorkingInDiff
  23. // || (context.editor !== undefined && context.editor.viewColumn === undefined)
  24. ) {
  25. // HACK: If in a diff, try to determine if we are on the right or left side
  26. // If there is a context uri and it doesn't match the editor uri, assume we are on the left
  27. // If on the left, use the editor uri and pretend we aren't in a diff
  28. if (context.uri !== undefined && context.editor !== undefined && context.editor.document !== undefined) {
  29. if (!UriComparer.equals(context.uri, context.editor.document.uri, { exact: true })) {
  30. return this.execute(context.editor, context.editor.document.uri, args);
  31. }
  32. }
  33. }
  34. return this.execute(context.editor, context.uri, args);
  35. }
  36. async execute(editor?: TextEditor, uri?: Uri, args: DiffWithWorkingCommandArgs = {}): Promise<any> {
  37. uri = getCommandUri(uri, editor);
  38. if (uri == null) return undefined;
  39. const gitUri = await GitUri.fromUri(uri);
  40. args = { ...args };
  41. if (args.line === undefined) {
  42. args.line = editor == null ? 0 : editor.selection.active.line;
  43. }
  44. if (args.commit === undefined || args.commit.isUncommitted) {
  45. // If the sha is missing, just let the user know the file matches
  46. if (gitUri.sha === undefined) return window.showInformationMessage('File matches the working tree');
  47. if (gitUri.sha === GitService.deletedOrMissingSha) {
  48. return window.showWarningMessage('Unable to open compare. File has been deleted from the working tree');
  49. }
  50. // If we are a fake "staged" sha, check the status
  51. let ref: string | undefined = gitUri.sha;
  52. if (gitUri.isUncommittedStaged) {
  53. ref = undefined;
  54. const status = await Container.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath);
  55. if (status !== undefined && status.indexStatus !== undefined) {
  56. const diffArgs: DiffWithCommandArgs = {
  57. repoPath: gitUri.repoPath,
  58. lhs: {
  59. sha: GitService.uncommittedStagedSha,
  60. uri: gitUri.documentUri()
  61. },
  62. rhs: {
  63. sha: '',
  64. uri: gitUri.documentUri()
  65. },
  66. line: args.line,
  67. showOptions: args.showOptions
  68. };
  69. return commands.executeCommand(Commands.DiffWith, diffArgs);
  70. }
  71. }
  72. try {
  73. args.commit = await Container.git.getCommitForFile(gitUri.repoPath, gitUri.fsPath, {
  74. ref: ref,
  75. firstIfNotFound: true
  76. });
  77. if (args.commit === undefined) {
  78. return window.showWarningMessage(
  79. "Unable to open compare. File doesn't exist in the specified revision"
  80. );
  81. }
  82. }
  83. catch (ex) {
  84. Logger.error(
  85. ex,
  86. 'DiffWithWorkingCommand',
  87. `getLogCommit(${gitUri.repoPath}, ${gitUri.fsPath}, ${ref})`
  88. );
  89. return Messages.showGenericErrorMessage('Unable to open compare');
  90. }
  91. }
  92. const workingUri = await args.commit.getWorkingUri();
  93. if (workingUri === undefined) {
  94. return window.showWarningMessage('Unable to open compare. File has been deleted from the working tree');
  95. }
  96. const diffArgs: DiffWithCommandArgs = {
  97. repoPath: args.commit.repoPath,
  98. lhs: {
  99. sha: args.commit.sha,
  100. uri: args.commit.uri
  101. },
  102. rhs: {
  103. sha: '',
  104. uri: workingUri
  105. },
  106. line: args.line,
  107. showOptions: args.showOptions
  108. };
  109. return commands.executeCommand(Commands.DiffWith, diffArgs);
  110. }
  111. }