()
| 46 | } |
| 47 | |
| 48 | function parseIndex() { |
| 49 | const index: Partial<StructuredPatch> = {}; |
| 50 | index.hunks = []; |
| 51 | list.push(index); |
| 52 | |
| 53 | // Parse diff metadata |
| 54 | let seenDiffHeader = false; |
| 55 | while (i < diffstr.length) { |
| 56 | const line = diffstr[i]; |
| 57 | |
| 58 | // File header (---, +++) or hunk header (@@) found; end parsing diff metadata |
| 59 | if (isFileHeader(line) || isHunkHeader(line)) { |
| 60 | break; |
| 61 | } |
| 62 | |
| 63 | // The next two branches handle recognized diff headers. Note that |
| 64 | // isDiffHeader deliberately does NOT match arbitrary `diff` |
| 65 | // commands like `diff -u -p -r1.1 -r1.2`, because in some |
| 66 | // formats (e.g. CVS diffs) such lines appear as metadata within |
| 67 | // a single file's header section, after an `Index:` line. See the |
| 68 | // diffx documentation (https://diffx.org) for examples. |
| 69 | // |
| 70 | // In both branches: if we've already seen a diff header for *this* |
| 71 | // file and now we encounter another one, it must belong to the |
| 72 | // next file, so break. |
| 73 | |
| 74 | if (isGitDiffHeader(line)) { |
| 75 | if (seenDiffHeader) { |
| 76 | return; |
| 77 | } |
| 78 | seenDiffHeader = true; |
| 79 | index.isGit = true; |
| 80 | |
| 81 | // Parse the old and new filenames from the `diff --git` header and |
| 82 | // tentatively set oldFileName and newFileName from them. These may |
| 83 | // be overridden below by `rename from` / `rename to` or `copy from` / |
| 84 | // `copy to` extended headers, or by --- and +++ lines. But for Git |
| 85 | // diffs that lack all of those (e.g. mode-only changes, binary |
| 86 | // file changes without rename), these are the only filenames we |
| 87 | // get. |
| 88 | // parseGitDiffHeader returns null if the header can't be parsed |
| 89 | // (e.g. unterminated quoted filename, or unexpected format). In |
| 90 | // that case we skip setting filenames here; they may still be |
| 91 | // set from --- / +++ or rename from / rename to lines below. |
| 92 | const paths = parseGitDiffHeader(line); |
| 93 | if (paths) { |
| 94 | index.oldFileName = paths.oldFileName; |
| 95 | index.newFileName = paths.newFileName; |
| 96 | } |
| 97 | |
| 98 | // Consume Git extended headers (`old mode`, `new mode`, `rename from`, |
| 99 | // `rename to`, `similarity index`, `index`, `Binary files ... differ`, |
| 100 | // etc.) |
| 101 | i++; |
| 102 | while (i < diffstr.length) { |
| 103 | const extLine = diffstr[i]; |
| 104 | |
| 105 | // Stop consuming extended headers if we hit a file header, |
no test coverage detected