提交 74349805 编写于 作者: V Vakhurin Sergey

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.
上级 7300527f
......@@ -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({
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册