Skip to content

Commit 8c86d3a

Browse files
committed
fix: correct hunk headers when updating files in a patch
1 parent b5eba13 commit 8c86d3a

File tree

2 files changed

+60
-15
lines changed

2 files changed

+60
-15
lines changed

src/fileSystemProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,11 @@ export class ElectronPatchFileSystemProvider extends ElectronFileSystemProvider
149149
if (vscode.Uri.joinPath(cwd, filename).fsPath === uri.fsPath) {
150150
// Get the diff between the original blob (before the original patch)
151151
// and the new blob content so that we have the new patch content
152-
fileDiff = await gitDiffBlobs(cwd, blobIdA, newBlobId);
152+
fileDiff = await gitDiffBlobs(cwd, filename, blobIdA, newBlobId);
153153
fileDiff = fileDiff.replaceAll(`a/${blobIdA}`, `a/${filename}`);
154154
fileDiff = fileDiff.replaceAll(`b/${newBlobId}`, `b/${filename}`);
155155
} else {
156-
fileDiff = await gitDiffBlobs(cwd, blobIdA, blobIdB);
156+
fileDiff = await gitDiffBlobs(cwd, filename, blobIdA, blobIdB);
157157
fileDiff = fileDiff.replaceAll(`a/${blobIdA}`, `a/${filename}`);
158158
fileDiff = fileDiff.replaceAll(`b/${blobIdB}`, `b/${filename}`);
159159
}

src/utils.ts

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as childProcess from "node:child_process";
2+
import * as fs from "node:fs/promises";
23
import * as os from "node:os";
34
import * as path from "node:path";
45
import { promisify } from "node:util";
@@ -845,8 +846,59 @@ export async function gitHashObject(cwd: vscode.Uri, content: string) {
845846
return (await stdoutPromise).trim();
846847
}
847848

849+
async function gitDiffBlobsInternal(
850+
cwd: vscode.Uri,
851+
filename: string,
852+
blobIdA: string,
853+
blobIdB: string,
854+
) {
855+
const ext = path.extname(filename);
856+
const tmpDir = await fs.mkdtemp(
857+
path.join(os.tmpdir(), "electron-build-tools-"),
858+
);
859+
const tmpFileA = path.join(tmpDir, `${blobIdA}${ext}`);
860+
const tmpFileB = path.join(tmpDir, `${blobIdB}${ext}`);
861+
862+
let stdout: string;
863+
864+
const [contentA, contentB] = await Promise.all([
865+
getContentForBlobId(blobIdA, cwd),
866+
getContentForBlobId(blobIdB, cwd),
867+
]);
868+
869+
await Promise.all([
870+
fs.writeFile(tmpFileA, contentA),
871+
fs.writeFile(tmpFileB, contentB),
872+
]);
873+
874+
try {
875+
({ stdout } = await exec(
876+
`git diff --full-index --no-index ${tmpFileA} ${tmpFileB}`,
877+
{ encoding: "utf8", cwd: cwd.fsPath },
878+
));
879+
} catch (err) {
880+
// git diff --no-index exits with code 1 when files differ
881+
if (
882+
err instanceof Error &&
883+
Object.prototype.hasOwnProperty.call(err, "code") &&
884+
(err as PromisifiedExecError).code === 1
885+
) {
886+
stdout = (err as PromisifiedExecError).stdout;
887+
} else {
888+
throw err;
889+
}
890+
} finally {
891+
await fs.rm(tmpDir, { recursive: true, force: true }).catch(() => {});
892+
}
893+
894+
return stdout
895+
.replaceAll(`a${tmpFileA}`, `a/${blobIdA}`)
896+
.replaceAll(`b${tmpFileB}`, `b/${blobIdB}`);
897+
}
898+
848899
export async function gitDiffBlobs(
849900
cwd: vscode.Uri,
901+
filename: string,
850902
blobIdA: string,
851903
blobIdB: string,
852904
) {
@@ -862,12 +914,11 @@ export async function gitDiffBlobs(
862914
if (/^[0]+$/.test(blobIdA)) {
863915
// Git doesn't like the all-zero blob ID, so use the empty blob SHA instead
864916
// The empty blob SHA is the SHA of an empty file (e.g., /dev/null)
865-
let { stdout: fileDiff } = await exec(
866-
`git diff --full-index ${EMPTY_BLOB_SHA}..${blobIdB}`,
867-
{
868-
encoding: "utf8",
869-
cwd: cwd.fsPath,
870-
},
917+
let fileDiff = await gitDiffBlobsInternal(
918+
cwd,
919+
filename,
920+
EMPTY_BLOB_SHA,
921+
blobIdB,
871922
);
872923

873924
// Restore the original all zero blob ID in the diff output
@@ -885,13 +936,7 @@ export async function gitDiffBlobs(
885936
return fileDiff;
886937
}
887938

888-
const { stdout } = await exec(
889-
`git diff --full-index ${blobIdA}..${blobIdB}`,
890-
{
891-
encoding: "utf8",
892-
cwd: cwd.fsPath,
893-
},
894-
);
939+
const stdout = await gitDiffBlobsInternal(cwd, filename, blobIdA, blobIdB);
895940

896941
return stdout;
897942
}

0 commit comments

Comments
 (0)