mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-29 22:43:19 -05:00
Added support for encodings for Git.
Fixes #21146 **Bug** Git always uses utf8 encoding for retrieving file contents. **Fix** Pass the 'files.encoding' configuration property to the git-extension and use this encoding to decode git output.
This commit is contained in:
5
extensions/git/npm-shrinkwrap.json
generated
5
extensions/git/npm-shrinkwrap.json
generated
@@ -7,6 +7,11 @@
|
||||
"from": "applicationinsights@0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.15",
|
||||
"from": "iconv-lite@0.4.15",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz"
|
||||
},
|
||||
"vscode-extension-telemetry": {
|
||||
"version": "0.0.6",
|
||||
"from": "vscode-extension-telemetry@>=0.0.6 <0.0.7",
|
||||
|
||||
@@ -623,6 +623,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"iconv-lite": "0.4.15",
|
||||
"vscode-extension-telemetry": "^0.0.6",
|
||||
"vscode-nls": "^2.0.1"
|
||||
},
|
||||
|
||||
@@ -9,6 +9,7 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as cp from 'child_process';
|
||||
import iconv = require('iconv-lite');
|
||||
import { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp } from './util';
|
||||
import { EventEmitter, Event } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
@@ -159,7 +160,7 @@ export interface IExecutionResult {
|
||||
stderr: string;
|
||||
}
|
||||
|
||||
export async function exec(child: cp.ChildProcess): Promise<IExecutionResult> {
|
||||
export async function exec(child: cp.ChildProcess, encoding: string = 'utf8'): Promise<IExecutionResult> {
|
||||
const disposables: IDisposable[] = [];
|
||||
|
||||
const once = (ee: NodeJS.EventEmitter, name: string, fn: Function) => {
|
||||
@@ -178,14 +179,14 @@ export async function exec(child: cp.ChildProcess): Promise<IExecutionResult> {
|
||||
once(child, 'exit', c);
|
||||
}),
|
||||
new Promise<string>(c => {
|
||||
const buffers: string[] = [];
|
||||
const buffers: Buffer[] = [];
|
||||
on(child.stdout, 'data', b => buffers.push(b));
|
||||
once(child.stdout, 'close', () => c(buffers.join('')));
|
||||
once(child.stdout, 'close', () => c(decode(Buffer.concat(buffers), encoding)));
|
||||
}),
|
||||
new Promise<string>(c => {
|
||||
const buffers: string[] = [];
|
||||
const buffers: Buffer[] = [];
|
||||
on(child.stderr, 'data', b => buffers.push(b));
|
||||
once(child.stderr, 'close', () => c(buffers.join('')));
|
||||
once(child.stderr, 'close', () => c(decode(Buffer.concat(buffers), encoding)));
|
||||
})
|
||||
]);
|
||||
|
||||
@@ -194,6 +195,10 @@ export async function exec(child: cp.ChildProcess): Promise<IExecutionResult> {
|
||||
return { exitCode, stdout, stderr };
|
||||
}
|
||||
|
||||
function decode(buffer: NodeBuffer, encoding: string): string {
|
||||
return iconv.decode(buffer, encoding);
|
||||
}
|
||||
|
||||
export interface IGitErrorData {
|
||||
error?: Error;
|
||||
message?: string;
|
||||
@@ -329,7 +334,7 @@ export class Git {
|
||||
child.stdin.end(options.input, 'utf8');
|
||||
}
|
||||
|
||||
const result = await exec(child);
|
||||
const result = await exec(child, options.encoding);
|
||||
|
||||
if (result.exitCode) {
|
||||
let gitErrorCode: string | undefined = void 0;
|
||||
|
||||
@@ -28,6 +28,7 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi
|
||||
const outputChannel = window.createOutputChannel('Git');
|
||||
disposables.push(outputChannel);
|
||||
|
||||
const configFiles = workspace.getConfiguration('files');
|
||||
const config = workspace.getConfiguration('git');
|
||||
const enabled = config.get<boolean>('enabled') === true;
|
||||
const workspaceRootPath = workspace.rootPath;
|
||||
@@ -44,7 +45,7 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi
|
||||
return;
|
||||
}
|
||||
|
||||
const model = new Model(git, workspaceRootPath);
|
||||
const model = new Model(git, workspaceRootPath, configFiles.get<string>('encoding'));
|
||||
|
||||
outputChannel.appendLine(localize('using git', "Using git {0} from {1}", info.version, info.path));
|
||||
git.onOutput(str => outputChannel.append(str), null, disposables);
|
||||
|
||||
@@ -356,7 +356,8 @@ export class Model implements Disposable {
|
||||
|
||||
constructor(
|
||||
private _git: Git,
|
||||
private workspaceRootPath: string
|
||||
private workspaceRootPath: string,
|
||||
private encoding?: string
|
||||
) {
|
||||
const fsWatcher = workspace.createFileSystemWatcher('**');
|
||||
this.onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete);
|
||||
@@ -480,7 +481,9 @@ export class Model implements Disposable {
|
||||
async show(ref: string, filePath: string): Promise<string> {
|
||||
return await this.run(Operation.Show, async () => {
|
||||
const relativePath = path.relative(this.repository.root, filePath).replace(/\\/g, '/');
|
||||
const result = await this.repository.git.exec(this.repository.root, ['show', `${ref}:${relativePath}`]);
|
||||
const result = await this.repository.git.exec(this.repository.root, ['show', `${ref}:${relativePath}`], {
|
||||
encoding: this.encoding
|
||||
});
|
||||
|
||||
if (result.exitCode !== 0) {
|
||||
throw new GitError({
|
||||
|
||||
Reference in New Issue
Block a user