A patch is a file header plus a sequence of hunks, each a header and prefixed body lines. Today you parse the whole thing back into hunks of keep/delete/insert operations - the same Op list your diff produces.
Parse a unified diff string into a list of hunks, each with its ranges and its operations.
Parsing a patch is a line-by-line classification, using the very prefixes you emit when writing one. The --- and +++ file-header lines are skipped, an @@ line opens a new hunk (parsed by the previous lesson’s helper), and the \ No newline at end of file marker is skipped for now since it carries no operation. Every other line is a body line whose first character - space, minus, or plus - tells you whether it is a Keep, Delete, or Insert, with the rest of the line being the content. The result is a hunk holding the same []Op your Diff produces, which is exactly what makes applying it straightforward.
Notice the symmetry: writing a diff turned operations into prefixed lines, and reading it turns prefixed lines back into operations. The unified format is really just a serialization of the edit script with enough location metadata (the @@ ranges) to apply it to a file that may have shifted. With a parsed patch in hand, the applier can walk the original document and the hunk together, and the round-trip is one lesson away.
for _, line := range strings.Split(patch, "\n") {switch {case strings.HasPrefix(line, "--- "), strings.HasPrefix(line, "+++ "):continue // file headercase strings.HasPrefix(line, "@@"):// start a new hunk from parseHunkHeader(line)case strings.HasPrefix(line, "\\"):continue // "\ No newline at end of file" markercase strings.HasPrefix(line, " "):// Keep line[1:]case strings.HasPrefix(line, "-"):// Delete line[1:]case strings.HasPrefix(line, "+"):// Insert line[1:]}}