Polish diff file actions
This commit is contained in:
@@ -2561,11 +2561,49 @@ const HUNK_ACTION_FLAGS = {
|
||||
discard: ['--reverse'],
|
||||
};
|
||||
|
||||
const parsePatchPathToken = (line) => {
|
||||
const value = String(line || '').replace(/^(?:-{3}|\+{3})\s+/, '');
|
||||
if (!value || value === '/dev/null') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value.startsWith('"')) {
|
||||
let token = '"';
|
||||
let escaped = false;
|
||||
for (let index = 1; index < value.length; index += 1) {
|
||||
const char = value[index];
|
||||
token += char;
|
||||
if (escaped) {
|
||||
escaped = false;
|
||||
} else if (char === '\\') {
|
||||
escaped = true;
|
||||
} else if (char === '"') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(token);
|
||||
} catch {
|
||||
return token.slice(1, token.endsWith('"') ? -1 : undefined);
|
||||
}
|
||||
}
|
||||
|
||||
return value.split('\t', 1)[0] || null;
|
||||
};
|
||||
|
||||
const normalizePatchTargetPath = (value) => {
|
||||
if (!value || value === '/dev/null') {
|
||||
return null;
|
||||
}
|
||||
return value.replace(/^[ab]\//, '');
|
||||
};
|
||||
|
||||
const extractPatchTargetPath = (patch) => {
|
||||
const matches = [...patch.matchAll(/^(?:-{3}|\+{3})\s+(?:[ab]\/)?([^\s\t]+)/gm)];
|
||||
const matches = [...patch.matchAll(/^(?:-{3}|\+{3})\s+.+$/gm)];
|
||||
const realTargets = matches
|
||||
.map((match) => match[1])
|
||||
.filter((value) => value && value !== '/dev/null');
|
||||
.map((match) => normalizePatchTargetPath(parsePatchPathToken(match[0])))
|
||||
.filter(Boolean);
|
||||
return realTargets[0] || null;
|
||||
};
|
||||
|
||||
|
||||
@@ -240,6 +240,25 @@ describe('applyHunk', () => {
|
||||
'patch target path does not match'
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts hunk patches for files with spaces in their path', async () => {
|
||||
if (!canRunGit()) return;
|
||||
const { tmpDir, git } = await createTempRepo();
|
||||
const filePath = 'file name.txt';
|
||||
await writeFile(tmpDir, filePath, ORIGINAL_FILE);
|
||||
await git.add(filePath);
|
||||
await git.commit('Initial');
|
||||
|
||||
await writeFile(tmpDir, filePath, EDITED_FILE);
|
||||
const diff = await getDiff(tmpDir, { path: filePath });
|
||||
const hunks = splitHunks(diff);
|
||||
expect(hunks.length).toBe(2);
|
||||
|
||||
await applyHunk(tmpDir, filePath, { patch: hunks[0], action: 'stage' });
|
||||
|
||||
const staged = (await git.raw(['show', `:${filePath}`])).replace(/\r\n/g, '\n');
|
||||
expect(staged).toBe(makeFile('TOP', 'line20'));
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user