Archived
1
0

chore(vscode): update to 1.54.2

This commit is contained in:
Joe Previte
2021-03-11 10:27:10 -07:00
1459 changed files with 53404 additions and 51004 deletions

View File

@ -30,7 +30,7 @@ function main(argv: string[]): void {
const output = process.env['VSCODE_GIT_ASKPASS_PIPE'] as string;
const request = argv[2];
const host = argv[4].replace(/^["']+|["']+$/g, '');
const host = argv[4].replace(/^["']+|["':]+$/g, '');
const ipcClient = new IPCClient('askpass');
ipcClient.call({ request, host }).then(res => {

View File

@ -5,7 +5,7 @@
import * as os from 'os';
import * as path from 'path';
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider } from 'vscode';
import { Command, commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider } from 'vscode';
import TelemetryReporter from 'vscode-extension-telemetry';
import * as nls from 'vscode-nls';
import { Branch, ForcePushMode, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourceProvider } from './api/git';
@ -153,21 +153,21 @@ class AddRemoteItem implements QuickPickItem {
}
}
interface CommandOptions {
interface ScmCommandOptions {
repository?: boolean;
diff?: boolean;
}
interface Command {
interface ScmCommand {
commandId: string;
key: string;
method: Function;
options: CommandOptions;
options: ScmCommandOptions;
}
const Commands: Command[] = [];
const Commands: ScmCommand[] = [];
function command(commandId: string, options: CommandOptions = {}): Function {
function command(commandId: string, options: ScmCommandOptions = {}): Function {
return (_target: any, key: string, descriptor: any) => {
if (!(typeof descriptor.value === 'function')) {
throw new Error('not supported');
@ -374,16 +374,20 @@ export class CommandCenter {
@command('git.openAllChanges', { repository: true })
async openChanges(repository: Repository): Promise<void> {
[
...repository.workingTreeGroup.resourceStates,
...repository.untrackedGroup.resourceStates,
].forEach(resource => {
commands.executeCommand(
for (const resource of [...repository.workingTreeGroup.resourceStates, ...repository.untrackedGroup.resourceStates]) {
if (
resource.type === Status.DELETED || resource.type === Status.DELETED_BY_THEM ||
resource.type === Status.DELETED_BY_US || resource.type === Status.BOTH_DELETED
) {
continue;
}
void commands.executeCommand(
'vscode.open',
resource.resourceUri,
{ preview: false, }
{ background: true, preview: false, }
);
});
}
}
async cloneRepository(url?: string, parentPath?: string, options: { recursive?: boolean } = {}): Promise<void> {
@ -2608,6 +2612,22 @@ export class CommandCenter {
@command('git.timeline.openDiff', { repository: false })
async timelineOpenDiff(item: TimelineItem, uri: Uri | undefined, _source: string) {
const cmd = this.resolveTimelineOpenDiffCommand(
item, uri,
{
preserveFocus: true,
preview: true,
viewColumn: ViewColumn.Active
},
);
if (cmd === undefined) {
return undefined;
}
return commands.executeCommand(cmd.command, ...(cmd.arguments ?? []));
}
resolveTimelineOpenDiffCommand(item: TimelineItem, uri: Uri | undefined, options?: TextDocumentShowOptions): Command | undefined {
if (uri === undefined || uri === null || !GitTimelineItem.is(item)) {
return undefined;
}
@ -2624,13 +2644,11 @@ export class CommandCenter {
title = localize('git.title.diffRefs', '{0} ({1}) ⟷ {0} ({2})', basename, item.shortPreviousRef, item.shortRef);
}
const options: TextDocumentShowOptions = {
preserveFocus: true,
preview: true,
viewColumn: ViewColumn.Active
return {
command: 'vscode.diff',
title: 'Open Comparison',
arguments: [toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title, options]
};
return commands.executeCommand('vscode.diff', toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title, options);
}
@command('git.timeline.copyCommitId', { repository: false })
@ -2651,6 +2669,52 @@ export class CommandCenter {
env.clipboard.writeText(item.message);
}
private _selectedForCompare: { uri: Uri, item: GitTimelineItem } | undefined;
@command('git.timeline.selectForCompare', { repository: false })
async timelineSelectForCompare(item: TimelineItem, uri: Uri | undefined, _source: string) {
if (!GitTimelineItem.is(item) || !uri) {
return;
}
this._selectedForCompare = { uri, item };
await commands.executeCommand('setContext', 'git.timeline.selectedForCompare', true);
}
@command('git.timeline.compareWithSelected', { repository: false })
async timelineCompareWithSelected(item: TimelineItem, uri: Uri | undefined, _source: string) {
if (!GitTimelineItem.is(item) || !uri || !this._selectedForCompare || uri.toString() !== this._selectedForCompare.uri.toString()) {
return;
}
const { item: selected } = this._selectedForCompare;
const basename = path.basename(uri.fsPath);
let leftTitle;
if ((selected.previousRef === 'HEAD' || selected.previousRef === '~') && selected.ref === '') {
leftTitle = localize('git.title.workingTree', '{0} (Working Tree)', basename);
}
else if (selected.previousRef === 'HEAD' && selected.ref === '~') {
leftTitle = localize('git.title.index', '{0} (Index)', basename);
} else {
leftTitle = localize('git.title.ref', '{0} ({1})', basename, selected.shortRef);
}
let rightTitle;
if ((item.previousRef === 'HEAD' || item.previousRef === '~') && item.ref === '') {
rightTitle = localize('git.title.workingTree', '{0} (Working Tree)', basename);
}
else if (item.previousRef === 'HEAD' && item.ref === '~') {
rightTitle = localize('git.title.index', '{0} (Index)', basename);
} else {
rightTitle = localize('git.title.ref', '{0} ({1})', basename, item.shortRef);
}
const title = localize('git.title.diff', '{0} ⟷ {1}', leftTitle, rightTitle);
await commands.executeCommand('vscode.diff', selected.ref === '' ? uri : toGitUri(uri, selected.ref), item.ref === '' ? uri : toGitUri(uri, item.ref), title);
}
@command('git.rebaseAbort', { repository: true })
async rebaseAbort(repository: Repository): Promise<void> {
if (repository.rebaseCommit) {
@ -2660,7 +2724,7 @@ export class CommandCenter {
}
}
private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any {
private createCommand(id: string, key: string, method: Function, options: ScmCommandOptions): (...args: any[]) => any {
const result = (...args: any[]) => {
let result: Promise<any>;

View File

@ -823,8 +823,7 @@ export class Repository {
return this.repositoryRoot;
}
// TODO@Joao: rename to exec
async run(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
async exec(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
return await this.git.exec(this.repositoryRoot, args, options);
}
@ -849,7 +848,7 @@ export class Repository {
args.push(value);
}
const result = await this.run(args, options);
const result = await this.exec(args, options);
return result.stdout.trim();
}
@ -862,7 +861,7 @@ export class Repository {
args.push('-l');
const result = await this.run(args);
const result = await this.exec(args);
const lines = result.stdout.trim().split(/\r|\r\n|\n/);
return lines.map(entry => {
@ -878,7 +877,7 @@ export class Repository {
args.push(options.path);
}
const result = await this.run(args);
const result = await this.exec(args);
if (result.exitCode) {
// An empty repo
return [];
@ -909,7 +908,7 @@ export class Repository {
args.push('--', uri.fsPath);
const result = await this.run(args);
const result = await this.exec(args);
if (result.exitCode) {
// No file history, e.g. a new file or untracked
return [];
@ -964,7 +963,7 @@ export class Repository {
}
const { mode, object } = elements[0];
const catFile = await this.run(['cat-file', '-s', object]);
const catFile = await this.exec(['cat-file', '-s', object]);
const size = parseInt(catFile.stdout);
return { mode, object, size };
@ -981,12 +980,12 @@ export class Repository {
}
async lstree(treeish: string, path: string): Promise<LsTreeElement[]> {
const { stdout } = await this.run(['ls-tree', '-l', treeish, '--', sanitizePath(path)]);
const { stdout } = await this.exec(['ls-tree', '-l', treeish, '--', sanitizePath(path)]);
return parseLsTree(stdout);
}
async lsfiles(path: string): Promise<LsFilesElement[]> {
const { stdout } = await this.run(['ls-files', '--stage', '--', sanitizePath(path)]);
const { stdout } = await this.exec(['ls-files', '--stage', '--', sanitizePath(path)]);
return parseLsFiles(stdout);
}
@ -1051,7 +1050,7 @@ export class Repository {
}
try {
await this.run(args);
await this.exec(args);
} catch (err) {
if (/patch does not apply/.test(err.stderr)) {
err.gitErrorCode = GitErrorCodes.PatchDoesNotApply;
@ -1068,7 +1067,7 @@ export class Repository {
args.push('--cached');
}
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1081,7 +1080,7 @@ export class Repository {
}
const args = ['diff', '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1094,7 +1093,7 @@ export class Repository {
}
const args = ['diff', ref, '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1107,7 +1106,7 @@ export class Repository {
}
const args = ['diff', '--cached', '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1120,13 +1119,13 @@ export class Repository {
}
const args = ['diff', '--cached', ref, '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
async diffBlobs(object1: string, object2: string): Promise<string> {
const args = ['diff', object1, object2];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1140,7 +1139,7 @@ export class Repository {
}
const args = ['diff', range, '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout.trim();
}
@ -1155,7 +1154,7 @@ export class Repository {
args.push(ref);
}
const gitResult = await this.run(args);
const gitResult = await this.exec(args);
if (gitResult.exitCode) {
return [];
}
@ -1228,14 +1227,14 @@ export class Repository {
async getMergeBase(ref1: string, ref2: string): Promise<string> {
const args = ['merge-base', ref1, ref2];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout.trim();
}
async hashObject(data: string): Promise<string> {
const args = ['hash-object', '-w', '--stdin'];
const result = await this.run(args, { input: data });
const result = await this.exec(args, { input: data });
return result.stdout.trim();
}
@ -1251,10 +1250,10 @@ export class Repository {
if (paths && paths.length) {
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
await this.run([...args, '--', ...chunk]);
await this.exec([...args, '--', ...chunk]);
}
} else {
await this.run([...args, '--', '.']);
await this.exec([...args, '--', '.']);
}
}
@ -1267,7 +1266,7 @@ export class Repository {
args.push(...paths.map(sanitizePath));
await this.run(args);
await this.exec(args);
}
async stage(path: string, data: string): Promise<void> {
@ -1300,7 +1299,7 @@ export class Repository {
add = '--add';
}
await this.run(['update-index', add, '--cacheinfo', mode, hash, path]);
await this.exec(['update-index', add, '--cacheinfo', mode, hash, path]);
}
async checkout(treeish: string, paths: string[], opts: { track?: boolean, detached?: boolean } = Object.create(null)): Promise<void> {
@ -1321,10 +1320,10 @@ export class Repository {
try {
if (paths && paths.length > 0) {
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
await this.run([...args, '--', ...chunk]);
await this.exec([...args, '--', ...chunk]);
}
} else {
await this.run(args);
await this.exec(args);
}
} catch (err) {
if (/Please,? commit your changes or stash them/.test(err.stderr || '')) {
@ -1375,21 +1374,21 @@ export class Repository {
}
try {
await this.run(args, !opts.amend || message ? { input: message || '' } : {});
await this.exec(args, !opts.amend || message ? { input: message || '' } : {});
} catch (commitErr) {
await this.handleCommitError(commitErr);
}
}
async rebaseAbort(): Promise<void> {
await this.run(['rebase', '--abort']);
await this.exec(['rebase', '--abort']);
}
async rebaseContinue(): Promise<void> {
const args = ['rebase', '--continue'];
try {
await this.run(args);
await this.exec(args);
} catch (commitErr) {
await this.handleCommitError(commitErr);
}
@ -1402,14 +1401,14 @@ export class Repository {
}
try {
await this.run(['config', '--get-all', 'user.name']);
await this.exec(['config', '--get-all', 'user.name']);
} catch (err) {
err.gitErrorCode = GitErrorCodes.NoUserNameConfigured;
throw err;
}
try {
await this.run(['config', '--get-all', 'user.email']);
await this.exec(['config', '--get-all', 'user.email']);
} catch (err) {
err.gitErrorCode = GitErrorCodes.NoUserEmailConfigured;
throw err;
@ -1425,39 +1424,39 @@ export class Repository {
args.push(ref);
}
await this.run(args);
await this.exec(args);
}
async deleteBranch(name: string, force?: boolean): Promise<void> {
const args = ['branch', force ? '-D' : '-d', name];
await this.run(args);
await this.exec(args);
}
async renameBranch(name: string): Promise<void> {
const args = ['branch', '-m', name];
await this.run(args);
await this.exec(args);
}
async move(from: string, to: string): Promise<void> {
const args = ['mv', from, to];
await this.run(args);
await this.exec(args);
}
async setBranchUpstream(name: string, upstream: string): Promise<void> {
const args = ['branch', '--set-upstream-to', upstream, name];
await this.run(args);
await this.exec(args);
}
async deleteRef(ref: string): Promise<void> {
const args = ['update-ref', '-d', ref];
await this.run(args);
await this.exec(args);
}
async merge(ref: string): Promise<void> {
const args = ['merge', ref];
try {
await this.run(args);
await this.exec(args);
} catch (err) {
if (/^CONFLICT /m.test(err.stdout || '')) {
err.gitErrorCode = GitErrorCodes.Conflict;
@ -1476,12 +1475,12 @@ export class Repository {
args = [...args, name];
}
await this.run(args);
await this.exec(args);
}
async deleteTag(name: string): Promise<void> {
let args = ['tag', '-d', name];
await this.run(args);
await this.exec(args);
}
async clean(paths: string[]): Promise<void> {
@ -1494,7 +1493,7 @@ export class Repository {
for (const paths of groups) {
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
promises.push(limiter.queue(() => this.run([...args, '--', ...chunk])));
promises.push(limiter.queue(() => this.exec([...args, '--', ...chunk])));
}
}
@ -1502,10 +1501,10 @@ export class Repository {
}
async undo(): Promise<void> {
await this.run(['clean', '-fd']);
await this.exec(['clean', '-fd']);
try {
await this.run(['checkout', '--', '.']);
await this.exec(['checkout', '--', '.']);
} catch (err) {
if (/did not match any file\(s\) known to git\./.test(err.stderr || '')) {
return;
@ -1517,11 +1516,11 @@ export class Repository {
async reset(treeish: string, hard: boolean = false): Promise<void> {
const args = ['reset', hard ? '--hard' : '--soft', treeish];
await this.run(args);
await this.exec(args);
}
async revert(treeish: string, paths: string[]): Promise<void> {
const result = await this.run(['branch']);
const result = await this.exec(['branch']);
let args: string[];
// In case there are no branches, we must use rm --cached
@ -1534,10 +1533,10 @@ export class Repository {
try {
if (paths && paths.length > 0) {
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
await this.run([...args, '--', ...chunk]);
await this.exec([...args, '--', ...chunk]);
}
} else {
await this.run([...args, '--', '.']);
await this.exec([...args, '--', '.']);
}
} catch (err) {
// In case there are merge conflicts to be resolved, git reset will output
@ -1552,17 +1551,17 @@ export class Repository {
async addRemote(name: string, url: string): Promise<void> {
const args = ['remote', 'add', name, url];
await this.run(args);
await this.exec(args);
}
async removeRemote(name: string): Promise<void> {
const args = ['remote', 'remove', name];
await this.run(args);
await this.exec(args);
}
async renameRemote(name: string, newName: string): Promise<void> {
const args = ['remote', 'rename', name, newName];
await this.run(args);
await this.exec(args);
}
async fetch(options: { remote?: string, ref?: string, all?: boolean, prune?: boolean, depth?: number, silent?: boolean, readonly cancellationToken?: CancellationToken } = {}): Promise<void> {
@ -1595,7 +1594,7 @@ export class Repository {
}
try {
await this.run(args, spawnOptions);
await this.exec(args, spawnOptions);
} catch (err) {
if (/No remote repository specified\./.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoRemoteRepositorySpecified;
@ -1628,7 +1627,7 @@ export class Repository {
}
try {
await this.run(args, {
await this.exec(args, {
cancellationToken: options.cancellationToken,
env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent }
});
@ -1658,7 +1657,7 @@ export class Repository {
args.push(branch);
try {
await this.run(args, options);
await this.exec(args, options);
} catch (err) {
if (/^CONFLICT \([^)]+\): \b/m.test(err.stdout || '')) {
err.gitErrorCode = GitErrorCodes.Conflict;
@ -1700,7 +1699,7 @@ export class Repository {
}
try {
await this.run(args, { env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent } });
await this.exec(args, { env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent } });
} catch (err) {
if (/^error: failed to push some refs to\b/m.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.PushRejected;
@ -1718,13 +1717,13 @@ export class Repository {
async cherryPick(commitHash: string): Promise<void> {
const args = ['cherry-pick', commitHash];
await this.run(args);
await this.exec(args);
}
async blame(path: string): Promise<string> {
try {
const args = ['blame', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout.trim();
} catch (err) {
if (/^fatal: no such path/.test(err.stderr || '')) {
@ -1747,7 +1746,7 @@ export class Repository {
args.push('-m', message);
}
await this.run(args);
await this.exec(args);
} catch (err) {
if (/No local changes to save/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoLocalChanges;
@ -1773,7 +1772,7 @@ export class Repository {
args.push(`stash@{${index}}`);
}
await this.run(args);
await this.exec(args);
} catch (err) {
if (/No stash found/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoStashFound;
@ -1795,7 +1794,7 @@ export class Repository {
}
try {
await this.run(args);
await this.exec(args);
} catch (err) {
if (/No stash found/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoStashFound;
@ -1860,7 +1859,7 @@ export class Repository {
async getHEAD(): Promise<Ref> {
try {
const result = await this.run(['symbolic-ref', '--short', 'HEAD']);
const result = await this.exec(['symbolic-ref', '--short', 'HEAD']);
if (!result.stdout) {
throw new Error('Not in a branch');
@ -1868,7 +1867,7 @@ export class Repository {
return { name: result.stdout.trim(), commit: undefined, type: RefType.Head };
} catch (err) {
const result = await this.run(['rev-parse', 'HEAD']);
const result = await this.exec(['rev-parse', 'HEAD']);
if (!result.stdout) {
throw new Error('Error parsing HEAD');
@ -1879,7 +1878,7 @@ export class Repository {
}
async findTrackingBranches(upstreamBranch: string): Promise<Branch[]> {
const result = await this.run(['for-each-ref', '--format', '%(refname:short)%00%(upstream:short)', 'refs/heads']);
const result = await this.exec(['for-each-ref', '--format', '%(refname:short)%00%(upstream:short)', 'refs/heads']);
return result.stdout.trim().split('\n')
.map(line => line.trim().split('\0'))
.filter(([_, upstream]) => upstream === upstreamBranch)
@ -1907,7 +1906,7 @@ export class Repository {
args.push('--contains', opts.contains);
}
const result = await this.run(args);
const result = await this.exec(args);
const fn = (line: string): Ref | null => {
let match: RegExpExecArray | null;
@ -1930,7 +1929,7 @@ export class Repository {
}
async getStashes(): Promise<Stash[]> {
const result = await this.run(['stash', 'list']);
const result = await this.exec(['stash', 'list']);
const regex = /^stash@{(\d+)}:(.+)$/;
const rawStashes = result.stdout.trim().split('\n')
.filter(b => !!b)
@ -1942,7 +1941,7 @@ export class Repository {
}
async getRemotes(): Promise<Remote[]> {
const result = await this.run(['remote', '--verbose']);
const result = await this.exec(['remote', '--verbose']);
const lines = result.stdout.trim().split('\n').filter(l => !!l);
const remotes: MutableRemote[] = [];
@ -1985,7 +1984,7 @@ export class Repository {
args.push(`refs/heads/${name}`, `refs/remotes/${name}`);
}
const result = await this.run(args);
const result = await this.exec(args);
const branches: Branch[] = result.stdout.trim().split('\n').map<Branch | undefined>(line => {
let [branchName, upstream, status, ref] = line.trim().split('\0');
@ -2067,7 +2066,7 @@ export class Repository {
async getCommitTemplate(): Promise<string> {
try {
const result = await this.run(['config', '--get', 'commit.template']);
const result = await this.exec(['config', '--get', 'commit.template']);
if (!result.stdout) {
return '';
@ -2090,7 +2089,7 @@ export class Repository {
}
async getCommit(ref: string): Promise<Commit> {
const result = await this.run(['show', '-s', `--format=${COMMIT_FORMAT}`, '-z', ref]);
const result = await this.exec(['show', '-s', `--format=${COMMIT_FORMAT}`, '-z', ref]);
const commits = parseGitCommits(result.stdout);
if (commits.length === 0) {
return Promise.reject<Commit>('bad commit format');
@ -2102,7 +2101,7 @@ export class Repository {
const args = ['submodule', 'update'];
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
await this.run([...args, '--', ...chunk]);
await this.exec([...args, '--', ...chunk]);
}
}

View File

@ -73,12 +73,13 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
git.onOutput.addListener('log', onOutput);
disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput)));
const cc = new CommandCenter(git, model, outputChannel, telemetryReporter);
disposables.push(
new CommandCenter(git, model, outputChannel, telemetryReporter),
cc,
new GitFileSystemProvider(model),
new GitDecorations(model),
new GitProtocolHandler(),
new GitTimelineProvider(model)
new GitTimelineProvider(model, cc)
);
checkGitVersion(info);

View File

@ -55,13 +55,13 @@ export class Resource implements SourceControlResourceState {
case Status.UNTRACKED: return localize('untracked', "Untracked");
case Status.IGNORED: return localize('ignored', "Ignored");
case Status.INTENT_TO_ADD: return localize('intent to add', "Intent to Add");
case Status.BOTH_DELETED: return localize('both deleted', "Both Deleted");
case Status.ADDED_BY_US: return localize('added by us', "Added By Us");
case Status.DELETED_BY_THEM: return localize('deleted by them', "Deleted By Them");
case Status.ADDED_BY_THEM: return localize('added by them', "Added By Them");
case Status.DELETED_BY_US: return localize('deleted by us', "Deleted By Us");
case Status.BOTH_ADDED: return localize('both added', "Both Added");
case Status.BOTH_MODIFIED: return localize('both modified', "Both Modified");
case Status.BOTH_DELETED: return localize('both deleted', "Conflict: Both Deleted");
case Status.ADDED_BY_US: return localize('added by us', "Conflict: Added By Us");
case Status.DELETED_BY_THEM: return localize('deleted by them', "Conflict: Deleted By Them");
case Status.ADDED_BY_THEM: return localize('added by them', "Conflict: Added By Them");
case Status.DELETED_BY_US: return localize('deleted by us', "Conflict: Deleted By Us");
case Status.BOTH_ADDED: return localize('both added', "Conflict: Both Added");
case Status.BOTH_MODIFIED: return localize('both modified', "Conflict: Both Modified");
default: return '';
}
}
@ -199,12 +199,13 @@ export class Resource implements SourceControlResourceState {
case Status.DELETED_BY_US:
return 'D';
case Status.INDEX_COPIED:
return 'C';
case Status.BOTH_DELETED:
case Status.ADDED_BY_US:
case Status.ADDED_BY_THEM:
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return 'C';
return '!'; // Using ! instead of ⚠, because the latter looks really bad on windows
default:
throw new Error('Unknown git status: ' + this.type);
}
@ -223,12 +224,13 @@ export class Resource implements SourceControlResourceState {
case Status.INDEX_ADDED:
case Status.INTENT_TO_ADD:
return new ThemeColor('gitDecoration.addedResourceForeground');
case Status.INDEX_COPIED:
case Status.INDEX_RENAMED:
return new ThemeColor('gitDecoration.renamedResourceForeground');
case Status.UNTRACKED:
return new ThemeColor('gitDecoration.untrackedResourceForeground');
case Status.IGNORED:
return new ThemeColor('gitDecoration.ignoredResourceForeground');
case Status.INDEX_COPIED:
case Status.BOTH_DELETED:
case Status.ADDED_BY_US:
case Status.DELETED_BY_THEM:
@ -246,10 +248,10 @@ export class Resource implements SourceControlResourceState {
switch (this.type) {
case Status.INDEX_MODIFIED:
case Status.MODIFIED:
case Status.INDEX_COPIED:
return 2;
case Status.IGNORED:
return 3;
case Status.INDEX_COPIED:
case Status.BOTH_DELETED:
case Status.ADDED_BY_US:
case Status.DELETED_BY_THEM:
@ -1482,7 +1484,7 @@ export class Repository implements Disposable {
const maybeRebased = await this.run(Operation.Log, async () => {
try {
const result = await this.repository.run(['log', '--oneline', '--cherry', `${currentBranch ?? ''}...${currentBranch ?? ''}@{upstream}`, '--']);
const result = await this.repository.exec(['log', '--oneline', '--cherry', `${currentBranch ?? ''}...${currentBranch ?? ''}@{upstream}`, '--']);
if (result.exitCode) {
return false;
}

View File

@ -9,6 +9,7 @@ import { Model } from './model';
import { Repository, Resource } from './repository';
import { debounce } from './decorators';
import { emojify, ensureEmojis } from './emoji';
import { CommandCenter } from './commands';
const localize = nls.loadMessageBundle();
@ -73,7 +74,7 @@ export class GitTimelineProvider implements TimelineProvider {
private repoDisposable: Disposable | undefined;
private repoStatusDate: Date | undefined;
constructor(private readonly model: Model) {
constructor(private readonly model: Model, private commands: CommandCenter) {
this.disposable = Disposable.from(
model.onDidOpenRepository(this.onRepositoriesChanged, this),
workspace.onDidChangeConfiguration(this.onConfigurationChanged, this)
@ -161,16 +162,20 @@ export class GitTimelineProvider implements TimelineProvider {
const message = emojify(c.message);
const item = new GitTimelineItem(c.hash, commits[i + 1]?.hash ?? `${c.hash}^`, message, date?.getTime() ?? 0, c.hash, 'git:file:commit');
item.iconPath = new (ThemeIcon as any)('git-commit');
item.iconPath = new ThemeIcon('git-commit');
if (showAuthor) {
item.description = c.authorName;
}
item.detail = `${c.authorName} (${c.authorEmail}) — ${c.hash.substr(0, 8)}\n${dateFormatter.format(date)}\n\n${message}`;
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',
arguments: [item, uri, this.id]
};
const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri);
if (cmd) {
item.command = {
title: 'Open Comparison',
command: cmd.command,
arguments: cmd.arguments,
};
}
return item;
});
@ -184,14 +189,18 @@ export class GitTimelineProvider implements TimelineProvider {
const item = new GitTimelineItem('~', 'HEAD', localize('git.timeline.stagedChanges', 'Staged Changes'), date.getTime(), 'index', 'git:file:index');
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new (ThemeIcon as any)('git-commit');
item.iconPath = new ThemeIcon('git-commit');
item.description = '';
item.detail = localize('git.timeline.detail', '{0} — {1}\n{2}\n\n{3}', you, localize('git.index', 'Index'), dateFormatter.format(date), Resource.getStatusText(index.type));
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',
arguments: [item, uri, this.id]
};
const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri);
if (cmd) {
item.command = {
title: 'Open Comparison',
command: cmd.command,
arguments: cmd.arguments,
};
}
items.splice(0, 0, item);
}
@ -202,14 +211,18 @@ export class GitTimelineProvider implements TimelineProvider {
const item = new GitTimelineItem('', index ? '~' : 'HEAD', localize('git.timeline.uncommitedChanges', 'Uncommitted Changes'), date.getTime(), 'working', 'git:file:working');
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new (ThemeIcon as any)('git-commit');
item.iconPath = new ThemeIcon('git-commit');
item.description = '';
item.detail = localize('git.timeline.detail', '{0} — {1}\n{2}\n\n{3}', you, localize('git.workingTree', 'Working Tree'), dateFormatter.format(date), Resource.getStatusText(working.type));
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',
arguments: [item, uri, this.id]
};
const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri);
if (cmd) {
item.command = {
title: 'Open Comparison',
command: cmd.command,
arguments: cmd.arguments,
};
}
items.splice(0, 0, item);
}