Skip to content

Commit

Permalink
Closes #535 - Support commit ids in compares
Browse files Browse the repository at this point in the history
  • Loading branch information
eamodio committed Nov 12, 2018
1 parent 7b34a94 commit 0ee7e5e
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 36 deletions.
8 changes: 5 additions & 3 deletions src/commands/diffBranchWithBranch.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';
import { CancellationTokenSource, TextEditor, Uri } from 'vscode';
import { TextEditor, Uri } from 'vscode';
import { GlyphChars } from '../constants';
import { Container } from '../container';
import { Logger } from '../logger';
Expand Down Expand Up @@ -66,12 +66,14 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand {
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 instanceof CommandQuickPickItem) return pick.execute();

args.ref1 = pick.name;
args.ref1 = pick.ref;
if (args.ref1 === undefined) return undefined;
}

Expand Down
5 changes: 3 additions & 2 deletions src/commands/diffDirectory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,14 @@ export class DiffDirectoryCommand extends ActiveEditorCommand {
args = { ...args };

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 instanceof CommandQuickPickItem) return pick.execute();

args.ref1 = pick.name;
args.ref1 = pick.ref;
if (args.ref1 === undefined) return undefined;
}

Expand Down
3 changes: 2 additions & 1 deletion src/commands/diffWithBranch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,15 @@ export class DiffWithBranchCommand extends ActiveEditorCommand {
const pick = await new BranchesAndTagsQuickPick(gitUri.repoPath).show(
`Compare ${paths.basename(gitUri.fsPath)} with${GlyphChars.Ellipsis}`,
{
allowCommitId: true,
goBack: args.goBackCommand
}
);
if (pick === undefined) return undefined;

if (pick instanceof CommandQuickPickItem) return pick.execute();

const ref = pick.name;
const ref = pick.ref;
if (ref === undefined) return undefined;

let renamedUri: Uri | undefined;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/openBranchInRemote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class OpenBranchInRemoteCommand extends ActiveEditorCommand {
);
if (pick === undefined || pick instanceof CommandQuickPickItem) return undefined;

args.branch = pick.item.name;
args.branch = pick.ref;
}

const remotes = await Container.git.getRemotes(repoPath);
Expand Down
3 changes: 1 addition & 2 deletions src/commands/openFileInRemote.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
'use strict';
import { __await } from 'tslib';
import { commands, Range, TextEditor, Uri, window } from 'vscode';
import { GlyphChars } from '../constants';
import { Container } from '../container';
Expand Down Expand Up @@ -69,7 +68,7 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand {
);
if (pick === undefined || pick instanceof CommandQuickPickItem) return undefined;

args.branch = pick.item.name;
args.branch = pick.ref;
}
else {
args.branch = branch.name;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/showQuickBranchHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute();

args.branch = pick.item.name;
args.branch = pick.ref;
if (args.branch === undefined) return undefined;

progressCancellation = BranchHistoryQuickPick.showProgress(args.branch);
Expand Down
12 changes: 12 additions & 0 deletions src/git/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,18 @@ export class Git {
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) {
if (Git.isUncommitted(ref)) return ref;

Expand Down
6 changes: 6 additions & 0 deletions src/git/gitService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2015,6 +2015,12 @@ export class GitService implements Disposable {
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, uri: Uri): Promise<string>;
stageFile(repoPath: string, fileNameOrUri: string | Uri): Promise<string> {
Expand Down
118 changes: 102 additions & 16 deletions src/quickpicks/branchesAndTagsQuickPick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,38 @@
import { CancellationToken, CancellationTokenSource, QuickPickItem, QuickPickOptions, window } from 'vscode';
import { GlyphChars } from '../constants';
import { Container } from '../container';
import { GitBranch, GitTag } from '../git/gitService';
import { GitBranch, GitService, GitTag } from '../git/gitService';
import { Functions } from '../system';
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 {
label: string;
description: string;
Expand All @@ -20,8 +48,8 @@ export class BranchQuickPickItem implements QuickPickItem {
this.description = branch.remote
? `${GlyphChars.Space.repeat(2)} remote branch`
: branch.current
? 'current branch'
: '';
? 'current branch'
: '';
}

get current() {
Expand All @@ -32,7 +60,7 @@ export class BranchQuickPickItem implements QuickPickItem {
return this.branch;
}

get name() {
get ref() {
return this.branch.name;
}

Expand Down Expand Up @@ -62,7 +90,7 @@ export class TagQuickPickItem implements QuickPickItem {
return this.tag;
}

get name() {
get ref() {
return this.tag.name;
}

Expand All @@ -71,9 +99,10 @@ export class TagQuickPickItem implements QuickPickItem {
}
}

export type BranchOrTagQuickPickItem = BranchQuickPickItem | TagQuickPickItem;
export type BranchAndTagQuickPickResult = BranchQuickPickItem | TagQuickPickItem | RefQuickPickItem;

export interface BranchesAndTagsQuickPickOptions {
allowCommitId?: boolean;
autoPick?: boolean;
checked?: string;
filters?: {
Expand All @@ -92,7 +121,7 @@ export class BranchesAndTagsQuickPick {
async show(
placeHolder: string,
options: BranchesAndTagsQuickPickOptions = {}
): Promise<BranchOrTagQuickPickItem | CommandQuickPickItem | undefined> {
): Promise<BranchAndTagQuickPickResult | CommandQuickPickItem | undefined> {
const cancellation = new CancellationTokenSource();

let scope;
Expand All @@ -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) {
pick = autoPick;
Expand Down Expand Up @@ -173,7 +259,7 @@ export class BranchesAndTagsQuickPick {
}
}

const items: (BranchOrTagQuickPickItem | CommandQuickPickItem)[] = [];
const items: (BranchQuickPickItem | TagQuickPickItem | CommandQuickPickItem)[] = [];

if (branches !== undefined) {
const filter =
Expand Down
14 changes: 11 additions & 3 deletions src/quickpicks/commonQuickPicks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import { Container } from '../container';
import { GitLog, GitLogCommit, GitRepoSearchBy, GitStashCommit, GitUri } from '../git/gitService';
import { KeyMapping, Keys } from '../keyboard';
import { Functions, Strings } from '../system';
import { BranchesAndTagsQuickPick, BranchQuickPickItem, TagQuickPickItem } from './branchesAndTagsQuickPick';
import {
BranchesAndTagsQuickPick,
BranchQuickPickItem,
RefQuickPickItem,
TagQuickPickItem
} from './branchesAndTagsQuickPick';

export function getQuickPickIgnoreFocusOut() {
return !configuration.get<boolean>(configuration.name('advanced')('quickPick')('closeOnFocusOut').value);
Expand Down Expand Up @@ -145,8 +150,11 @@ export class ChooseFromBranchesAndTagsQuickPickItem extends CommandQuickPickItem
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
});
}
}

Expand Down
12 changes: 7 additions & 5 deletions src/views/nodes/compareNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,18 @@ export class CompareNode extends ViewNode<CompareView> {
}
else if (repoPath !== this._selectedRef.repoPath) {
// If we don't have a matching repoPath, then start over
this.selectForCompare(repoPath, ref);
void this.selectForCompare(repoPath, ref);
return;
}

if (ref === undefined) {
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;

ref = pick.name;
ref = pick.ref;
}

const ref1 = this._selectedRef;
Expand All @@ -151,11 +152,12 @@ export class CompareNode extends ViewNode<CompareView> {
let autoCompare = false;
if (ref === undefined) {
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;

ref = pick.name;
ref = pick.ref;

autoCompare = true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/views/nodes/fileHistoryTrackerNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode<FileHistoryVie
const pick = await new BranchesAndTagsQuickPick(this.uri.repoPath!).show(
`Change the file history base to${GlyphChars.Ellipsis}`,
{
allowCommitId: true,
checked: this._baseRef
}
);
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;

this._uri = unknownGitUri;
Expand Down
3 changes: 2 additions & 1 deletion src/views/nodes/lineHistoryTrackerNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,13 @@ export class LineHistoryTrackerNode extends SubscribeableViewNode<LineHistoryVie
const pick = await new BranchesAndTagsQuickPick(this.uri.repoPath!).show(
`Change the line history base to${GlyphChars.Ellipsis}`,
{
allowCommitId: true,
checked: this._base
}
);
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;

this._uri = unknownGitUri;
Expand Down

0 comments on commit 0ee7e5e

Please sign in to comment.