Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
diffSerializer.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
open Diff let serialize_line = function | `ContextLine content -> Printf.sprintf " %s" content | `RemovedLine content -> Printf.sprintf "-%s" content | `AddedLine content -> Printf.sprintf "+%s" content let serialize_binary_content binary_content = Printf.sprintf "GIT binary patch\n%s" binary_content let serialize_created_file (file : created_file) = let diff_header = Printf.sprintf "diff --git a/%s b/%s" file.path file.path in let file_mode = Printf.sprintf "new file mode %d" file.mode in let content = match file.content with | `Binary binary_content -> [ serialize_binary_content binary_content ] | `Text added_lines -> let lines = added_lines |> List.map serialize_line in if List.length lines = 0 then [] else let file_path_header = Printf.sprintf {|--- /dev/null +++ b/%s|} file.path in let hunk_header = Printf.sprintf "@@ -0,0 +1,%d @@" (List.length lines) in file_path_header :: hunk_header :: lines in diff_header :: file_mode :: content |> String.concat "\n" let serialize_deleted_file (file : deleted_file) = let diff_header = Printf.sprintf "diff --git a/%s b/%s" file.path file.path in let file_mode = Printf.sprintf "deleted file mode %d" file.mode in let content = match file.content with | `Binary binary_content -> [ serialize_binary_content binary_content ] | `Text removed_lines -> let lines = removed_lines |> List.map serialize_line in if List.length lines = 0 then [] else let file_path_header = Printf.sprintf {|--- a/%s +++ /dev/null|} file.path in let hunk_header = Printf.sprintf "@@ -1,%d +0,0 @@" (List.length lines) in file_path_header :: hunk_header :: lines in diff_header :: file_mode :: content |> String.concat "\n" let count_left_lines lines = lines |> List.fold_left (fun count line -> match line with | `ContextLine _ -> count + 1 | `RemovedLine _ -> count + 1 | `AddedLine _ -> count) 0 let count_right_lines lines = lines |> List.fold_left (fun count line -> match line with | `ContextLine _ -> count + 1 | `RemovedLine _ -> count | `AddedLine _ -> count + 1) 0 let serialize_hunk hunk right_offset = let left_start_line = hunk.starting_line in let left_line_count = count_left_lines hunk.lines in let right_start_line = left_start_line + right_offset in let right_line_count = count_right_lines hunk.lines in let left_lines = if left_line_count = 1 then Printf.sprintf "-%d" left_start_line else Printf.sprintf "-%d,%d" left_start_line left_line_count in let right_lines = if right_line_count = 1 then Printf.sprintf "+%d" right_start_line else Printf.sprintf "+%d,%d" right_start_line right_line_count in let context_snippet = match hunk.context_snippet with None -> "" | Some snippet -> Printf.sprintf " %s" snippet in let hunk_header = Printf.sprintf "@@ %s %s @@%s" left_lines right_lines context_snippet in let lines = hunk.lines |> List.map serialize_line in hunk_header :: lines let serialize_changed_file (changed_file : changed_file) = let src_path, dst_path = match changed_file.path with | Path path -> (path, path) | ChangedPath { old_path; new_path } -> (old_path, new_path) in let diff_header = [ Printf.sprintf "diff --git a/%s b/%s" src_path dst_path ] in let mode_change = match changed_file.mode_change with | None -> [] | Some mode_change -> [ Printf.sprintf "old mode %d" mode_change.old_mode; Printf.sprintf "new mode %d" mode_change.new_mode; ] in let rename = match changed_file.path with | Path _ -> [] | ChangedPath { old_path; new_path } -> [ "similarity index 100%"; Printf.sprintf "rename from %s" old_path; Printf.sprintf "rename to %s" new_path; ] in let content = match changed_file.content with | `Binary binary_content -> [ serialize_binary_content binary_content ] | `Text hunks -> let changed_file_header = Printf.sprintf {|--- a/%s +++ b/%s|} src_path dst_path in let _, hunks = hunks |> List.fold_left_map (fun acc hunk -> let left_lines = count_left_lines hunk.lines in let right_lines = count_right_lines hunk.lines in (acc + right_lines - left_lines, serialize_hunk hunk acc)) 0 in let hunk_lines = hunks |> List.flatten in if List.length hunks > 0 then changed_file_header :: hunk_lines else [] in List.concat [ diff_header; mode_change; rename; content ] |> String.concat "\n" let serialize_file = function | CreatedFile file -> serialize_created_file file | DeletedFile file -> serialize_deleted_file file | ChangedFile file -> serialize_changed_file file let serialize diff = diff.files |> List.map serialize_file |> String.concat "\n"