Explorar el Código

Adds Change Base (branch/tag) command to file history view

Adds Change Base (branch/tag) command to line history view
main
Eric Amodio hace 6 años
padre
commit
755c1ff6f9
Se han modificado 14 ficheros con 325 adiciones y 187 borrados
  1. +38
    -2
      package.json
  2. +1
    -17
      src/commands/diffBranchWithBranch.ts
  3. +3
    -19
      src/commands/diffDirectory.ts
  4. +36
    -49
      src/commands/diffWithBranch.ts
  5. +27
    -1
      src/git/gitUri.ts
  6. +81
    -35
      src/quickpicks/branchesAndTagsQuickPick.ts
  7. +3
    -20
      src/quickpicks/commonQuickPicks.ts
  8. +9
    -1
      src/system/function.ts
  9. +7
    -1
      src/views/fileHistoryView.ts
  10. +7
    -0
      src/views/lineHistoryView.ts
  11. +63
    -36
      src/views/nodes/fileHistoryNode.ts
  12. +19
    -2
      src/views/nodes/fileHistoryTrackerNode.ts
  13. +12
    -2
      src/views/nodes/lineHistoryNode.ts
  14. +19
    -2
      src/views/nodes/lineHistoryTrackerNode.ts

+ 38
- 2
package.json Ver fichero

@ -2225,6 +2225,15 @@
"category": "GitLens"
},
{
"command": "gitlens.views.fileHistory.changeBase",
"title": "Change Base...",
"category": "GitLens",
"icon": {
"dark": "images/dark/icon-history.svg",
"light": "images/light/icon-history.svg"
}
},
{
"command": "gitlens.views.fileHistory.setEditorFollowingOn",
"title": "Resume File Tracking",
"category": "GitLens",
@ -2267,6 +2276,15 @@
"category": "GitLens"
},
{
"command": "gitlens.views.lineHistory.changeBase",
"title": "Change Base...",
"category": "GitLens",
"icon": {
"dark": "images/dark/icon-history.svg",
"light": "images/light/icon-history.svg"
}
},
{
"command": "gitlens.views.lineHistory.setEditorFollowingOn",
"title": "Resume Line Tracking",
"category": "GitLens",
@ -2808,6 +2826,10 @@
"when": "false"
},
{
"command": "gitlens.views.fileHistory.changeBase",
"when": "false"
},
{
"command": "gitlens.views.fileHistory.setEditorFollowingOn",
"when": "false"
},
@ -2832,6 +2854,10 @@
"when": "false"
},
{
"command": "gitlens.views.lineHistory.changeBase",
"when": "false"
},
{
"command": "gitlens.views.lineHistory.setEditorFollowingOn",
"when": "false"
},
@ -3180,11 +3206,16 @@
"group": "navigation@1"
},
{
"command": "gitlens.views.fileHistory.refresh",
"command": "gitlens.views.fileHistory.changeBase",
"when": "view =~ /^gitlens.views.fileHistory:/",
"group": "navigation@2"
},
{
"command": "gitlens.views.fileHistory.refresh",
"when": "view =~ /^gitlens.views.fileHistory:/",
"group": "navigation@99"
},
{
"command": "gitlens.views.fileHistory.setRenameFollowingOn",
"when": "view =~ /^gitlens.views.fileHistory:/ && !config.gitlens.advanced.fileHistoryFollowsRenames",
"group": "1_gitlens"
@ -3205,11 +3236,16 @@
"group": "navigation@1"
},
{
"command": "gitlens.views.lineHistory.refresh",
"command": "gitlens.views.lineHistory.changeBase",
"when": "view =~ /^gitlens.views.lineHistory:/",
"group": "navigation@2"
},
{
"command": "gitlens.views.lineHistory.refresh",
"when": "view =~ /^gitlens.views.lineHistory:/",
"group": "navigation@99"
},
{
"command": "gitlens.views.lineHistory.setRenameFollowingOn",
"when": "view =~ /^gitlens.views.lineHistory:/ && !config.gitlens.advanced.fileHistoryFollowsRenames",
"group": "1_gitlens"

+ 1
- 17
src/commands/diffBranchWithBranch.ts Ver fichero

@ -44,8 +44,6 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand {
uri = getCommandUri(uri, editor);
let progressCancellation: CancellationTokenSource | undefined;
try {
const repoPath = await getRepoPathOrActiveOrPrompt(
uri,
@ -68,18 +66,7 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand {
break;
}
progressCancellation = BranchesAndTagsQuickPick.showProgress(placeHolder);
const [branches, tags] = await Promise.all([
Container.git.getBranches(repoPath),
Container.git.getTags(repoPath)
]);
if (progressCancellation.token.isCancellationRequested) return undefined;
const pick = await BranchesAndTagsQuickPick.show(branches, tags, placeHolder, {
progressCancellation: progressCancellation
});
const pick = await new BranchesAndTagsQuickPick(repoPath).show(placeHolder);
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute();
@ -96,8 +83,5 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand {
Logger.error(ex, 'DiffBranchWithBranchCommand');
return Messages.showGenericErrorMessage('Unable to open branch compare');
}
finally {
progressCancellation && progressCancellation.cancel();
}
}
}

+ 3
- 19
src/commands/diffDirectory.ts Ver fichero

@ -50,8 +50,6 @@ export class DiffDirectoryCommand extends ActiveEditorCommand {
async execute(editor?: TextEditor, uri?: Uri, args: DiffDirectoryCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
let progressCancellation: CancellationTokenSource | undefined;
try {
const repoPath = await getRepoPathOrActiveOrPrompt(
uri,
@ -63,20 +61,9 @@ export class DiffDirectoryCommand extends ActiveEditorCommand {
if (!args.ref1) {
args = { ...args };
const placeHolder = `Compare Working Tree to${GlyphChars.Ellipsis}`;
progressCancellation = BranchesAndTagsQuickPick.showProgress(placeHolder);
const [branches, tags] = await Promise.all([
Container.git.getBranches(repoPath),
Container.git.getTags(repoPath)
]);
if (progressCancellation.token.isCancellationRequested) return undefined;
const pick = await BranchesAndTagsQuickPick.show(branches, tags, placeHolder, {
progressCancellation: progressCancellation
});
const pick = await new BranchesAndTagsQuickPick(repoPath).show(
`Compare Working Tree to${GlyphChars.Ellipsis}`
);
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute();
@ -106,8 +93,5 @@ export class DiffDirectoryCommand extends ActiveEditorCommand {
Logger.error(ex, 'DiffDirectoryCommand');
return Messages.showGenericErrorMessage('Unable to open directory compare');
}
finally {
progressCancellation && progressCancellation.cancel();
}
}
}

+ 36
- 49
src/commands/diffWithBranch.ts Ver fichero

@ -35,60 +35,47 @@ export class DiffWithBranchCommand extends ActiveEditorCommand {
const gitUri = await GitUri.fromUri(uri);
if (!gitUri.repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to open file compare`);
const placeHolder = `Compare ${paths.basename(gitUri.fsPath)} with${GlyphChars.Ellipsis}`;
const progressCancellation = BranchesAndTagsQuickPick.showProgress(placeHolder);
try {
const [branches, tags] = await Promise.all([
Container.git.getBranches(gitUri.repoPath),
Container.git.getTags(gitUri.repoPath)
]);
if (progressCancellation.token.isCancellationRequested) return undefined;
const pick = await BranchesAndTagsQuickPick.show(branches, tags, placeHolder, {
progressCancellation: progressCancellation,
goBackCommand: args.goBackCommand
});
if (pick === undefined) return undefined;
const pick = await new BranchesAndTagsQuickPick(gitUri.repoPath).show(
`Compare ${paths.basename(gitUri.fsPath)} with${GlyphChars.Ellipsis}`,
{
goBack: args.goBackCommand
}
);
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute();
if (pick instanceof CommandQuickPickItem) return pick.execute();
const ref = pick.name;
if (ref === undefined) return undefined;
const ref = pick.name;
if (ref === undefined) return undefined;
let renamedUri: Uri | undefined;
let renamedTitle: string | undefined;
let renamedUri: Uri | undefined;
let renamedTitle: string | undefined;
// Check to see if this file has been renamed
const files = await Container.git.getDiffStatus(gitUri.repoPath, 'HEAD', ref, { filter: 'R' });
if (files !== undefined) {
const fileName = Strings.normalizePath(paths.relative(gitUri.repoPath, gitUri.fsPath));
const rename = files.find(s => s.fileName === fileName);
if (rename !== undefined && rename.originalFileName !== undefined) {
renamedUri = Uri.file(paths.join(gitUri.repoPath, rename.originalFileName));
renamedTitle = `${paths.basename(rename.originalFileName)} (${ref})`;
}
// Check to see if this file has been renamed
const files = await Container.git.getDiffStatus(gitUri.repoPath, 'HEAD', ref, { filter: 'R' });
if (files !== undefined) {
const fileName = Strings.normalizePath(paths.relative(gitUri.repoPath, gitUri.fsPath));
const rename = files.find(s => s.fileName === fileName);
if (rename !== undefined && rename.originalFileName !== undefined) {
renamedUri = Uri.file(paths.join(gitUri.repoPath, rename.originalFileName));
renamedTitle = `${paths.basename(rename.originalFileName)} (${ref})`;
}
const diffArgs: DiffWithCommandArgs = {
repoPath: gitUri.repoPath,
lhs: {
sha: pick.remote ? `remotes/${ref}` : ref,
uri: renamedUri || (gitUri as Uri),
title: renamedTitle || `${paths.basename(gitUri.fsPath)} (${ref})`
},
rhs: {
sha: '',
uri: gitUri as Uri
},
line: args.line,
showOptions: args.showOptions
};
return commands.executeCommand(Commands.DiffWith, diffArgs);
}
finally {
progressCancellation.cancel();
}
const diffArgs: DiffWithCommandArgs = {
repoPath: gitUri.repoPath,
lhs: {
sha: pick.remote ? `remotes/${ref}` : ref,
uri: renamedUri || (gitUri as Uri),
title: renamedTitle || `${paths.basename(gitUri.fsPath)} (${ref})`
},
rhs: {
sha: '',
uri: gitUri as Uri
},
line: args.line,
showOptions: args.showOptions
};
return commands.executeCommand(Commands.DiffWith, diffArgs);
}
}

+ 27
- 1
src/git/gitUri.ts Ver fichero

@ -89,8 +89,34 @@ export class GitUri extends ((Uri as any) as UriEx) {
uri.authority,
paths.resolve(commitOrRepoPath.repoPath, commitOrRepoPath.fileName || uri.fsPath)
);
super({ scheme: uri.scheme, authority: authority, path: fsPath, query: uri.query, fragment: uri.fragment });
let path;
switch (uri.scheme) {
case 'https':
case 'http':
case 'file':
if (!fsPath) {
path = '/';
}
else if (fsPath[0] !== '/') {
path = `/${fsPath}`;
}
else {
path = fsPath;
}
break;
default:
path = fsPath;
break;
}
super({
scheme: uri.scheme,
authority: authority,
path: path,
query: uri.query,
fragment: uri.fragment
});
this.repoPath = commitOrRepoPath.repoPath;
this.versionedPath = commitOrRepoPath.versionedPath;
if (GitService.isStagedUncommitted(commitOrRepoPath.sha) || !GitService.isUncommitted(commitOrRepoPath.sha)) {

+ 81
- 35
src/quickpicks/branchesAndTagsQuickPick.ts Ver fichero

@ -1,10 +1,11 @@
'use strict';
import { CancellationTokenSource, QuickPickItem, QuickPickOptions, window } from 'vscode';
import { CancellationToken, CancellationTokenSource, QuickPickItem, QuickPickOptions, window } from 'vscode';
import { GlyphChars } from '../constants';
import { Container } from '../container';
import { GitBranch, GitTag } from '../git/gitService';
import { KeyNoopCommand } from '../keyboard';
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, showQuickPickProgress } from './commonQuickPicks';
import { Functions, Iterables } from '../system';
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from './commonQuickPicks';
export class BranchOrTagQuickPickItem implements QuickPickItem {
label: string;
@ -12,12 +13,15 @@ export class BranchOrTagQuickPickItem implements QuickPickItem {
detail: string | undefined;
constructor(
public readonly branchOrTag: GitBranch | GitTag
public readonly branchOrTag: GitBranch | GitTag,
checked?: boolean
) {
if (branchOrTag instanceof GitBranch) {
this.label = `${branchOrTag.current ? `$(check)${GlyphChars.Space}` : GlyphChars.Space.repeat(4)} ${
branchOrTag.name
}`;
this.label = `${
checked === true || (checked === undefined && branchOrTag.current)
? `$(check)${GlyphChars.Space}`
: GlyphChars.Space.repeat(4)
} ${branchOrTag.name}`;
this.description = branchOrTag.remote ? `${GlyphChars.Space.repeat(2)} remote branch` : '';
}
else {
@ -26,6 +30,10 @@ export class BranchOrTagQuickPickItem implements QuickPickItem {
}
}
get current() {
return this.branchOrTag instanceof GitBranch ? this.branchOrTag.current : false;
}
get name() {
return this.branchOrTag.name;
}
@ -36,45 +44,83 @@ export class BranchOrTagQuickPickItem implements QuickPickItem {
}
export class BranchesAndTagsQuickPick {
static showProgress(placeHolder: string) {
return showQuickPickProgress(placeHolder, {
left: KeyNoopCommand,
',': KeyNoopCommand,
'.': KeyNoopCommand
});
}
constructor(
public readonly repoPath: string
) {}
static async show(
branches: GitBranch[],
tags: GitTag[],
async show(
placeHolder: string,
options: { goBackCommand?: CommandQuickPickItem; progressCancellation?: CancellationTokenSource } = {}
options: { checked?: string; goBack?: CommandQuickPickItem } = {}
): Promise<BranchOrTagQuickPickItem | CommandQuickPickItem | undefined> {
const items = [
...branches.filter(b => !b.remote).map(b => new BranchOrTagQuickPickItem(b)),
...tags.map(t => new BranchOrTagQuickPickItem(t)),
...branches.filter(b => b.remote).map(b => new BranchOrTagQuickPickItem(b))
] as (BranchOrTagQuickPickItem | CommandQuickPickItem)[];
const cancellation = new CancellationTokenSource();
if (options.goBackCommand !== undefined) {
items.splice(0, 0, options.goBackCommand);
}
try {
const items = this.getItems(options, cancellation.token);
const scope = await Container.keyboard.beginScope({ left: options.goBack || KeyNoopCommand });
const pick = await window.showQuickPick(items, {
placeHolder: placeHolder,
ignoreFocusOut: getQuickPickIgnoreFocusOut()
} as QuickPickOptions);
if (options.progressCancellation !== undefined && options.progressCancellation.token.isCancellationRequested) {
return undefined;
if (pick === undefined) {
cancellation.cancel();
}
await scope.dispose();
return pick;
}
finally {
cancellation.dispose();
}
}
const scope = await Container.keyboard.beginScope({ left: options.goBackCommand || KeyNoopCommand });
private async getItems(
options: { checked?: string; goBack?: CommandQuickPickItem } = {},
token: CancellationToken
) {
const result = await Functions.cancellable(
Promise.all([Container.git.getBranches(this.repoPath), Container.git.getTags(this.repoPath)]),
token
);
if (result === undefined || token.isCancellationRequested) return [];
options.progressCancellation && options.progressCancellation.cancel();
const [branches, tags] = result;
const pick = await window.showQuickPick(items, {
placeHolder: placeHolder,
ignoreFocusOut: getQuickPickIgnoreFocusOut()
} as QuickPickOptions);
const items = [
...Iterables.filterMap(
branches,
b =>
!b.remote
? new BranchOrTagQuickPickItem(
b,
options.checked !== undefined ? b.name === options.checked : undefined
)
: undefined
),
...Iterables.filterMap(
branches,
b =>
b.remote
? new BranchOrTagQuickPickItem(
b,
options.checked !== undefined ? b.name === options.checked : undefined
)
: undefined
),
...tags.map(
t =>
new BranchOrTagQuickPickItem(
t,
options.checked !== undefined ? t.name === options.checked : undefined
)
)
] as (BranchOrTagQuickPickItem | CommandQuickPickItem)[];
await scope.dispose();
if (options.goBack !== undefined) {
items.splice(0, 0, options.goBack);
}
return pick;
return items;
}
}

+ 3
- 20
src/quickpicks/commonQuickPicks.ts Ver fichero

@ -136,7 +136,7 @@ export class ChooseFromBranchesAndTagsQuickPickItem extends CommandQuickPickItem
constructor(
private readonly repoPath: string,
private readonly placeHolder: string,
private readonly goBackCommand?: CommandQuickPickItem,
private readonly _goBack?: CommandQuickPickItem,
item: QuickPickItem = {
label: 'Choose from Branch or Tag History...',
description: `${Strings.pad(GlyphChars.Dash, 2, 2)} shows list of branches and tags`
@ -145,25 +145,8 @@ export class ChooseFromBranchesAndTagsQuickPickItem extends CommandQuickPickItem
super(item, undefined, undefined);
}
async execute(): Promise<CommandQuickPickItem | BranchOrTagQuickPickItem | undefined> {
const progressCancellation = BranchesAndTagsQuickPick.showProgress(this.placeHolder);
try {
const [branches, tags] = await Promise.all([
Container.git.getBranches(this.repoPath),
Container.git.getTags(this.repoPath)
]);
if (progressCancellation.token.isCancellationRequested) return undefined;
return BranchesAndTagsQuickPick.show(branches, tags, this.placeHolder, {
progressCancellation: progressCancellation,
goBackCommand: this.goBackCommand
});
}
finally {
progressCancellation.cancel();
}
execute(): Promise<CommandQuickPickItem | BranchOrTagQuickPickItem | undefined> {
return new BranchesAndTagsQuickPick(this.repoPath).show(this.placeHolder, { goBack: this._goBack });
}
}

+ 9
- 1
src/system/function.ts Ver fichero

@ -1,5 +1,5 @@
'use strict';
import { Disposable } from 'vscode';
import { CancellationToken, Disposable } from 'vscode';
const _debounce = require('lodash.debounce');
const _once = require('lodash.once');
@ -16,6 +16,14 @@ interface IPropOfValue {
}
export namespace Functions {
export function cancellable<T>(promise: Promise<T>, token: CancellationToken): Promise<T | undefined> {
return new Promise<T | undefined>((resolve, reject) => {
token.onCancellationRequested(() => resolve(undefined));
promise.then(resolve, reject);
});
}
export function debounce<T extends Function>(
fn: T,
wait?: number,

+ 7
- 1
src/views/fileHistoryView.ts Ver fichero

@ -28,7 +28,7 @@ export class FileHistoryView extends ViewBase {
(node: ViewNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args),
this
);
commands.registerCommand(this.getQualifiedCommand('changeBase'), () => this.changeBase(), this);
commands.registerCommand(
this.getQualifiedCommand('setEditorFollowingOn'),
() => this.setEditorFollowing(true),
@ -78,6 +78,12 @@ export class FileHistoryView extends ViewBase {
return { ...Container.config.views, ...Container.config.views.fileHistory };
}
private changeBase() {
if (this._root !== undefined) {
void this._root.changeBase();
}
}
private setEditorFollowing(enabled: boolean) {
setCommandContext(CommandContext.ViewsFileHistoryEditorFollowing, enabled);
if (this._root !== undefined) {

+ 7
- 0
src/views/lineHistoryView.ts Ver fichero

@ -28,6 +28,7 @@ export class LineHistoryView extends ViewBase {
(node: ViewNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args),
this
);
commands.registerCommand(this.getQualifiedCommand('changeBase'), () => this.changeBase(), this);
commands.registerCommand(
this.getQualifiedCommand('setEditorFollowingOn'),
() => this.setEditorFollowing(true),
@ -77,6 +78,12 @@ export class LineHistoryView extends ViewBase {
return { ...Container.config.views, ...Container.config.views.lineHistory };
}
private changeBase() {
if (this._root !== undefined) {
void this._root.changeBase();
}
}
private setEditorFollowing(enabled: boolean) {
setCommandContext(CommandContext.ViewsLineHistoryEditorFollowing, enabled);
if (this._root !== undefined) {

+ 63
- 36
src/views/nodes/fileHistoryNode.ts Ver fichero

@ -1,5 +1,6 @@
'use strict';
import { Disposable, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { GlyphChars } from '../../constants';
import { Container } from '../../container';
import {
GitCommitType,
@ -11,7 +12,7 @@ import {
RepositoryFileSystemChangeEvent
} from '../../git/gitService';
import { Logger } from '../../logger';
import { debug, Iterables } from '../../system';
import { debug, gate, Iterables, log } from '../../system';
import { FileHistoryView } from '../fileHistoryView';
import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode';
import { MessageNode } from './common';
@ -30,45 +31,49 @@ export class FileHistoryNode extends SubscribeableViewNode {
CommitFileNodeDisplayAs.CommitLabel |
(this.view.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.StatusIcon);
const status = await Container.git.getStatusForFile(this.uri.repoPath!, this.uri.fsPath);
if (status !== undefined && (status.indexStatus !== undefined || status.workingTreeStatus !== undefined)) {
let sha;
let previousSha;
if (status.workingTreeStatus !== undefined) {
sha = GitService.uncommittedSha;
if (status.indexStatus !== undefined) {
previousSha = GitService.stagedUncommittedSha;
if (this.uri.sha === undefined) {
const status = await Container.git.getStatusForFile(this.uri.repoPath!, this.uri.fsPath);
if (status !== undefined && (status.indexStatus !== undefined || status.workingTreeStatus !== undefined)) {
let sha;
let previousSha;
if (status.workingTreeStatus !== undefined) {
sha = GitService.uncommittedSha;
if (status.indexStatus !== undefined) {
previousSha = GitService.stagedUncommittedSha;
}
else if (status.workingTreeStatus !== '?') {
previousSha = 'HEAD';
}
}
else if (status.workingTreeStatus !== '?') {
else {
sha = GitService.stagedUncommittedSha;
previousSha = 'HEAD';
}
}
else {
sha = GitService.stagedUncommittedSha;
previousSha = 'HEAD';
}
const user = await Container.git.getCurrentUser(this.uri.repoPath!);
const commit = new GitLogCommit(
GitCommitType.File,
this.uri.repoPath!,
sha,
'You',
user !== undefined ? user.email : undefined,
new Date(),
new Date(),
'',
status.fileName,
[status],
status.status,
status.originalFileName,
previousSha,
status.originalFileName || status.fileName
);
children.push(new CommitFileNode(status, commit, this, this.view, displayAs));
const user = await Container.git.getCurrentUser(this.uri.repoPath!);
const commit = new GitLogCommit(
GitCommitType.File,
this.uri.repoPath!,
sha,
'You',
user !== undefined ? user.email : undefined,
new Date(),
new Date(),
'',
status.fileName,
[status],
status.status,
status.originalFileName,
previousSha,
status.originalFileName || status.fileName
);
children.push(new CommitFileNode(status, commit, this, this.view, displayAs));
}
}
const log = await Container.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, { ref: this.uri.sha });
const log = await Container.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, {
ref: this.uri.sha
});
if (log !== undefined) {
children.push(
...insertDateMarkers(
@ -86,9 +91,24 @@ export class FileHistoryNode extends SubscribeableViewNode {
}
getTreeItem(): TreeItem {
const item = new TreeItem(`${this.uri.getFormattedPath()}`, TreeItemCollapsibleState.Expanded);
const item = new TreeItem(
`${this.uri.getFormattedPath({
suffix: `${
this.uri.sha
? ` ${
this.uri.sha === GitService.deletedOrMissingSha
? this.uri.shortSha
: `(${this.uri.shortSha})`
}`
: ''
}`
})}`,
TreeItemCollapsibleState.Expanded
);
item.contextValue = ResourceType.FileHistory;
item.tooltip = `History of ${this.uri.getFilename()}\n${this.uri.getDirectory()}/`;
item.tooltip = `History of ${this.uri.getFilename()}\n${this.uri.getDirectory()}/${
this.uri.sha === undefined ? '' : `\n\n${this.uri.sha}`
}`;
item.iconPath = {
dark: Container.context.asAbsolutePath('images/dark/icon-history.svg'),
@ -100,6 +120,13 @@ export class FileHistoryNode extends SubscribeableViewNode {
return item;
}
@gate()
@log()
changeBase(ref: string | undefined) {
this.uri.sha = ref;
return this.triggerChange();
}
@debug()
protected async subscribe() {
const repo = await Container.git.getRepository(this.uri);

+ 19
- 2
src/views/nodes/fileHistoryTrackerNode.ts Ver fichero

@ -3,7 +3,8 @@ import * as paths from 'path';
import { Disposable, TextEditor, TreeItem, TreeItemCollapsibleState, Uri, window } from 'vscode';
import { UriComparer } from '../../comparers';
import { Container } from '../../container';
import { GitUri } from '../../git/gitService';
import { GitCommitish, GitUri } from '../../git/gitService';
import { BranchesAndTagsQuickPick, BranchOrTagQuickPickItem } from '../../quickpicks';
import { debug, Functions, gate, log } from '../../system';
import { FileHistoryView } from '../fileHistoryView';
import { MessageNode } from './common';
@ -11,6 +12,7 @@ import { FileHistoryNode } from './fileHistoryNode';
import { ResourceType, SubscribeableViewNode, unknownGitUri, ViewNode } from './viewNode';
export class FileHistoryTrackerNode extends SubscribeableViewNode<FileHistoryView> {
private _base: string | undefined;
private _child: FileHistoryNode | undefined;
constructor(view: FileHistoryView) {
@ -37,7 +39,8 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode
return [new MessageNode(this, 'There are no editors open that can provide file history information.')];
}
this._child = new FileHistoryNode(this.uri, this, this.view);
const fileUri = new GitUri(this.uri, { ...this.uri, sha: this.uri.sha || this._base } as GitCommitish);
this._child = new FileHistoryNode(fileUri, this, this.view);
}
return [this._child];
@ -53,6 +56,20 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode
}
@gate()
@log()
async changeBase() {
const pick = await new BranchesAndTagsQuickPick(this.uri.repoPath!).show('Change the file history base to...', {
checked: this._base
});
if (pick === undefined || !(pick instanceof BranchOrTagQuickPickItem)) return;
this._base = pick.current ? undefined : pick.name;
if (this._child === undefined) return;
await this._child.changeBase(this._base);
}
@gate()
@debug()
async refresh() {
const editor = window.activeTextEditor;

+ 12
- 2
src/views/nodes/lineHistoryNode.ts Ver fichero

@ -1,5 +1,6 @@
'use strict';
import { Disposable, Selection, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { GlyphChars } from '../../constants';
import { Container } from '../../container';
import { GitCommitType, GitFile, GitLogCommit } from '../../git/git';
import {
@ -10,7 +11,7 @@ import {
RepositoryFileSystemChangeEvent
} from '../../git/gitService';
import { Logger } from '../../logger';
import { debug, Iterables } from '../../system';
import { debug, gate, Iterables, log } from '../../system';
import { LineHistoryView } from '../lineHistoryView';
import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode';
import { MessageNode } from './common';
@ -112,7 +113,9 @@ export class LineHistoryNode extends SubscribeableViewNode {
TreeItemCollapsibleState.Expanded
);
item.contextValue = ResourceType.LineHistory;
item.tooltip = `History of ${this.uri.getFilename()}${lines}\n${this.uri.getDirectory()}/`;
item.tooltip = `History of ${this.uri.getFilename()}${lines}\n${this.uri.getDirectory()}/${
this.uri.sha === undefined ? '' : `\n\n${this.uri.sha}`
}`;
item.iconPath = {
dark: Container.context.asAbsolutePath('images/dark/icon-history.svg'),
@ -124,6 +127,13 @@ export class LineHistoryNode extends SubscribeableViewNode {
return item;
}
@gate()
@log()
changeBase(ref: string | undefined) {
this.uri.sha = ref;
return this.triggerChange();
}
@debug()
protected async subscribe() {
const repo = await Container.git.getRepository(this.uri);

+ 19
- 2
src/views/nodes/lineHistoryTrackerNode.ts Ver fichero

@ -2,7 +2,8 @@
import { Disposable, Selection, TreeItem, TreeItemCollapsibleState, window } from 'vscode';
import { UriComparer } from '../../comparers';
import { Container } from '../../container';
import { GitUri } from '../../git/gitService';
import { GitCommitish, GitUri } from '../../git/gitService';
import { BranchesAndTagsQuickPick, BranchOrTagQuickPickItem } from '../../quickpicks';
import { debug, Functions, gate, log } from '../../system';
import { LinesChangeEvent } from '../../trackers/gitLineTracker';
import { LineHistoryView } from '../lineHistoryView';
@ -11,6 +12,7 @@ import { LineHistoryNode } from './lineHistoryNode';
import { ResourceType, SubscribeableViewNode, unknownGitUri, ViewNode } from './viewNode';
export class LineHistoryTrackerNode extends SubscribeableViewNode<LineHistoryView> {
private _base: string | undefined;
private _child: LineHistoryNode | undefined;
private _selection: Selection | undefined;
@ -38,7 +40,8 @@ export class LineHistoryTrackerNode extends SubscribeableViewNode
return [new MessageNode(this, 'There are no editors open that can provide line history information.')];
}
this._child = new LineHistoryNode(this.uri, this._selection!, this, this.view);
const fileUri = new GitUri(this.uri, { ...this.uri, sha: this.uri.sha || this._base } as GitCommitish);
this._child = new LineHistoryNode(fileUri, this._selection!, this, this.view);
}
return [this._child];
@ -54,6 +57,20 @@ export class LineHistoryTrackerNode extends SubscribeableViewNode
}
@gate()
@log()
async changeBase() {
const pick = await new BranchesAndTagsQuickPick(this.uri.repoPath!).show('Change the line history base to...', {
checked: this._base
});
if (pick === undefined || !(pick instanceof BranchOrTagQuickPickItem)) return;
this._base = pick.current ? undefined : pick.name;
if (this._child === undefined) return;
await this._child.changeBase(this._base);
}
@gate()
@debug()
async refresh() {
const editor = window.activeTextEditor;

Cargando…
Cancelar
Guardar