Browse Source

Closes #535 - Support commit ids in compares

main
Eric Amodio 6 years ago
parent
commit
0ee7e5e425
13 changed files with 155 additions and 36 deletions
  1. +5
    -3
      src/commands/diffBranchWithBranch.ts
  2. +3
    -2
      src/commands/diffDirectory.ts
  3. +2
    -1
      src/commands/diffWithBranch.ts
  4. +1
    -1
      src/commands/openBranchInRemote.ts
  5. +1
    -2
      src/commands/openFileInRemote.ts
  6. +1
    -1
      src/commands/showQuickBranchHistory.ts
  7. +12
    -0
      src/git/git.ts
  8. +6
    -0
      src/git/gitService.ts
  9. +102
    -16
      src/quickpicks/branchesAndTagsQuickPick.ts
  10. +11
    -3
      src/quickpicks/commonQuickPicks.ts
  11. +7
    -5
      src/views/nodes/compareNode.ts
  12. +2
    -1
      src/views/nodes/fileHistoryTrackerNode.ts
  13. +2
    -1
      src/views/nodes/lineHistoryTrackerNode.ts

+ 5
- 3
src/commands/diffBranchWithBranch.ts View File

@ -1,5 +1,5 @@
'use strict'; 'use strict';
import { CancellationTokenSource, TextEditor, Uri } from 'vscode';
import { TextEditor, Uri } from 'vscode';
import { GlyphChars } from '../constants'; import { GlyphChars } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
import { Logger } from '../logger'; import { Logger } from '../logger';
@ -66,12 +66,14 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand {
break; break;
} }
const pick = await new BranchesAndTagsQuickPick(repoPath).show(placeHolder);
const pick = await new BranchesAndTagsQuickPick(repoPath).show(placeHolder, {
allowCommitId: true
});
if (pick === undefined) return undefined; if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute(); if (pick instanceof CommandQuickPickItem) return pick.execute();
args.ref1 = pick.name;
args.ref1 = pick.ref;
if (args.ref1 === undefined) return undefined; if (args.ref1 === undefined) return undefined;
} }

+ 3
- 2
src/commands/diffDirectory.ts View File

@ -62,13 +62,14 @@ export class DiffDirectoryCommand extends ActiveEditorCommand {
args = { ...args }; args = { ...args };
const pick = await new BranchesAndTagsQuickPick(repoPath).show( const pick = await new BranchesAndTagsQuickPick(repoPath).show(
`Compare Working Tree with${GlyphChars.Ellipsis}`
`Compare Working Tree with${GlyphChars.Ellipsis}`,
{ allowCommitId: true }
); );
if (pick === undefined) return undefined; if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute(); if (pick instanceof CommandQuickPickItem) return pick.execute();
args.ref1 = pick.name;
args.ref1 = pick.ref;
if (args.ref1 === undefined) return undefined; if (args.ref1 === undefined) return undefined;
} }

+ 2
- 1
src/commands/diffWithBranch.ts View File

@ -38,6 +38,7 @@ export class DiffWithBranchCommand extends ActiveEditorCommand {
const pick = await new BranchesAndTagsQuickPick(gitUri.repoPath).show( const pick = await new BranchesAndTagsQuickPick(gitUri.repoPath).show(
`Compare ${paths.basename(gitUri.fsPath)} with${GlyphChars.Ellipsis}`, `Compare ${paths.basename(gitUri.fsPath)} with${GlyphChars.Ellipsis}`,
{ {
allowCommitId: true,
goBack: args.goBackCommand goBack: args.goBackCommand
} }
); );
@ -45,7 +46,7 @@ export class DiffWithBranchCommand extends ActiveEditorCommand {
if (pick instanceof CommandQuickPickItem) return pick.execute(); if (pick instanceof CommandQuickPickItem) return pick.execute();
const ref = pick.name;
const ref = pick.ref;
if (ref === undefined) return undefined; if (ref === undefined) return undefined;
let renamedUri: Uri | undefined; let renamedUri: Uri | undefined;

+ 1
- 1
src/commands/openBranchInRemote.ts View File

@ -65,7 +65,7 @@ export class OpenBranchInRemoteCommand extends ActiveEditorCommand {
); );
if (pick === undefined || pick instanceof CommandQuickPickItem) return undefined; if (pick === undefined || pick instanceof CommandQuickPickItem) return undefined;
args.branch = pick.item.name;
args.branch = pick.ref;
} }
const remotes = await Container.git.getRemotes(repoPath); const remotes = await Container.git.getRemotes(repoPath);

+ 1
- 2
src/commands/openFileInRemote.ts View File

@ -1,5 +1,4 @@
'use strict'; 'use strict';
import { __await } from 'tslib';
import { commands, Range, TextEditor, Uri, window } from 'vscode'; import { commands, Range, TextEditor, Uri, window } from 'vscode';
import { GlyphChars } from '../constants'; import { GlyphChars } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
@ -69,7 +68,7 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand {
); );
if (pick === undefined || pick instanceof CommandQuickPickItem) return undefined; if (pick === undefined || pick instanceof CommandQuickPickItem) return undefined;
args.branch = pick.item.name;
args.branch = pick.ref;
} }
else { else {
args.branch = branch.name; args.branch = branch.name;

+ 1
- 1
src/commands/showQuickBranchHistory.ts View File

@ -68,7 +68,7 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
if (pick === undefined) return undefined; if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute(); if (pick instanceof CommandQuickPickItem) return pick.execute();
args.branch = pick.item.name;
args.branch = pick.ref;
if (args.branch === undefined) return undefined; if (args.branch === undefined) return undefined;
progressCancellation = BranchHistoryQuickPick.showProgress(args.branch); progressCancellation = BranchHistoryQuickPick.showProgress(args.branch);

+ 12
- 0
src/git/git.ts View File

@ -549,6 +549,18 @@ export class Git {
return data === '' ? undefined : data.trim(); return data === '' ? undefined : data.trim();
} }
static async cat_validate(repoPath: string, ref: string) {
if (Git.isUncommitted(ref)) return true;
try {
await git<string>({ cwd: repoPath, exceptionHandler: throwExceptionHandler }, 'cat-file', '-t', ref);
return true;
}
catch (ex) {
return false;
}
}
static async cat_file_validate(repoPath: string, fileName: string, ref: string) { static async cat_file_validate(repoPath: string, fileName: string, ref: string) {
if (Git.isUncommitted(ref)) return ref; if (Git.isUncommitted(ref)) return ref;

+ 6
- 0
src/git/gitService.ts View File

@ -2015,6 +2015,12 @@ export class GitService implements Disposable {
return ensuredRef; return ensuredRef;
} }
async validateReference(repoPath: string, ref: string) {
Logger.log(`validateReference('${repoPath}', '${ref}'`);
return await Git.cat_validate(repoPath, ref);
}
stageFile(repoPath: string, fileName: string): Promise<string>; stageFile(repoPath: string, fileName: string): Promise<string>;
stageFile(repoPath: string, uri: Uri): Promise<string>; stageFile(repoPath: string, uri: Uri): Promise<string>;
stageFile(repoPath: string, fileNameOrUri: string | Uri): Promise<string> { stageFile(repoPath: string, fileNameOrUri: string | Uri): Promise<string> {

+ 102
- 16
src/quickpicks/branchesAndTagsQuickPick.ts View File

@ -2,10 +2,38 @@
import { CancellationToken, CancellationTokenSource, QuickPickItem, QuickPickOptions, window } from 'vscode'; import { CancellationToken, CancellationTokenSource, QuickPickItem, QuickPickOptions, window } from 'vscode';
import { GlyphChars } from '../constants'; import { GlyphChars } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
import { GitBranch, GitTag } from '../git/gitService';
import { GitBranch, GitService, GitTag } from '../git/gitService';
import { Functions } from '../system'; import { Functions } from '../system';
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from './commonQuickPicks'; import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from './commonQuickPicks';
export class RefQuickPickItem implements QuickPickItem {
label: string;
description: string;
detail: string | undefined;
constructor(
public readonly ref: string,
checked?: boolean
) {
this.label = `${checked ? `$(check)${GlyphChars.Space}` : GlyphChars.Space.repeat(4)} ${GitService.shortenSha(
ref
)}`;
this.description = '';
}
get current() {
return false;
}
get item() {
return undefined;
}
get remote() {
return false;
}
}
export class BranchQuickPickItem implements QuickPickItem { export class BranchQuickPickItem implements QuickPickItem {
label: string; label: string;
description: string; description: string;
@ -20,8 +48,8 @@ export class BranchQuickPickItem implements QuickPickItem {
this.description = branch.remote this.description = branch.remote
? `${GlyphChars.Space.repeat(2)} remote branch` ? `${GlyphChars.Space.repeat(2)} remote branch`
: branch.current : branch.current
? 'current branch'
: '';
? 'current branch'
: '';
} }
get current() { get current() {
@ -32,7 +60,7 @@ export class BranchQuickPickItem implements QuickPickItem {
return this.branch; return this.branch;
} }
get name() {
get ref() {
return this.branch.name; return this.branch.name;
} }
@ -62,7 +90,7 @@ export class TagQuickPickItem implements QuickPickItem {
return this.tag; return this.tag;
} }
get name() {
get ref() {
return this.tag.name; return this.tag.name;
} }
@ -71,9 +99,10 @@ export class TagQuickPickItem implements QuickPickItem {
} }
} }
export type BranchOrTagQuickPickItem = BranchQuickPickItem | TagQuickPickItem;
export type BranchAndTagQuickPickResult = BranchQuickPickItem | TagQuickPickItem | RefQuickPickItem;
export interface BranchesAndTagsQuickPickOptions { export interface BranchesAndTagsQuickPickOptions {
allowCommitId?: boolean;
autoPick?: boolean; autoPick?: boolean;
checked?: string; checked?: string;
filters?: { filters?: {
@ -92,7 +121,7 @@ export class BranchesAndTagsQuickPick {
async show( async show(
placeHolder: string, placeHolder: string,
options: BranchesAndTagsQuickPickOptions = {} options: BranchesAndTagsQuickPickOptions = {}
): Promise<BranchOrTagQuickPickItem | CommandQuickPickItem | undefined> {
): Promise<BranchAndTagQuickPickResult | CommandQuickPickItem | undefined> {
const cancellation = new CancellationTokenSource(); const cancellation = new CancellationTokenSource();
let scope; let scope;
@ -113,14 +142,71 @@ export class BranchesAndTagsQuickPick {
}); });
} }
let pick = await window.showQuickPick(
items,
{
placeHolder: placeHolder,
ignoreFocusOut: getQuickPickIgnoreFocusOut()
} as QuickPickOptions,
cancellation.token
);
let pick;
if (options.allowCommitId) {
placeHolder += `${GlyphChars.Space.repeat(3)}(use # to enter a commit id)`;
const quickpick = window.createQuickPick<BranchAndTagQuickPickResult | CommandQuickPickItem>();
quickpick.busy = true;
quickpick.enabled = false;
quickpick.placeholder = placeHolder;
quickpick.ignoreFocusOut = getQuickPickIgnoreFocusOut();
quickpick.show();
quickpick.items = await items;
quickpick.busy = false;
quickpick.enabled = true;
pick = await new Promise<BranchAndTagQuickPickResult | CommandQuickPickItem | undefined>(resolve => {
cancellation.token.onCancellationRequested(() => quickpick.hide());
quickpick.onDidHide(() => resolve(undefined));
quickpick.onDidChangeValue(value => {
quickpick.title =
value && value.startsWith('#')
? `Please enter a commit id (Press 'Enter' to confirm or 'Escape' to cancel)`
: undefined;
});
quickpick.onDidAccept(async () => {
if (quickpick.selectedItems.length === 0) {
let ref = quickpick.value;
if (!ref || !ref.startsWith('#')) return;
ref = ref.substr(1);
quickpick.busy = true;
quickpick.enabled = false;
if (await Container.git.validateReference(this.repoPath, ref)) {
resolve(new RefQuickPickItem(ref));
}
else {
quickpick.title = 'You must enter a valid commit id';
quickpick.busy = false;
quickpick.enabled = true;
return;
}
}
else {
resolve(quickpick.selectedItems[0]);
}
quickpick.hide();
});
});
quickpick.dispose();
}
else {
pick = await window.showQuickPick(
items,
{
placeHolder: placeHolder,
ignoreFocusOut: getQuickPickIgnoreFocusOut()
} as QuickPickOptions,
cancellation.token
);
}
if (pick === undefined && autoPick !== undefined) { if (pick === undefined && autoPick !== undefined) {
pick = autoPick; pick = autoPick;
@ -173,7 +259,7 @@ export class BranchesAndTagsQuickPick {
} }
} }
const items: (BranchOrTagQuickPickItem | CommandQuickPickItem)[] = [];
const items: (BranchQuickPickItem | TagQuickPickItem | CommandQuickPickItem)[] = [];
if (branches !== undefined) { if (branches !== undefined) {
const filter = const filter =

+ 11
- 3
src/quickpicks/commonQuickPicks.ts View File

@ -16,7 +16,12 @@ import { Container } from '../container';
import { GitLog, GitLogCommit, GitRepoSearchBy, GitStashCommit, GitUri } from '../git/gitService'; import { GitLog, GitLogCommit, GitRepoSearchBy, GitStashCommit, GitUri } from '../git/gitService';
import { KeyMapping, Keys } from '../keyboard'; import { KeyMapping, Keys } from '../keyboard';
import { Functions, Strings } from '../system'; import { Functions, Strings } from '../system';
import { BranchesAndTagsQuickPick, BranchQuickPickItem, TagQuickPickItem } from './branchesAndTagsQuickPick';
import {
BranchesAndTagsQuickPick,
BranchQuickPickItem,
RefQuickPickItem,
TagQuickPickItem
} from './branchesAndTagsQuickPick';
export function getQuickPickIgnoreFocusOut() { export function getQuickPickIgnoreFocusOut() {
return !configuration.get<boolean>(configuration.name('advanced')('quickPick')('closeOnFocusOut').value); return !configuration.get<boolean>(configuration.name('advanced')('quickPick')('closeOnFocusOut').value);
@ -145,8 +150,11 @@ export class ChooseFromBranchesAndTagsQuickPickItem extends CommandQuickPickItem
super(item, undefined, undefined); super(item, undefined, undefined);
} }
execute(): Promise<CommandQuickPickItem | BranchQuickPickItem | TagQuickPickItem | undefined> {
return new BranchesAndTagsQuickPick(this.repoPath).show(this.placeHolder, { goBack: this._goBack });
execute(): Promise<CommandQuickPickItem | BranchQuickPickItem | TagQuickPickItem | RefQuickPickItem | undefined> {
return new BranchesAndTagsQuickPick(this.repoPath).show(this.placeHolder, {
allowCommitId: true,
goBack: this._goBack
});
} }
} }

+ 7
- 5
src/views/nodes/compareNode.ts View File

@ -118,17 +118,18 @@ export class CompareNode extends ViewNode {
} }
else if (repoPath !== this._selectedRef.repoPath) { else if (repoPath !== this._selectedRef.repoPath) {
// If we don't have a matching repoPath, then start over // If we don't have a matching repoPath, then start over
this.selectForCompare(repoPath, ref);
void this.selectForCompare(repoPath, ref);
return; return;
} }
if (ref === undefined) { if (ref === undefined) {
const pick = await new BranchesAndTagsQuickPick(repoPath).show( const pick = await new BranchesAndTagsQuickPick(repoPath).show(
`Compare ${this.getRefName(this._selectedRef.ref)} with${GlyphChars.Ellipsis}`
`Compare ${this.getRefName(this._selectedRef.ref)} with${GlyphChars.Ellipsis}`,
{ allowCommitId: true }
); );
if (pick === undefined || pick instanceof CommandQuickPickItem) return; if (pick === undefined || pick instanceof CommandQuickPickItem) return;
ref = pick.name;
ref = pick.ref;
} }
const ref1 = this._selectedRef; const ref1 = this._selectedRef;
@ -151,11 +152,12 @@ export class CompareNode extends ViewNode {
let autoCompare = false; let autoCompare = false;
if (ref === undefined) { if (ref === undefined) {
const pick = await new BranchesAndTagsQuickPick(repoPath).show( const pick = await new BranchesAndTagsQuickPick(repoPath).show(
`Select branch or tag for compare${GlyphChars.Ellipsis}`
`Select branch or tag for compare${GlyphChars.Ellipsis}`,
{ allowCommitId: true }
); );
if (pick === undefined || pick instanceof CommandQuickPickItem) return; if (pick === undefined || pick instanceof CommandQuickPickItem) return;
ref = pick.name;
ref = pick.ref;
autoCompare = true; autoCompare = true;
} }

+ 2
- 1
src/views/nodes/fileHistoryTrackerNode.ts View File

@ -70,12 +70,13 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode
const pick = await new BranchesAndTagsQuickPick(this.uri.repoPath!).show( const pick = await new BranchesAndTagsQuickPick(this.uri.repoPath!).show(
`Change the file history base to${GlyphChars.Ellipsis}`, `Change the file history base to${GlyphChars.Ellipsis}`,
{ {
allowCommitId: true,
checked: this._baseRef checked: this._baseRef
} }
); );
if (pick === undefined || pick instanceof CommandQuickPickItem) return; if (pick === undefined || pick instanceof CommandQuickPickItem) return;
this._baseRef = pick.current ? undefined : pick.name;
this._baseRef = pick.current ? undefined : pick.ref;
if (this._child === undefined) return; if (this._child === undefined) return;
this._uri = unknownGitUri; this._uri = unknownGitUri;

+ 2
- 1
src/views/nodes/lineHistoryTrackerNode.ts View File

@ -69,12 +69,13 @@ export class LineHistoryTrackerNode extends SubscribeableViewNode
const pick = await new BranchesAndTagsQuickPick(this.uri.repoPath!).show( const pick = await new BranchesAndTagsQuickPick(this.uri.repoPath!).show(
`Change the line history base to${GlyphChars.Ellipsis}`, `Change the line history base to${GlyphChars.Ellipsis}`,
{ {
allowCommitId: true,
checked: this._base checked: this._base
} }
); );
if (pick === undefined || pick instanceof CommandQuickPickItem) return; if (pick === undefined || pick instanceof CommandQuickPickItem) return;
this._base = pick.current ? undefined : pick.name;
this._base = pick.current ? undefined : pick.ref;
if (this._child === undefined) return; if (this._child === undefined) return;
this._uri = unknownGitUri; this._uri = unknownGitUri;

Loading…
Cancel
Save