2026-01-21 17:07.11: New job: test mirage/irmin https://github.com/mirage/irmin.git#refs/pull/2390/head (d7cb84ab292c02deb5850b9cc1c6f8ca23ed921b) (linux-x86_64:(lint-fmt)) Base: ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500 ocamlformat version: version 0.27.0 (from opam) To reproduce locally: git clone --recursive "https://github.com/mirage/irmin.git" && cd "irmin" && git fetch origin "refs/pull/2390/head" && git reset --hard d7cb84ab cat > Dockerfile <<'END-OF-DOCKERFILE' FROM ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500 USER 1000:1000 RUN cd ~/opam-repository && (git cat-file -e 873cb18c37b308713d11ad3894c4bb78d73fb3e7 || git fetch origin master) && git reset -q --hard 873cb18c37b308713d11ad3894c4bb78d73fb3e7 && git log --no-decorate -n1 --oneline && opam update -u RUN opam depext -i dune WORKDIR /src RUN opam depext -i ocamlformat=0.27.0 COPY --chown=1000:1000 . /src/ RUN opam exec -- dune build @fmt --ignore-promoted-rules || (echo "dune build @fmt failed"; exit 2) END-OF-DOCKERFILE docker build . END-REPRO-BLOCK 2026-01-21 17:07.11: Using cache hint "mirage/irmin-ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500-debian-13-4.08_opam-2.5-ocamlformat-873cb18c37b308713d11ad3894c4bb78d73fb3e7" 2026-01-21 17:07.11: Using OBuilder spec: ((from ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500) (user (uid 1000) (gid 1000)) (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "cd ~/opam-repository && (git cat-file -e 873cb18c37b308713d11ad3894c4bb78d73fb3e7 || git fetch origin master) && git reset -q --hard 873cb18c37b308713d11ad3894c4bb78d73fb3e7 && git log --no-decorate -n1 --oneline && opam update -u")) (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "opam depext -i dune")) (workdir /src) (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "opam depext -i ocamlformat=0.27.0")) (copy (src .) (dst /src/)) (run (shell "opam exec -- dune build @fmt --ignore-promoted-rules || (echo \"dune build @fmt failed\"; exit 2)")) ) 2026-01-21 17:07.11: Waiting for resource in pool OCluster 2026-01-21 17:07.12: Waiting for worker… 2026-01-21 17:07.12: Got resource from pool OCluster Building on asteria.caelum.ci.dev All commits already cached HEAD is now at d7cb84ab29 Implement inline contents for small values (from ocaml/opam:debian-13-ocaml-4.08@sha256:7cdc2a1943ac1462f548be7816c6d02f14e605659f225027208abe04795ea500) 2026-01-21 17:08.01 ---> saved as "4c1f60dc0cc5644c6a4c05cf3315bdbf9cc478b70e443b212a1220385bab8bba" /: (user (uid 1000) (gid 1000)) /: (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "cd ~/opam-repository && (git cat-file -e 873cb18c37b308713d11ad3894c4bb78d73fb3e7 || git fetch origin master) && git reset -q --hard 873cb18c37b308713d11ad3894c4bb78d73fb3e7 && git log --no-decorate -n1 --oneline && opam update -u")) From https://github.com/ocaml/opam-repository * branch master -> FETCH_HEAD a6b2f19780..31c3ce4c9b master -> origin/master 873cb18c37 Merge pull request #29216 from shonfeder/release-dune-3.21.0 <><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> [default] Initialised default (at git+file:///home/opam/opam-repository): [INFO] opam 2.1 and 2.2 include many performance and security improvements over 2.0; please consider upgrading (https://opam.ocaml.org/doc/Install.html) Everything as up-to-date as possible (run with --verbose to show unavailable upgrades). However, you may "opam upgrade" these packages explicitly, which will ask permission to downgrade or uninstall the conflicting packages. Nothing to do. # Run eval $(opam env) to update the current shell environment 2026-01-21 17:08.54 ---> saved as "72a7cd495abee3d0659c15140c96fff42d035222fc9b794ad453f1a5292cd6f1" /: (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "opam depext -i dune")) # Detecting depexts using vars: arch=x86_64, os=linux, os-distribution=debian, os-family=debian # No extra OS packages requirements found. # All required OS packages found. # Now letting opam install the packages The following actions will be performed: - install dune 3.21.0 <><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><> [dune.3.21.0] found in cache <><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> -> installed dune.3.21.0 Done. # Run eval $(opam env) to update the current shell environment 2026-01-21 17:09.22 ---> saved as "3b5aee51bb4636e6dab95deb6944478b896d0b06f021712424b773f7d70073ac" /: (workdir /src) /src: (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "opam depext -i ocamlformat=0.27.0")) # Detecting depexts using vars: arch=x86_64, os=linux, os-distribution=debian, os-family=debian # No extra OS packages requirements found. # All required OS packages found. # Now letting opam install the packages The following actions will be performed: - install sexplib0 v0.14.0 [required by base] - install ocamlbuild 0.16.1 [required by fpath, astring, uuseg] - install cmdliner 1.3.0 [required by ocamlformat] - install either 1.0.0 [required by ocamlformat-lib] - install menhirLib 20250912 [required by ocamlformat-lib] - install csexp 1.5.2 [required by ocamlformat] - install dune-build-info 3.21.0 [required by ocamlformat-lib] - install camlp-streams 5.0.1 [required by ocamlformat-lib] - install seq base [required by re] - install menhirSdk 20250912 [required by ocamlformat-lib] - install fix 20250919 [required by ocamlformat-lib] - install menhirCST 20250912 [required by menhir] - install ocamlfind 1.9.8 [required by ocp-indent, astring, fpath, uuseg] - install ocaml-version 4.0.3 [required by ocamlformat-lib] - install dune-configurator 3.21.0 [required by base] - install re 1.11.0 [required by ocamlformat] - install menhir 20250912 [required by ocamlformat-lib] - install topkg 1.1.1 [required by fpath, astring, uuseg] - install ocp-indent 1.9.0 [required by ocamlformat-lib] - install base v0.14.3 [required by ocamlformat-lib] - install uutf 1.0.4 [required by ocamlformat-lib] - install astring 0.8.5 [required by ocamlformat-lib] - install stdio v0.14.0 [required by ocamlformat-lib] - install uucp 15.0.0 [required by uuseg] - install fpath 0.7.3 [required by ocamlformat-lib] - install uuseg 15.0.0 [required by ocamlformat-lib] - install ocamlformat-lib 0.27.0 [required by ocamlformat] - install ocamlformat 0.27.0 ===== 28 to install ===== <><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><> [astring.0.8.5] found in cache [base.v0.14.3] found in cache [camlp-streams.5.0.1] found in cache [cmdliner.1.3.0] found in cache [csexp.1.5.2] found in cache [dune-build-info.3.21.0] found in cache [dune-configurator.3.21.0] found in cache [either.1.0.0] found in cache [fix.20250919] found in cache [fpath.0.7.3] found in cache [menhir.20250912] found in cache [menhirCST.20250912] found in cache [menhirLib.20250912] found in cache [menhirSdk.20250912] found in cache [ocaml-version.4.0.3] found in cache [ocamlbuild.0.16.1] found in cache [ocamlfind.1.9.8] found in cache [ocamlformat.0.27.0] found in cache [ocamlformat-lib.0.27.0] found in cache [ocp-indent.1.9.0] found in cache [re.1.11.0] found in cache [sexplib0.v0.14.0] found in cache [stdio.v0.14.0] found in cache [topkg.1.1.1] found in cache [uucp.15.0.0] found in cache [uuseg.15.0.0] found in cache [uutf.1.0.4] found in cache <><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> -> installed seq.base -> installed camlp-streams.5.0.1 -> installed csexp.1.5.2 -> installed cmdliner.1.3.0 -> installed either.1.0.0 -> installed fix.20250919 -> installed menhirCST.20250912 -> installed menhirLib.20250912 -> installed menhirSdk.20250912 -> installed ocaml-version.4.0.3 -> installed re.1.11.0 -> installed sexplib0.v0.14.0 -> installed dune-build-info.3.21.0 -> installed dune-configurator.3.21.0 -> installed ocamlfind.1.9.8 -> installed ocamlbuild.0.16.1 -> installed ocp-indent.1.9.0 -> installed base.v0.14.3 -> installed topkg.1.1.1 -> installed stdio.v0.14.0 -> installed uutf.1.0.4 -> installed astring.0.8.5 -> installed fpath.0.7.3 -> installed menhir.20250912 -> installed uucp.15.0.0 -> installed uuseg.15.0.0 -> installed ocamlformat-lib.0.27.0 -> installed ocamlformat.0.27.0 Done. <><> ocp-indent.1.9.0 installed successfully ><><><><><><><><><><><><><><><><><> => This package requires additional configuration for use in editors. Install package 'user-setup', or manually: * for Emacs, add these lines to ~/.emacs: (add-to-list 'load-path "/home/opam/.opam/4.08/share/emacs/site-lisp") (require 'ocp-indent) * for Vim, add this line to ~/.vimrc: set rtp^="/home/opam/.opam/4.08/share/ocp-indent/vim" # Run eval $(opam env) to update the current shell environment 2026-01-21 17:10.18 ---> saved as "2ae43ae662b95641fa2bf73d980051b9145f20314d85ad107c6a3257b77df4e6" /src: (copy (src .) (dst /src/)) 2026-01-21 17:10.19 ---> saved as "7e7a96a1a8ec2c1ec9404d99e6386c585da9a816ca54482a7fa4e70c4100694d" /src: (run (shell "opam exec -- dune build @fmt --ignore-promoted-rules || (echo \"dune build @fmt failed\"; exit 2)")) Warning: Invalid documentation comment: File "src/irmin-pack/layout.ml", line 97, characters 27-50: '{v ... v}' (verbatim text) should begin on its own line. Warning: Invalid documentation comment: File "src/irmin-pack/layout.ml", line 97, characters 50-51: Paragraph should begin on its own line. Warning: Invalid documentation comment: File "test/irmin-graphql/common.mli", line 88, character 16 to line 92, character 6: '{[...]}' (code block) should begin on its own line. Warning: Invalid documentation comment: File "test/irmin-graphql/common.mli", line 98, character 16 to line 102, character 6: '{[...]}' (code block) should begin on its own line. Warning: Invalid documentation comment: File "test/irmin-graphql/common.mli", line 104, character 24 to line 108, character 6: '{[...]}' (code block) should begin on its own line. Warning: Invalid documentation comment: File "test/irmin-graphql/common.mli", line 114, character 16 to line 118, character 6: '{[...]}' (code block) should begin on its own line. File "src/irmin/irmin.ml", line 1, characters 0-0: diff --git a/_build/default/src/irmin/irmin.ml b/_build/default/src/irmin/.formatted/irmin.ml index 6750ee5..ce15365 100644 --- a/_build/default/src/irmin/irmin.ml +++ b/_build/default/src/irmin/.formatted/irmin.ml @@ -181,8 +181,8 @@ struct end module Of_backend = Store.Make - module Tree = Tree + module type Tree = Tree.S module type S = Store.S File "src/irmin-pack/conf.mli", line 1, characters 0-0: diff --git a/_build/default/src/irmin-pack/conf.mli b/_build/default/src/irmin-pack/.formatted/conf.mli index 6d3ffc0..7ead362 100644 --- a/_build/default/src/irmin-pack/conf.mli +++ b/_build/default/src/irmin-pack/.formatted/conf.mli @@ -135,14 +135,16 @@ val inline_contents : Irmin.Backend.Conf.t -> bool When enabled, content values smaller than 16 bytes (serialized) are stored directly within the parent node entry rather than as separate pack entries. - This reduces storage overhead and improves read performance for small values. + This reduces storage overhead and improves read performance for small + values. Note: Enabling this option changes the hash computation of nodes, making stores incompatible with stores created with inlining disabled for hash-based comparisons. - See the {{:./doc/irmin-pack/design/inline_contents.md}inline contents design - doc} for more details. *) + See the + {{:./doc/irmin-pack/design/inline_contents.md}inline contents design doc} + for more details. *) val switch : Irmin.Backend.Conf.t -> Eio.Switch.t (** Eio switch *) File "src/irmin/irmin.mli", line 1, characters 0-0: diff --git a/_build/default/src/irmin/irmin.mli b/_build/default/src/irmin/.formatted/irmin.mli index a645d46..521c3b1 100644 --- a/_build/default/src/irmin/irmin.mli +++ b/_build/default/src/irmin/.formatted/irmin.mli @@ -85,13 +85,14 @@ module Tree : sig will be inlined. Default is [false]. This is a global setting that should be set before creating stores. *) - module Make (B : Backend.S) : Tree_intf.S - with type path = B.Node.Path.t - and type step = B.Node.Path.step - and type metadata = B.Node.Metadata.t - and type contents = B.Contents.value - and type contents_key = B.Contents.Key.t - and type hash = B.Hash.t + module Make (B : Backend.S) : + Tree_intf.S + with type path = B.Node.Path.t + and type step = B.Node.Path.step + and type metadata = B.Node.Metadata.t + and type contents = B.Contents.value + and type contents_key = B.Contents.Key.t + and type hash = B.Hash.t end module Metadata = Metadata File "src/irmin-pack/inode_intf.ml", line 1, characters 0-0: diff --git a/_build/default/src/irmin-pack/inode_intf.ml b/_build/default/src/irmin-pack/.formatted/inode_intf.ml index 8d54e52..f2d4d6f 100644 --- a/_build/default/src/irmin-pack/inode_intf.ml +++ b/_build/default/src/irmin-pack/.formatted/inode_intf.ml @@ -118,10 +118,12 @@ module type Compress = sig type address = Offset of pack_offset | Hash of hash type ptr = { index : dict_key; hash : address } type tree = { depth : dict_key; length : dict_key; entries : ptr list } + type value = | Contents of name * address * metadata | Contents_inlined_value of name * string * metadata | Node of name * address + type v = Values of value list | Tree of tree type v1 = { mutable length : int; v : v } File "src/irmin/node.ml", line 1, characters 0-0: diff --git a/_build/default/src/irmin/node.ml b/_build/default/src/irmin/.formatted/node.ml index f79091b..9f617ba 100644 --- a/_build/default/src/irmin/node.ml +++ b/_build/default/src/irmin/.formatted/node.ml @@ -185,7 +185,8 @@ struct | Node n -> (n.name, `Node (n.node, n.inlined)) | Contents c -> (c.name, `Contents (c.contents, Metadata.default)) | Contents_m c -> (c.name, `Contents (c.contents, c.metadata)) - | Contents_inlined_value c -> (c.name, `Contents_inlined (c.value, c.metadata)) + | Contents_inlined_value c -> + (c.name, `Contents_inlined (c.value, c.metadata)) | Node_hash _ | Contents_hash _ | Contents_m_hash _ | Contents_inlined_hash _ -> (* Not reachable after [Portable.of_node]. See invariant on {!entry}. *) @@ -217,7 +218,8 @@ struct (c.name, `Contents (Contents_key.to_hash c.contents, c.metadata)) | Contents_hash c -> (c.name, `Contents (c.contents, Metadata.default)) | Contents_m_hash c -> (c.name, `Contents (c.contents, c.metadata)) - | Contents_inlined_value c -> (c.name, `Contents_inlined (c.value, c.metadata)) + | Contents_inlined_value c -> + (c.name, `Contents_inlined (c.value, c.metadata)) | Contents_inlined _c -> assert false | Contents_inlined_hash _c -> assert false File "test/irmin-pack/gen_always.ml", line 1, characters 0-0: diff --git a/_build/default/test/irmin-pack/gen_always.ml b/_build/default/test/irmin-pack/.formatted/gen_always.ml index d315877..58696da 100644 --- a/_build/default/test/irmin-pack/gen_always.ml +++ b/_build/default/test/irmin-pack/.formatted/gen_always.ml @@ -43,7 +43,7 @@ let info = Store.Info.empty let generate ~sw ~fs = let path = "version_3_always_new" in rm_dir path; - let rw = Store.Repo.v (config ~sw ~fs (Eio.Path.(fs / path))) in + let rw = Store.Repo.v (config ~sw ~fs Eio.Path.(fs / path)) in (* Create tree matching the original structure: borphan | b01 <- n01 <- n0 <- c0 @@ -61,11 +61,17 @@ let generate ~sw ~fs = let k_b01 = Store.Backend.Contents.add bstore "b01" in (* Create n01 node with step-b01 -> b01 *) - let n01 = Store.Backend.Node.Val.of_list [ ("step-b01", `Contents (k_b01, ())) ] [] in + let n01 = + Store.Backend.Node.Val.of_list + [ ("step-b01", `Contents (k_b01, ())) ] + [] + in let k_n01 = Store.Backend.Node.add nstore n01 in (* Create n0 (root) node with step-n01 -> n01 *) - let n0 = Store.Backend.Node.Val.of_list [ ("step-n01", `Node (k_n01, [])) ] [] in + let n0 = + Store.Backend.Node.Val.of_list [ ("step-n01", `Node (k_n01, [])) ] [] + in let k_n0 = Store.Backend.Node.add nstore n0 in (* Create commit *) @@ -81,7 +87,8 @@ let generate ~sw ~fs = let hex = String.to_seq hash_bytes |> Seq.map (fun c -> Printf.sprintf "%02x" (Char.code c)) - |> List.of_seq |> String.concat "" + |> List.of_seq + |> String.concat "" in Printf.printf "Commit hash (hex): %s\n" hex); File "test/irmin-pack/gen_minimal.ml", line 1, characters 0-0: diff --git a/_build/default/test/irmin-pack/gen_minimal.ml b/_build/default/test/irmin-pack/.formatted/gen_minimal.ml index e9de76b..0da9c6b 100644 --- a/_build/default/test/irmin-pack/gen_minimal.ml +++ b/_build/default/test/irmin-pack/.formatted/gen_minimal.ml @@ -43,7 +43,7 @@ let info = Store.Info.empty let generate ~sw ~fs = let path = "version_3_minimal_new" in rm_dir path; - let rw = Store.Repo.v (config ~sw ~fs (Eio.Path.(fs / path))) in + let rw = Store.Repo.v (config ~sw ~fs Eio.Path.(fs / path)) in (* Create tree matching the original structure: borphan | b01 <- n01 <- n0 <- c0 @@ -61,11 +61,17 @@ let generate ~sw ~fs = let k_b01 = Store.Backend.Contents.add bstore "b01" in (* Create n01 node with step-b01 -> b01 *) - let n01 = Store.Backend.Node.Val.of_list [ ("step-b01", `Contents (k_b01, ())) ] [] in + let n01 = + Store.Backend.Node.Val.of_list + [ ("step-b01", `Contents (k_b01, ())) ] + [] + in let k_n01 = Store.Backend.Node.add nstore n01 in (* Create n0 (root) node with step-n01 -> n01 *) - let n0 = Store.Backend.Node.Val.of_list [ ("step-n01", `Node (k_n01, [])) ] [] in + let n0 = + Store.Backend.Node.Val.of_list [ ("step-n01", `Node (k_n01, [])) ] [] + in let k_n0 = Store.Backend.Node.add nstore n0 in (* Create commit *) @@ -81,7 +87,8 @@ let generate ~sw ~fs = let hex = String.to_seq hash_bytes |> Seq.map (fun c -> Printf.sprintf "%02x" (Char.code c)) - |> List.of_seq |> String.concat "" + |> List.of_seq + |> String.concat "" in Printf.printf "Commit hash (hex): %s\n" hex); File "test/irmin-pack/gen_gced.ml", line 1, characters 0-0: diff --git a/_build/default/test/irmin-pack/gen_gced.ml b/_build/default/test/irmin-pack/.formatted/gen_gced.ml index a0f6aea..9162f26 100644 --- a/_build/default/test/irmin-pack/gen_gced.ml +++ b/_build/default/test/irmin-pack/.formatted/gen_gced.ml @@ -42,7 +42,7 @@ let info = Store.Info.empty let generate ~domain_mgr ~sw ~fs = let path = "version_3_minimal_gced_new" in rm_dir path; - let rw = Store.Repo.v (config ~sw ~fs (Eio.Path.(fs / path))) in + let rw = Store.Repo.v (config ~sw ~fs Eio.Path.(fs / path)) in (* Create tree matching the original structure: borphan | b01 <- n01 <- n0 <- c0 @@ -50,39 +50,49 @@ let generate ~domain_mgr ~sw ~fs = borphan is orphan content that is added to the content store but NOT part of the tree. The tree only has step-n01/step-b01 -> "b01" *) - - let k_c0 = Store.Backend.Repo.batch rw (fun bstore nstore cstore -> - (* First, add the orphan content directly to the content store *) - let _ = Store.Backend.Contents.add bstore "borphan" in - - (* Add b01 content *) - let k_b01 = Store.Backend.Contents.add bstore "b01" in - - (* Create n01 node with step-b01 -> b01 *) - let n01 = Store.Backend.Node.Val.of_list [ ("step-b01", `Contents (k_b01, ())) ] [] in - let k_n01 = Store.Backend.Node.add nstore n01 in - - (* Create n0 (root) node with step-n01 -> n01 *) - let n0 = Store.Backend.Node.Val.of_list [ ("step-n01", `Node (k_n01, [])) ] [] in - let k_n0 = Store.Backend.Node.add nstore n0 in - - (* Create commit *) - let c0 = Store.Backend.Commit.Val.v ~parents:[] ~info ~node:k_n0 in - let k_c0 = Store.Backend.Commit.add cstore c0 in - - Printf.printf "Commit key type: %s\n" - (Irmin.Type.to_string Store.Backend.Commit.Key.t k_c0); - let hash = Store.Backend.Commit.Key.to_hash k_c0 in - Printf.printf "Commit hash (type): %s\n" - (Irmin.Type.to_string Store.Hash.t hash); - let hash_bytes = Irmin.Type.(unstage (to_bin_string Store.Hash.t)) hash in - let hex = - String.to_seq hash_bytes - |> Seq.map (fun c -> Printf.sprintf "%02x" (Char.code c)) - |> List.of_seq |> String.concat "" - in - Printf.printf "Commit hash (hex): %s\n" hex; - k_c0) in + let k_c0 = + Store.Backend.Repo.batch rw (fun bstore nstore cstore -> + (* First, add the orphan content directly to the content store *) + let _ = Store.Backend.Contents.add bstore "borphan" in + + (* Add b01 content *) + let k_b01 = Store.Backend.Contents.add bstore "b01" in + + (* Create n01 node with step-b01 -> b01 *) + let n01 = + Store.Backend.Node.Val.of_list + [ ("step-b01", `Contents (k_b01, ())) ] + [] + in + let k_n01 = Store.Backend.Node.add nstore n01 in + + (* Create n0 (root) node with step-n01 -> n01 *) + let n0 = + Store.Backend.Node.Val.of_list [ ("step-n01", `Node (k_n01, [])) ] [] + in + let k_n0 = Store.Backend.Node.add nstore n0 in + + (* Create commit *) + let c0 = Store.Backend.Commit.Val.v ~parents:[] ~info ~node:k_n0 in + let k_c0 = Store.Backend.Commit.add cstore c0 in + + Printf.printf "Commit key type: %s\n" + (Irmin.Type.to_string Store.Backend.Commit.Key.t k_c0); + let hash = Store.Backend.Commit.Key.to_hash k_c0 in + Printf.printf "Commit hash (type): %s\n" + (Irmin.Type.to_string Store.Hash.t hash); + let hash_bytes = + Irmin.Type.(unstage (to_bin_string Store.Hash.t)) hash + in + let hex = + String.to_seq hash_bytes + |> Seq.map (fun c -> Printf.sprintf "%02x" (Char.code c)) + |> List.of_seq + |> String.concat "" + in + Printf.printf "Commit hash (hex): %s\n" hex; + k_c0) + in (* Run GC with c0 as target to remove borphan *) Printf.printf "Running GC with c0 as target...\n"; File "test/irmin-pack/test_inline_contents.ml", line 1, characters 0-0: diff --git a/_build/default/test/irmin-pack/test_inline_contents.ml b/_build/default/test/irmin-pack/.formatted/test_inline_contents.ml index 006dab2..74e3711 100644 --- a/_build/default/test/irmin-pack/test_inline_contents.ml +++ b/_build/default/test/irmin-pack/.formatted/test_inline_contents.ml @@ -42,18 +42,22 @@ let config ~sw ~fs ?(readonly = false) ?(fresh = true) ~inline_contents root = let info = S.Info.empty -(** Test that data can be stored and retrieved correctly with inlining disabled *) +(** Test that data can be stored and retrieved correctly with inlining disabled +*) let test_without_inlining ~fs () = let root = root_no_inline ~fs in rm_dir root; Eio.Switch.run @@ fun sw -> let repo = - S.Repo.v (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:false root) + S.Repo.v + (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:false root) in (* Create a tree with small and large contents *) let tree = S.Tree.empty () in - let tree = S.Tree.add tree [ "small" ] "abc" in (* Small content, < 16 bytes *) - let tree = S.Tree.add tree [ "large" ] (String.make 100 'x') in (* Large content *) + let tree = S.Tree.add tree [ "small" ] "abc" in + (* Small content, < 16 bytes *) + let tree = S.Tree.add tree [ "large" ] (String.make 100 'x') in + (* Large content *) (* Create a commit *) let commit = S.Commit.v repo ~parents:[] ~info tree in let hash = S.Commit.hash commit in @@ -63,21 +67,28 @@ let test_without_inlining ~fs () = let small = S.Tree.find tree' [ "small" ] in let large = S.Tree.find tree' [ "large" ] in Alcotest.(check (option string)) "small content" (Some "abc") small; - Alcotest.(check (option string)) "large content" (Some (String.make 100 'x')) large; + Alcotest.(check (option string)) + "large content" + (Some (String.make 100 'x')) + large; S.Repo.close repo -(** Test that data can be stored and retrieved correctly with inlining enabled *) +(** Test that data can be stored and retrieved correctly with inlining enabled +*) let test_with_inlining ~fs () = let root = root_with_inline ~fs in rm_dir root; Eio.Switch.run @@ fun sw -> let repo = - S.Repo.v (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:true root) + S.Repo.v + (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:true root) in (* Create a tree with small and large contents *) let tree = S.Tree.empty () in - let tree = S.Tree.add tree [ "small" ] "abc" in (* Small content, < 16 bytes *) - let tree = S.Tree.add tree [ "large" ] (String.make 100 'x') in (* Large content *) + let tree = S.Tree.add tree [ "small" ] "abc" in + (* Small content, < 16 bytes *) + let tree = S.Tree.add tree [ "large" ] (String.make 100 'x') in + (* Large content *) (* Create a commit *) let commit = S.Commit.v repo ~parents:[] ~info tree in let hash = S.Commit.hash commit in @@ -87,10 +98,14 @@ let test_with_inlining ~fs () = let small = S.Tree.find tree' [ "small" ] in let large = S.Tree.find tree' [ "large" ] in Alcotest.(check (option string)) "small content" (Some "abc") small; - Alcotest.(check (option string)) "large content" (Some (String.make 100 'x')) large; + Alcotest.(check (option string)) + "large content" + (Some (String.make 100 'x')) + large; S.Repo.close repo -(** Test that the same data produces the same content hash regardless of inlining *) +(** Test that the same data produces the same content hash regardless of + inlining *) let test_content_equivalence ~fs () = let root_no_inline = root_equiv_no ~fs in let root_inline = root_equiv_yes ~fs in @@ -100,7 +115,8 @@ let test_content_equivalence ~fs () = (* Create store without inlining *) let repo1 = S.Repo.v - (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:false root_no_inline) + (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:false + root_no_inline) in let tree1 = S.Tree.empty () in let tree1 = S.Tree.add tree1 [ "a" ] "small" in @@ -111,7 +127,8 @@ let test_content_equivalence ~fs () = (* Create store with inlining *) let repo2 = S.Repo.v - (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:true root_inline) + (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:true + root_inline) in let tree2 = S.Tree.empty () in let tree2 = S.Tree.add tree2 [ "a" ] "small" in @@ -122,28 +139,49 @@ let test_content_equivalence ~fs () = (* Verify data is the same when read back *) let repo1 = S.Repo.v - (config ~sw ~fs ~readonly:true ~fresh:false ~inline_contents:false root_no_inline) + (config ~sw ~fs ~readonly:true ~fresh:false ~inline_contents:false + root_no_inline) in let repo2 = S.Repo.v - (config ~sw ~fs ~readonly:true ~fresh:false ~inline_contents:true root_inline) + (config ~sw ~fs ~readonly:true ~fresh:false ~inline_contents:true + root_inline) + in + let tree1' = + S.Commit.of_hash repo1 (S.Commit.hash commit1) + |> Option.get + |> S.Commit.tree + in + let tree2' = + S.Commit.of_hash repo2 (S.Commit.hash commit2) + |> Option.get + |> S.Commit.tree in - let tree1' = S.Commit.of_hash repo1 (S.Commit.hash commit1) |> Option.get |> S.Commit.tree in - let tree2' = S.Commit.of_hash repo2 (S.Commit.hash commit2) |> Option.get |> S.Commit.tree in (* Verify contents are identical *) - Alcotest.(check (option string)) "a" (S.Tree.find tree1' [ "a" ]) (S.Tree.find tree2' [ "a" ]); - Alcotest.(check (option string)) "b" (S.Tree.find tree1' [ "b" ]) (S.Tree.find tree2' [ "b" ]); - Alcotest.(check (option string)) "c/d" (S.Tree.find tree1' [ "c"; "d" ]) (S.Tree.find tree2' [ "c"; "d" ]); + Alcotest.(check (option string)) + "a" + (S.Tree.find tree1' [ "a" ]) + (S.Tree.find tree2' [ "a" ]); + Alcotest.(check (option string)) + "b" + (S.Tree.find tree1' [ "b" ]) + (S.Tree.find tree2' [ "b" ]); + Alcotest.(check (option string)) + "c/d" + (S.Tree.find tree1' [ "c"; "d" ]) + (S.Tree.find tree2' [ "c"; "d" ]); S.Repo.close repo1; S.Repo.close repo2 -(** Test that verifies small content is actually inlined in the node structure *) +(** Test that verifies small content is actually inlined in the node structure +*) let test_inlining_structure ~fs () = let root = Eio.Path.(fs / "_build" / "test-inline-structure") in rm_dir root; Eio.Switch.run @@ fun sw -> let repo = - S.Repo.v (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:true root) + S.Repo.v + (config ~sw ~fs ~readonly:false ~fresh:true ~inline_contents:true root) in (* Create a tree with small content that should be inlined *) let tree = S.Tree.empty () in @@ -151,10 +189,14 @@ let test_inlining_structure ~fs () = - 1-byte variant tag for the Contents.t encoding - 1-byte varint length prefix for the string So raw content must be < 14 bytes (13 or less) to be inlined. *) - let tree = S.Tree.add tree [ "tiny" ] "x" in (* 1 byte raw -> 3 bytes serialized -> inlined *) - let tree = S.Tree.add tree [ "small" ] "hello" in (* 5 bytes raw -> 7 bytes serialized -> inlined *) - let tree = S.Tree.add tree [ "medium" ] "0123456789abc" in (* 13 bytes raw -> 15 bytes serialized -> inlined *) - let tree = S.Tree.add tree [ "large" ] "0123456789abcd" in (* 14 bytes raw -> 16 bytes serialized -> NOT inlined *) + let tree = S.Tree.add tree [ "tiny" ] "x" in + (* 1 byte raw -> 3 bytes serialized -> inlined *) + let tree = S.Tree.add tree [ "small" ] "hello" in + (* 5 bytes raw -> 7 bytes serialized -> inlined *) + let tree = S.Tree.add tree [ "medium" ] "0123456789abc" in + (* 13 bytes raw -> 15 bytes serialized -> inlined *) + let tree = S.Tree.add tree [ "large" ] "0123456789abcd" in + (* 14 bytes raw -> 16 bytes serialized -> NOT inlined *) (* Commit to persist the tree *) let commit = S.Commit.v repo ~parents:[] ~info tree in let _hash = S.Commit.hash commit in @@ -162,7 +204,8 @@ let test_inlining_structure ~fs () = let commit' = S.Commit.of_hash repo (S.Commit.hash commit) |> Option.get in let tree' = S.Commit.tree commit' in (* Get the root node using to_backend_node *) - let root_node = match S.Tree.destruct tree' with + let root_node = + match S.Tree.destruct tree' with | `Node (n, _inlined) -> S.to_backend_node n | `Contents _ | `Contents_inlined_3 _ -> Alcotest.fail "Expected a node" in @@ -171,17 +214,17 @@ let test_inlining_structure ~fs () = (* Count inlined vs non-inlined contents *) let inlined_count = ref 0 in let non_inlined_count = ref 0 in - List.iter (fun (step, value) -> - match value with - | `Contents_inlined (bytes, _) -> - [%log.debug "Inlined content at %s: %S" step bytes]; - incr inlined_count - | `Contents _ -> - [%log.debug "Non-inlined content at %s" step]; - incr non_inlined_count - | `Node _ -> - [%log.debug "Node at %s" step] - ) entries; + List.iter + (fun (step, value) -> + match value with + | `Contents_inlined (bytes, _) -> + [%log.debug "Inlined content at %s: %S" step bytes]; + incr inlined_count + | `Contents _ -> + [%log.debug "Non-inlined content at %s" step]; + incr non_inlined_count + | `Node _ -> [%log.debug "Node at %s" step]) + entries; (* Verify: 3 entries should be inlined (tiny, small, medium), 1 should not (large) *) Alcotest.(check int) "inlined count" 3 !inlined_count; Alcotest.(check int) "non-inlined count" 1 !non_inlined_count; File "test/irmin-pack/test_existing_stores.ml", line 1, characters 0-0: diff --git a/_build/default/test/irmin-pack/test_existing_stores.ml b/_build/default/test/irmin-pack/.formatted/test_existing_stores.ml index 00d49c3..a3519b5 100644 --- a/_build/default/test/irmin-pack/test_existing_stores.ml +++ b/_build/default/test/irmin-pack/.formatted/test_existing_stores.ml @@ -356,9 +356,9 @@ end (** Test that verifies mixed V2/V3 inode entries in a pack file. - This test opens an existing store with V2 inodes, adds new entries - (which will be V3), and verifies that both V2 and V3 entries coexist - and can be read correctly. + This test opens an existing store with V2 inodes, adds new entries (which + will be V3), and verifies that both V2 and V3 entries coexist and can be + read correctly. We use version_2_to_3_always store because it uses always indexing strategy which indexes inodes (unlike minimal strategy used by version_3_minimal). *) @@ -422,8 +422,7 @@ module Test_mixed_v2_v3 = struct (* The archived store should have V2 inodes (created before V3 introduction) *) Alcotest.(check bool) - "Initial store should have V2 inodes" - (initial_v2 > 0) true; + "Initial store should have V2 inodes" (initial_v2 > 0) true; (* Add new content - this will create V3 inodes *) let tree = S.Commit.tree commit in @@ -450,8 +449,7 @@ module Test_mixed_v2_v3 = struct "Should still have V2 inodes (old entries preserved)" (final_v2 >= initial_v2) true; Alcotest.(check bool) - "Should have new V3 inodes (from new writes)" - (final_v3 > initial_v3) true; + "Should have new V3 inodes (from new writes)" (final_v3 > initial_v3) true; (* Verify we can still read the original commit via its hash *) let repo = S.Repo.v conf in @@ -464,7 +462,7 @@ module Test_mixed_v2_v3 = struct [%log.app "Mixed V2/V3 test passed: V2=%d V3=%d inodes coexist and are readable" - final_v2 final_v3] + final_v2 final_v3] end let tests ~fs ~domain_mgr = File "src/irmin-cli/cli.ml", line 1, characters 0-0: diff --git a/_build/default/src/irmin-cli/cli.ml b/_build/default/src/irmin-cli/.formatted/cli.ml index 9554405..c4a6438 100644 --- a/_build/default/src/irmin-cli/cli.ml +++ b/_build/default/src/irmin-cli/.formatted/cli.ml @@ -177,7 +177,8 @@ let list ~env = let pp_step = Irmin.Type.pp S.Path.step_t in let pp ppf (s, k) = match S.Tree.destruct k with - | `Contents _ | `Contents_inlined_3 _ -> Fmt.pf ppf "FILE %a" pp_step s + | `Contents _ | `Contents_inlined_3 _ -> + Fmt.pf ppf "FILE %a" pp_step s | `Node _ -> Fmt.pf ppf "DIR %a" pp_step s in List.iter (print "%a" pp) paths File "dune", line 1, characters 0-0: diff --git a/_build/default/dune b/_build/default/.formatted/dune index ed29bf8..34f5fc8 100644 --- a/_build/default/dune +++ b/_build/default/.formatted/dune @@ -8,5 +8,12 @@ (files README.md) (package irmin-cli) (deps %{bin:irmin}) - (libraries irmin irmin-cli irmin-git irmin-git.unix eio eio_main eio.unix + (libraries + irmin + irmin-cli + irmin-git + irmin-git.unix + eio + eio_main + eio.unix lwt_eio)) File "src/irmin/tree.ml", line 1, characters 0-0: diff --git a/_build/default/src/irmin/tree.ml b/_build/default/src/irmin/.formatted/tree.ml index efccfa8..544d412 100644 --- a/_build/default/src/irmin/tree.ml +++ b/_build/default/src/irmin/.formatted/tree.ml @@ -2022,7 +2022,7 @@ module Make (P : Backend.S) = struct let of_contents ?(metadata = Metadata.default) c = let env = Env.empty () in let c = Contents.of_value ~env c in - if !inline_contents_enabled then ( + if !inline_contents_enabled then let len = match Repr.Size.of_value Contents.t with | Dynamic f -> f c @@ -2031,7 +2031,7 @@ module Make (P : Backend.S) = struct in (* Inline small contents (< 16 bytes) when inlining is enabled *) if len > 0 && len < 16 then `Contents_inlined_3 (c, metadata) - else `Contents (c, metadata)) + else `Contents (c, metadata) else `Contents (c, metadata) let of_contents_inlined ?(metadata = Metadata.default) c = @@ -2504,7 +2504,9 @@ module Make (P : Backend.S) = struct | `Contents_inlined_3 (c, m) -> (* Inline small contents: serialize to bytes and embed directly *) let v = Contents.force_exn c in - let to_bin = Type.(unstage (to_bin_string P.Contents.Val.t)) in + let to_bin = + Type.(unstage (to_bin_string P.Contents.Val.t)) + in let bytes = to_bin v in Some (step, `Contents_inlined (bytes, m)) | `Contents (c, m) -> ( File "src/irmin-pack-tools/tezos_explorer/show.ml", line 1, characters 0-0: diff --git a/_build/default/src/irmin-pack-tools/tezos_explorer/show.ml b/_build/default/src/irmin-pack-tools/tezos_explorer/.formatted/show.ml index 186b71a..c85f91b 100644 --- a/_build/default/src/irmin-pack-tools/tezos_explorer/show.ml +++ b/_build/default/src/irmin-pack-tools/tezos_explorer/.formatted/show.ml @@ -595,8 +595,10 @@ let show_inode c (inode : Files.Inode.compress) = | Contents_inlined_value (n, bytes, ()) -> let img1 = string A.(fg lightred ++ st bold) "Contents (inlined):" in let img2 = name n in - let content = strf ~attr:A.(fg lightwhite) "%d bytes" (String.length bytes) in - ( img1 <-> (void 2 0 <|> (img2 <-> content)), [] ) + let content = + strf ~attr:A.(fg lightwhite) "%d bytes" (String.length bytes) + in + (img1 <-> (void 2 0 <|> (img2 <-> content)), []) | Node (n, addr) -> let node, node_button = addr_show addr in let img1 = string A.(fg lightred ++ st bold) "Node:" in dune build @fmt failed "/usr/bin/env" "bash" "-c" "opam exec -- dune build @fmt --ignore-promoted-rules || (echo "dune build @fmt failed"; exit 2)" failed with exit status 2 2026-01-21 17:10.21: Job failed: Failed: Build failed