@@ -41,6 +41,10 @@ module String = struct
4141 let length = String. length
4242
4343 let equal = String. equal
44+
45+ let index_from = String. index_from
46+
47+ let sub = String. sub
4448end
4549
4650type hunk = {
@@ -219,36 +223,42 @@ let pp ~git ppf t =
219223 pp_operation ~git ppf t.operation ;
220224 List. iter (pp_hunk ppf) t.hunks
221225
222- let operation_of_strings git mine their =
226+ let operation_of_strings ~p mine their =
227+ let open (struct
228+ type t =
229+ | Dev_null
230+ | Ignore
231+ | File of string
232+ end ) in
223233 let get_filename_opt n =
224234 let s = match String. cut '\t' n with None -> n | Some (x , _ ) -> x in
225- if s = no_file then None else
226- if git && (String. is_prefix ~prefix: " a/" s || String. is_prefix ~prefix: " b/" s) then
227- Some (String. slice ~start: 2 s)
228- else Some s
235+ if s = no_file then Dev_null else
236+ let rec iter idx = function
237+ | 0 -> String. sub s idx (String. length s - idx)
238+ | p -> iter (String. index_from s idx '/' ) (p - 1 )
239+ in
240+ try File (iter 0 p) with Not_found -> Ignore
229241 in
230242 match get_filename_opt mine, get_filename_opt their with
231- | None , Some n -> Create n
232- | Some n , None -> Delete n
233- | Some a , Some b -> if String. equal a b then Edit a else Rename (a, b)
234- | None , None -> assert false (* ??!?? *)
243+ | Dev_null , File n -> Some ( Create n)
244+ | File n , Dev_null -> Some ( Delete n)
245+ | File a , File b -> Some ( if String. equal a b then Edit a else Rename (a, b) )
246+ | Dev_null , Dev_null | Ignore , _ | _ , Ignore -> None
235247
236248(* parses a list of lines to a diff.t list *)
237- let to_diff data =
249+ let to_diff ~ p data =
238250 (* first locate --- and +++ lines *)
239- let rec find_start git ?hdr = function
251+ let rec find_start ?hdr = function
240252 | [] -> hdr, []
241- | x ::xs when String. is_prefix ~prefix: " diff --git " x ->
242- begin match hdr with None -> find_start true xs | Some _ -> hdr, x::xs end
243253 | x ::y ::xs when String. is_prefix ~prefix: " rename from " x && String. is_prefix ~prefix: " rename to " y ->
244254 let hdr = Rename_only (String. slice ~start: 12 x, String. slice ~start: 10 y) in
245- find_start git ~hdr xs
255+ find_start ~hdr xs
246256 | x ::y ::xs when String. is_prefix ~prefix: " --- " x ->
247257 let mine = String. slice ~start: 4 x and their = String. slice ~start: 4 y in
248- Some ( operation_of_strings git mine their) , xs
249- | _ ::xs -> find_start git ?hdr xs
258+ operation_of_strings ~p mine their, xs
259+ | _ ::xs -> find_start ?hdr xs
250260 in
251- match find_start false data with
261+ match find_start data with
252262 | Some (Rename_only _ as operation ), rest ->
253263 let hunks = [] and mine_no_nl = false and their_no_nl = false in
254264 Some ({ operation ; hunks ; mine_no_nl ; their_no_nl }, rest)
@@ -260,11 +270,11 @@ let to_diff data =
260270
261271let to_lines = String. cuts '\n'
262272
263- let to_diffs data =
273+ let to_diffs ~ p data =
264274 let lines = to_lines data in
265275 let rec doit acc = function
266276 | [] -> List. rev acc
267- | xs -> match to_diff xs with
277+ | xs -> match to_diff ~p xs with
268278 | None -> List. rev acc
269279 | Some (diff , rest ) -> doit (diff :: acc) rest
270280 in
0 commit comments