let parse_svn_log wc_dir =
  let re_line = "r\\([0-9]+\\) | \\([^ ]+\\) | \\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\) \\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\) \\([+-][0-9][0-9]\\)[^|]*| \\([0-9]+\\) " in
  let re_line = Str.regexp re_line in
  let read_entry ic =
    let line = input_line ic in
    if Str.string_match re_line line 0 then
      begin
        let g n = Str.matched_group n line in
        let revid = my_int_of_string (g 1) in
        let login = g 2 in
        let year = my_int_of_string (g 3) in
        let month = my_int_of_string (g 4) in
        let day = my_int_of_string (g 5) in
        let hour = my_int_of_string (g 6) in
        let min = my_int_of_string (g 7) in
        let sec = my_int_of_string (g 8) in
        let tz = my_int_of_string (g 9) in
        let lines = my_int_of_string (g 10) in
        let b = Buffer.create 256 in
        ignore(input_line ic);
        for i = 1 to lines do
          Printf.bprintf b "%s\n" (input_line ic)
        done;
        Some (revid, login, (year, month, day, hour, min, sec, tz), Buffer.contents b)
      end
    else
      None
  in
  let command = Printf.sprintf "(cd %s && svn log)" (Filename.quote wc_dir) in
  try
    let ic = Unix.open_process_in command in
    let l = ref [] in
    begin
      try
        while true do
          match read_entry ic with
            Some e -> l := e :: !l
          | None -> ()
        done
      with
      End_of_file -> ignore(Unix.close_process_in ic)
    end;
    !l
  with
    Unix.Unix_error (e,s1,s2) ->
      let msg = Printf.sprintf "%s %s: %s"
        (Unix.error_message e) s2 s1
      in
      failwith msg