Something went wrong. Try again.
A local Git merge queue with content-bound gate verdicts
Something went wrong. Try again.
2.8 kB · 74 lines
OCaml
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475(* mq hook reference-transaction refuses nothing and writes nothing, in any phase, even where mq init has not run: Git aborts a transaction whose hook fails at preparing or prepared (githooks(5)), and a move made outside mq is ordinary Git (doc/invariants.md, 1). *)
open Merge_queue_eio
let test_refuses_nothing () = Fixture.with_dir @@ fun env root -> ignore (Fixture.git env ~dir:root [ "init"; "-q"; "-b"; "main" ]); let stdin = String.make 40 '0' ^ " " ^ String.make 40 'a' ^ " refs/heads/main\n" in List.iter (fun phase -> Alcotest.(check int) "0" 0 (Command_hook.run (Fixture.context env root) "reference-transaction" ~phase ~stdin)) [ Preparing; Prepared; Committed; Aborted ]; Alcotest.(check bool) "nothing written" false (Sys.file_exists Fpath.(to_string (root / ".git" / "mq")))
(* Git runs the hook at every phase of every transaction, mq's own among them: a land runs it at each phase of each ref it writes, and each run that touches the file system waits for it. A transaction that names no probe has nothing to answer before it commits, so the hook decides that from its phase and its standard input alone, with no operation on the file system. A probe, in the same phase, is answered: the counter counts. *)let test_reads_nothing_unprobed () = Fixture.with_dir @@ fun env root -> ignore (Fixture.git env ~dir:root [ "init"; "-q"; "-b"; "main" ]); let seen = ref [] in let env = Remote_observer.noting env ~note:(fun path -> seen := path :: !seen) in let hook phase stdin = let ctx = Fixture.context env root in seen := []; ignore (Command_hook.run ctx "reference-transaction" ~phase ~stdin); List.rev !seen in let update name = String.make 40 '0' ^ " " ^ String.make 40 'a' ^ " " ^ name in let unprobed = update "refs/heads/main" ^ "\n" ^ update "refs/mq/keep" ^ "\n" in List.iter (fun (what, phase) -> Alcotest.(check (list string)) (what ^ ": no operation on the file system") [] (hook phase unprobed)) [ ("preparing", Command_hook.Preparing); ("prepared", Prepared); ("aborted", Aborted); ]; let probe = Merge_queue.Ref_name.(to_string (probe 7)) in let answered = hook Prepared (unprobed ^ update probe ^ "\n") in Alcotest.(check bool) "a probe is answered" true (Sys.file_exists Fpath.(to_string (root / ".git" / "mq" / "probe.7"))); Alcotest.(check bool) "its answer is counted" true (answered <> [])
let suite = ( "command_hook", [ Alcotest.test_case "it refuses nothing and writes nothing" `Quick test_refuses_nothing; Alcotest.test_case "a transaction with no probe reads nothing" `Quick test_reads_nothing_unprobed; ] )