Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Sort Order Option setting to address #27759 #96214

Closed
wants to merge 62 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
4ffc5c6
Add Sort Order Option setting to address #27759
leilapearson Apr 27, 2020
928beec
Remove extra exports
leilapearson Apr 27, 2020
7e7ef75
Show args in default keybindings
Tyriar Apr 22, 2020
c5344ab
Prevent unexpected rename cancellation
ChrisPapp Apr 21, 2020
5bb2e2c
Use the cancellation token to trigger rename cancellation
ChrisPapp Apr 23, 2020
31a4db7
Make range in EditorStateCancellationTokenSource readonly
ChrisPapp Apr 23, 2020
bba5100
Fix #96009
jeanp413 Apr 26, 2020
96d11ef
Use DisposableStore
roblourens Apr 27, 2020
a7d6660
Add markdownDeprecationMessage
roblourens Apr 27, 2020
3ee8091
editor - properly resolve iconTheme editor option
bpasero Apr 27, 2020
2bfca5e
:lipstick: editor group perf
bpasero Apr 27, 2020
eadd056
:lipstick: redundant code
bpasero Apr 27, 2020
e55627c
:up: playwright@0.15.0 (#96218)
bpasero Apr 27, 2020
758e12b
Add editorOverviewRuler.background colour customisation point
robertrossmann Mar 30, 2020
73924a7
change all instances of `wordHighligher` to `wordHighlighter`
dustypomerleau Apr 22, 2020
074c0aa
fix https://github.com/microsoft/vscode/issues/96013
jrieken Apr 27, 2020
99d45f3
Fixes #95936: Improve width sizing for tokens inspector widget
alexdima Apr 27, 2020
ee41248
Fix error when invoking `explorer.newFile` while explorer viewlet is …
isidorn Apr 27, 2020
fd636e7
add format notebook command, #96239
jrieken Apr 27, 2020
394bf07
use precondition, #96239
jrieken Apr 27, 2020
42daa7b
localize strings, use category property. fyi @rebornix
jrieken Apr 27, 2020
17787b1
explorer: If there is something being edited via input box make sure …
isidorn Apr 27, 2020
72adb5a
notebook - more (and shared) category label, more nls
jrieken Apr 27, 2020
65b513c
Fix #95143
sandy081 Apr 27, 2020
0edd1d6
add log to askpass ipc
joaomoreno Apr 24, 2020
e5cfb03
git extension api: registerCredentialsProvider
joaomoreno Apr 24, 2020
120daea
wip: use registerCredentialsProvider in github-authentication extension
joaomoreno Apr 24, 2020
fedea4b
move github credential provider to git
joaomoreno Apr 27, 2020
21cec0d
Use a max length since we are inserting the whole msg in the DOM and …
isidorn Apr 27, 2020
bb229f1
Fixes #93370: Add ContinueBracketSearchPredicate and invoke it every …
alexdima Apr 27, 2020
0e6f4de
tune status bar accessibility
isidorn Apr 27, 2020
e8b7a0e
Fixes #95591
alexdima Apr 27, 2020
5adf0c7
Allow Quick Open (Ctrl-P) to Prioritize Exact Case Matches (fix #96122)
bpasero Apr 27, 2020
2ee4fb6
Fixes #94144: Remove special dark theme cursor
alexdima Apr 27, 2020
c1d6136
Fix #93904
sandy081 Apr 27, 2020
d8c838c
fix #96225
bpasero Apr 27, 2020
a90a98a
Show title area when there are buttons (fixes #95703)
chrmarti Apr 27, 2020
3d52ea3
fix #95095
sandy081 Apr 27, 2020
0d9bf4f
add TableOfContentsProvider for none text editors, #95234
jrieken Apr 27, 2020
1b756b0
Show warnings when task types don't match
alexr00 Apr 27, 2020
28b3703
#96064 do not show view focus command when not active
sandy081 Apr 27, 2020
e1bc348
Update do for location based API commands.
dbaeumer Apr 27, 2020
9af31c2
progress - preserve 150ms default delay for window progress (#95615)
bpasero Apr 27, 2020
2306c34
:lipstick:
jrieken Apr 27, 2020
2c77e38
git: use environmentVariableCollection
joaomoreno Apr 27, 2020
335b1b0
git: config.terminalAuthentication
joaomoreno Apr 27, 2020
d64f1d2
git: config.githubAuthentication
joaomoreno Apr 27, 2020
a3809d3
:lipstick:
joaomoreno Apr 27, 2020
8677d6c
fix button codicon colors
joaomoreno Apr 27, 2020
0a7b38a
Fix spacing after when
Tyriar Apr 27, 2020
c18e86b
CallStack: We need the MenuEntryActionViewItem so the icon would get …
isidorn Apr 27, 2020
c2cda6e
#96064 Fix model and view
sandy081 Apr 27, 2020
58e36a5
do not throw error and continue
sandy081 Apr 27, 2020
158cfc7
Update vscode.d.ts
badsyntax Apr 26, 2020
f3d8e31
Throttle status bar spinner animations to save CPU
evangrayk Apr 24, 2020
3662f2b
Treat `.gitignore_global` as an Ignore file by default. Fixes #96079.
johnbillion Apr 24, 2020
7754ccc
rename "Trigger" to "TriggerKind"; see #88230
weinand Apr 27, 2020
47bb655
Disable tasks tests in web
Tyriar Apr 27, 2020
058bb93
fixes #95940
joaomoreno Apr 27, 2020
2025795
Add ref to why test is disabled
Tyriar Apr 27, 2020
550fc69
fix #96256
bpasero Apr 27, 2020
e471148
restore compareFiles and compareFileExtensions
leilapearson Apr 27, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions extensions/git/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1665,6 +1665,18 @@
"scope": "resource",
"default": true,
"description": "%config.showCommitInput%"
},
"git.terminalAuthentication": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%config.terminalAuthentication%"
},
"git.githubAuthentication": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%config.githubAuthentication%"
}
}
},
Expand Down Expand Up @@ -1777,6 +1789,7 @@
"ignore"
],
"filenames": [
".gitignore_global",
".gitignore"
],
"configuration": "./languages/ignore.language-configuration.json"
Expand Down
2 changes: 2 additions & 0 deletions extensions/git/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@
"config.untrackedChanges.separate": "Untracked changes appear separately in the Source Control view. They are also excluded from several actions.",
"config.untrackedChanges.hidden": "Untracked changes are hidden and excluded from several actions.",
"config.showCommitInput": "Controls whether to show the commit input in the Git source control panel.",
"config.terminalAuthentication": "Controls whether to enable VS Code to be the authentication handler for git processes spawned in the integrated terminal.",
"config.githubAuthentication": "Controls whether to enable automatic GitHub authentication for git commands within VS Code.",
"colors.added": "Color for added resources.",
"colors.modified": "Color for modified resources.",
"colors.deleted": "Color for deleted resources.",
Expand Down
6 changes: 5 additions & 1 deletion extensions/git/src/api/api1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { Model } from '../model';
import { Repository as BaseRepository, Resource } from '../repository';
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, GitExtension, RefType, RemoteSourceProvider } from './git';
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, GitExtension, RefType, RemoteSourceProvider, CredentialsProvider } from './git';
import { Event, SourceControlInputBox, Uri, SourceControl, Disposable, commands } from 'vscode';
import { mapEvent } from '../util';
import { toGitUri } from '../uri';
Expand Down Expand Up @@ -263,6 +263,10 @@ export class ApiImpl implements API {
return this._model.registerRemoteSourceProvider(provider);
}

registerCredentialsProvider(provider: CredentialsProvider): Disposable {
return this._model.registerCredentialsProvider(provider);
}

constructor(private _model: Model) { }
}

Expand Down
11 changes: 11 additions & 0 deletions extensions/git/src/api/git.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ export interface RemoteSourceProvider {
getRemoteSources(query?: string): ProviderResult<RemoteSource[]>;
}

export interface Credentials {
readonly username: string;
readonly password: string;
}

export interface CredentialsProvider {
getCredentials(host: Uri): ProviderResult<Credentials>;
}

export type APIState = 'uninitialized' | 'initialized';

export interface API {
Expand All @@ -217,7 +226,9 @@ export interface API {
toGitUri(uri: Uri, ref: string): Uri;
getRepository(uri: Uri): Repository | null;
init(root: Uri): Promise<Repository | null>;

registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable;
registerCredentialsProvider(provider: CredentialsProvider): Disposable;
}

export interface GitExtension {
Expand Down
4 changes: 2 additions & 2 deletions extensions/git/src/askpass.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh
VSCODE_GIT_ASKPASS_PIPE=`mktemp`
VSCODE_GIT_ASKPASS_PIPE="$VSCODE_GIT_ASKPASS_PIPE" "$VSCODE_GIT_ASKPASS_NODE" "$VSCODE_GIT_ASKPASS_MAIN" $*
ELECTRON_RUN_AS_NODE="1" VSCODE_GIT_ASKPASS_PIPE="$VSCODE_GIT_ASKPASS_PIPE" "$VSCODE_GIT_ASKPASS_NODE" "$VSCODE_GIT_ASKPASS_MAIN" $*
cat $VSCODE_GIT_ASKPASS_PIPE
rm $VSCODE_GIT_ASKPASS_PIPE
rm $VSCODE_GIT_ASKPASS_PIPE
77 changes: 56 additions & 21 deletions extensions/git/src/askpass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,60 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { window, InputBoxOptions } from 'vscode';
import { IDisposable } from './util';
import { window, InputBoxOptions, Uri, OutputChannel, Disposable } from 'vscode';
import { IDisposable, EmptyDisposable, toDisposable } from './util';
import * as path from 'path';
import { IIPCHandler, IIPCServer } from './ipc/ipcServer';

export interface AskpassEnvironment {
GIT_ASKPASS: string;
ELECTRON_RUN_AS_NODE?: string;
VSCODE_GIT_ASKPASS_NODE?: string;
VSCODE_GIT_ASKPASS_MAIN?: string;
VSCODE_GIT_ASKPASS_HANDLE?: string;
}
import { IIPCHandler, IIPCServer, createIPCServer } from './ipc/ipcServer';
import { CredentialsProvider, Credentials } from './api/git';

export class Askpass implements IIPCHandler {

private disposable: IDisposable;
private disposable: IDisposable = EmptyDisposable;
private cache = new Map<string, Credentials>();
private credentialsProviders = new Set<CredentialsProvider>();

static getDisabledEnv(): AskpassEnvironment {
return {
GIT_ASKPASS: path.join(__dirname, 'askpass-empty.sh')
};
static async create(outputChannel: OutputChannel, context?: string): Promise<Askpass> {
try {
return new Askpass(await createIPCServer(context));
} catch (err) {
outputChannel.appendLine(`[error] Failed to create git askpass IPC: ${err}`);
return new Askpass();
}
}

constructor(ipc: IIPCServer) {
this.disposable = ipc.registerHandler('askpass', this);
private constructor(private ipc?: IIPCServer) {
if (ipc) {
this.disposable = ipc.registerHandler('askpass', this);
}
}

async handle({ request, host }: { request: string, host: string }): Promise<string> {
const uri = Uri.parse(host);
const authority = uri.authority.replace(/^.*@/, '');
const password = /password/i.test(request);
const cached = this.cache.get(authority);

if (cached && password) {
this.cache.delete(authority);
return cached.password;
}

if (!password) {
for (const credentialsProvider of this.credentialsProviders) {
try {
const credentials = await credentialsProvider.getCredentials(uri);

if (credentials) {
this.cache.set(authority, credentials);
setTimeout(() => this.cache.delete(authority), 60_000);
return credentials.username;
}
} catch { }
}
}

const options: InputBoxOptions = {
password: /password/i.test(request),
password,
placeHolder: request,
prompt: `Git: ${host}`,
ignoreFocusOut: true
Expand All @@ -41,15 +65,26 @@ export class Askpass implements IIPCHandler {
return await window.showInputBox(options) || '';
}

getEnv(): AskpassEnvironment {
getEnv(): { [key: string]: string; } {
if (!this.ipc) {
return {
GIT_ASKPASS: path.join(__dirname, 'askpass-empty.sh')
};
}

return {
ELECTRON_RUN_AS_NODE: '1',
...this.ipc.getEnv(),
GIT_ASKPASS: path.join(__dirname, 'askpass.sh'),
VSCODE_GIT_ASKPASS_NODE: process.execPath,
VSCODE_GIT_ASKPASS_MAIN: path.join(__dirname, 'askpass-main.js')
};
}

registerCredentialsProvider(provider: CredentialsProvider): Disposable {
this.credentialsProviders.add(provider);
return toDisposable(() => this.credentialsProviders.delete(provider));
}

dispose(): void {
this.disposable.dispose();
}
Expand Down
8 changes: 8 additions & 0 deletions extensions/git/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2560,6 +2560,14 @@ export class CommandCenter {
type = 'warning';
options.modal = false;
break;
case GitErrorCodes.AuthenticationFailed:
const regex = /Authentication failed for '(.*)'/i;
const match = regex.exec(err.stderr || String(err));

message = match
? localize('auth failed specific', "Failed to authenticate to git remote:\n\n{0}", match[1])
: localize('auth failed', "Failed to authenticate to git remote.");
break;
case GitErrorCodes.NoUserNameConfigured:
case GitErrorCodes.NoUserEmailConfigured:
message = localize('missing user info', "Make sure you configure your 'user.name' and 'user.email' in git.");
Expand Down
2 changes: 1 addition & 1 deletion extensions/git/src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ export interface IGitOptions {
function getGitErrorCode(stderr: string): string | undefined {
if (/Another git process seems to be running in this repository|If no other git process is currently running/.test(stderr)) {
return GitErrorCodes.RepositoryIsLocked;
} else if (/Authentication failed/.test(stderr)) {
} else if (/Authentication failed/i.test(stderr)) {
return GitErrorCodes.AuthenticationFailed;
} else if (/Not a git repository/i.test(stderr)) {
return GitErrorCodes.NotAGitRepository;
Expand Down
66 changes: 66 additions & 0 deletions extensions/git/src/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { CredentialsProvider, Credentials } from './api/git';
import { IDisposable, filterEvent, EmptyDisposable } from './util';
import { workspace, Uri, AuthenticationSession, authentication } from 'vscode';
import { Askpass } from './askpass';

export class GitHubCredentialProvider implements CredentialsProvider {

async getCredentials(host: Uri): Promise<Credentials | undefined> {
if (!/github\.com/i.test(host.authority)) {
return;
}

const session = await this.getSession();
return { username: session.account.id, password: await session.getAccessToken() };
}

private async getSession(): Promise<AuthenticationSession> {
const authenticationSessions = await authentication.getSessions('github', ['repo']);

if (authenticationSessions.length) {
return await authenticationSessions[0];
} else {
return await authentication.login('github', ['repo']);
}
}
}

export class GithubCredentialProviderManager {

private providerDisposable: IDisposable = EmptyDisposable;
private readonly disposable: IDisposable;

private _enabled = false;
private set enabled(enabled: boolean) {
if (this._enabled === enabled) {
return;
}

this._enabled = enabled;

if (enabled) {
this.providerDisposable = this.askpass.registerCredentialsProvider(new GitHubCredentialProvider());
} else {
this.providerDisposable.dispose();
}
}

constructor(private readonly askpass: Askpass) {
this.disposable = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git'))(this.refresh, this);
this.refresh();
}

private refresh(): void {
this.enabled = workspace.getConfiguration('git', null).get('githubAuthentication', true);
}

dispose(): void {
this.enabled = false;
this.disposable.dispose();
}
}
35 changes: 25 additions & 10 deletions extensions/git/src/ipc/ipcServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,42 @@ import * as os from 'os';
import * as fs from 'fs';
import * as crypto from 'crypto';

function getIPCHandlePath(nonce: string): string {
function getIPCHandlePath(id: string): string {
if (process.platform === 'win32') {
return `\\\\.\\pipe\\vscode-git-ipc-${nonce}-sock`;
return `\\\\.\\pipe\\vscode-git-${id}-sock`;
}

if (process.env['XDG_RUNTIME_DIR']) {
return path.join(process.env['XDG_RUNTIME_DIR'] as string, `vscode-git-ipc-${nonce}.sock`);
return path.join(process.env['XDG_RUNTIME_DIR'] as string, `vscode-git-${id}.sock`);
}

return path.join(os.tmpdir(), `vscode-git-ipc-${nonce}.sock`);
return path.join(os.tmpdir(), `vscode-git-${id}.sock`);
}

export interface IIPCHandler {
handle(request: any): Promise<any>;
}

export async function createIPCServer(): Promise<IIPCServer> {
export async function createIPCServer(context?: string): Promise<IIPCServer> {
const server = http.createServer();
const buffer = await new Promise<Buffer>((c, e) => crypto.randomBytes(20, (err, buf) => err ? e(err) : c(buf)));
const nonce = buffer.toString('hex');
const ipcHandlePath = getIPCHandlePath(nonce);
const hash = crypto.createHash('sha1');

if (!context) {
const buffer = await new Promise<Buffer>((c, e) => crypto.randomBytes(20, (err, buf) => err ? e(err) : c(buf)));
hash.update(buffer);
} else {
hash.update(context);
}

const ipcHandlePath = getIPCHandlePath(hash.digest('hex').substr(0, 10));

if (process.platform !== 'win32') {
try {
await fs.promises.unlink(ipcHandlePath);
} catch {
// noop
}
}

return new Promise((c, e) => {
try {
Expand All @@ -46,7 +61,7 @@ export async function createIPCServer(): Promise<IIPCServer> {

export interface IIPCServer extends Disposable {
readonly ipcHandlePath: string | undefined;
getEnv(): any;
getEnv(): { [key: string]: string; };
registerHandler(name: string, handler: IIPCHandler): Disposable;
}

Expand Down Expand Up @@ -91,7 +106,7 @@ class IPCServer implements IIPCServer, Disposable {
});
}

getEnv(): any {
getEnv(): { [key: string]: string; } {
return { VSCODE_GIT_IPC_HANDLE: this.ipcHandlePath };
}

Expand Down
Loading