Git - fix encoding issue with stage selected ranges (#236484)

pull/236598/head^2
Ladislau Szomoru 2024-12-19 15:46:46 +01:00 committed by GitHub
parent 4051adf0a8
commit 25b88b7e4a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 3 deletions

View File

@ -1657,9 +1657,9 @@ export class Repository {
await this.exec(args);
}
async stage(path: string, data: string): Promise<void> {
async stage(path: string, data: string, encoding: string): Promise<void> {
const child = this.stream(['hash-object', '--stdin', '-w', '--path', sanitizePath(path)], { stdio: [null, null, null] });
child.stdin!.end(data, 'utf8');
child.stdin!.end(iconv.encode(data, encoding));
const { exitCode, stdout } = await exec(child);
const hash = stdout.toString('utf8');

View File

@ -7,6 +7,7 @@ import TelemetryReporter from '@vscode/extension-telemetry';
import * as fs from 'fs';
import * as path from 'path';
import picomatch from 'picomatch';
import * as iconv from '@vscode/iconv-lite-umd';
import { CancellationError, CancellationToken, CancellationTokenSource, Command, commands, Disposable, Event, EventEmitter, FileDecoration, l10n, LogLevel, LogOutputChannel, Memento, ProgressLocation, ProgressOptions, QuickDiffProvider, RelativePattern, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, TabInputNotebookDiff, TabInputTextDiff, TabInputTextMultiDiff, ThemeColor, Uri, window, workspace, WorkspaceEdit } from 'vscode';
import { ActionButton } from './actionButton';
import { ApiRepository } from './api/api1';
@ -24,6 +25,7 @@ import { StatusBarCommands } from './statusbar';
import { toGitUri } from './uri';
import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, onceEvent, pathEquals, relativePath } from './util';
import { IFileWatcher, watch } from './watch';
import { detectEncoding } from './encoding';
const timeout = (millis: number) => new Promise(c => setTimeout(c, millis));
@ -1215,7 +1217,17 @@ export class Repository implements Disposable {
async stage(resource: Uri, contents: string): Promise<void> {
const path = relativePath(this.repository.root, resource.fsPath).replace(/\\/g, '/');
await this.run(Operation.Stage, async () => {
await this.repository.stage(path, contents);
const configFiles = workspace.getConfiguration('files', Uri.file(resource.fsPath));
let encoding = configFiles.get<string>('encoding') ?? 'utf8';
const autoGuessEncoding = configFiles.get<boolean>('autoGuessEncoding') === true;
const candidateGuessEncodings = configFiles.get<string[]>('candidateGuessEncodings') ?? [];
if (autoGuessEncoding) {
encoding = detectEncoding(Buffer.from(contents), candidateGuessEncodings) ?? encoding;
}
encoding = iconv.encodingExists(encoding) ? encoding : 'utf8';
await this.repository.stage(path, contents, encoding);
this._onDidChangeOriginalResource.fire(resource);
this.closeDiffEditors([], [...resource.fsPath]);