MCPcopy Index your code
hub / github.com/kpdecker/jsdiff / formatPatch

Function formatPatch

src/patch/create.ts:358–450  ·  view source on GitHub ↗
(patch: StructuredPatch | StructuredPatch[], headerOptions?: HeaderOptions)

Source from the content-addressed store, hash-verified

356 * headers for patches with no hunks (e.g. renames without content changes).
357 */
358export function formatPatch(patch: StructuredPatch | StructuredPatch[], headerOptions?: HeaderOptions): string {
359 if (!headerOptions) {
360 headerOptions = INCLUDE_HEADERS;
361 }
362 if (Array.isArray(patch)) {
363 if (patch.length > 1 && !headerOptions.includeFileHeaders && !patch.every(p => p.isGit)) {
364 throw new Error(
365 'Cannot omit file headers on a multi-file patch. '
366 + '(The result would be unparseable; how would a tool trying to apply '
367 + 'the patch know which changes are to which file?)'
368 );
369 }
370 return patch.map(p => formatPatch(p, headerOptions)).join('\n');
371 }
372
373 const ret = [];
374
375 // Git patches have a fixed header format (diff --git, extended headers,
376 // and ---/+++ when hunks are present), so headerOptions is ignored.
377 if (patch.isGit) {
378 headerOptions = INCLUDE_HEADERS;
379 // Emit Git-style diff --git header and extended headers.
380 // Git never puts /dev/null in the "diff --git" line; for file
381 // creations/deletions it uses the real filename on both sides.
382 if (!patch.oldFileName) {
383 throw new Error('oldFileName must be specified for Git patches');
384 }
385 if (!patch.newFileName) {
386 throw new Error('newFileName must be specified for Git patches');
387 }
388 let gitOldName = patch.oldFileName;
389 let gitNewName = patch.newFileName;
390 if (patch.isCreate && gitOldName === '/dev/null') {
391 gitOldName = gitNewName.replace(/^b\//, 'a/');
392 } else if (patch.isDelete && gitNewName === '/dev/null') {
393 gitNewName = gitOldName.replace(/^a\//, 'b/');
394 }
395 ret.push('diff --git ' + quoteFileNameIfNeeded(gitOldName) + ' ' + quoteFileNameIfNeeded(gitNewName));
396 if (patch.isDelete) {
397 ret.push('deleted file mode ' + (patch.oldMode ?? '100644'));
398 }
399 if (patch.isCreate) {
400 ret.push('new file mode ' + (patch.newMode ?? '100644'));
401 }
402 if (patch.oldMode && patch.newMode && !patch.isDelete && !patch.isCreate) {
403 ret.push('old mode ' + patch.oldMode);
404 ret.push('new mode ' + patch.newMode);
405 }
406 if (patch.isRename) {
407 ret.push('rename from ' + quoteFileNameIfNeeded((patch.oldFileName ?? '').replace(/^a\//, '')));
408 ret.push('rename to ' + quoteFileNameIfNeeded((patch.newFileName ?? '').replace(/^b\//, '')));
409 }
410 if (patch.isCopy) {
411 ret.push('copy from ' + quoteFileNameIfNeeded((patch.oldFileName ?? '').replace(/^a\//, '')));
412 ret.push('copy to ' + quoteFileNameIfNeeded((patch.newFileName ?? '').replace(/^b\//, '')));
413 }
414 } else {
415 if (headerOptions.includeIndex && patch.oldFileName == patch.newFileName && patch.oldFileName !== undefined) {

Callers 4

line-endings.jsFile · 0.85
reverse.jsFile · 0.85
create.jsFile · 0.85
createTwoFilesPatchFunction · 0.85

Calls 2

quoteFileNameIfNeededFunction · 0.85
joinMethod · 0.45

Tested by

no test coverage detected