Persistent store with Git semantics: lazy reads, delayed writes, content-addressing

bottler: simplify config, add parallel uploads, fix hyphenated names

- Simplify homebrew.yml: use `target` path instead of package/exe_name
- Rename prune to pruner (avoid conflict with graphviz)
- Add parallel uploads with rclone --transfers 16
- Fix hyphenated name parsing (git-mono was parsed as "git")
- Add timing output for build/upload/tap update steps
- Add dry-run command to preview build targets

+16 -15
+1 -1
bin/cmd_export.ml
··· 15 15 1 16 16 | Config.Git -> ( 17 17 (* Export as bundle or tar - for now just list what would be exported *) 18 - let git_dir = snd Eio.Path.(fs / config.store_path / ".git") in 18 + let git_dir = Fpath.(v config.store_path / ".git") in 19 19 let store = Irmin.Git_interop.import_git ~sw ~fs ~git_dir in 20 20 match Irmin.Store.Git.checkout store ~branch with 21 21 | None ->
+1 -1
bin/cmd_info.ml
··· 40 40 Fmt.pr "Branch: %s@." config.default_branch; 41 41 match config.backend with 42 42 | Config.Git -> 43 - let git_dir = snd Eio.Path.(fs / config.store_path / ".git") in 43 + let git_dir = Fpath.(v config.store_path / ".git") in 44 44 let store = Irmin.Git_interop.import_git ~sw ~fs ~git_dir in 45 45 let branches = Irmin.Store.Git.branches store in 46 46 Fmt.pr "Branches: %d@." (List.length branches);
+1 -1
bin/cmd_init.ml
··· 6 6 Eio_main.run @@ fun env -> 7 7 let fs = Eio.Stdenv.cwd env in 8 8 Eio.Switch.run @@ fun sw -> 9 - let path' = snd Eio.Path.(fs / path) in 9 + let path' = Fpath.v path in 10 10 match backend with 11 11 | `Git -> 12 12 let _store = Git_interop.init_git ~sw ~fs ~path:path' in
+1 -1
bin/common.ml
··· 62 62 type hash = Hash.sha1 63 63 64 64 let open_store ~sw ~fs ~config = 65 - let git_dir = snd Eio.Path.(fs / config.Config.store_path / ".git") in 65 + let git_dir = Fpath.(v config.Config.store_path / ".git") in 66 66 Git_interop.import_git ~sw ~fs ~git_dir 67 67 68 68 let checkout store ~branch = Store.Git.checkout store ~branch
+3 -3
lib/codec.ml
··· 111 111 let user_of_string s = 112 112 (* Parse "Name <email>" format *) 113 113 match String.index_opt s '<' with 114 - | None -> Git.User.make ~name:s ~email:"" ~date:timestamp () 114 + | None -> Git.User.v ~name:s ~email:"" ~date:timestamp () 115 115 | Some i -> 116 116 let name = String.trim (String.sub s 0 i) in 117 117 let rest = String.sub s (i + 1) (String.length s - i - 1) in ··· 120 120 | None -> rest 121 121 | Some j -> String.sub rest 0 j 122 122 in 123 - Git.User.make ~name ~email ~date:timestamp () 123 + Git.User.v ~name ~email ~date:timestamp () 124 124 in 125 - Git.Commit.make ~tree:(git_hash_of_sha1 tree) 125 + Git.Commit.v ~tree:(git_hash_of_sha1 tree) 126 126 ~parents:(List.map git_hash_of_sha1 parents) 127 127 ~author:(user_of_string author) ~committer:(user_of_string committer) 128 128 (Some message)
+8 -8
lib/git_interop.mli
··· 9 9 val import_git : 10 10 sw:Eio.Switch.t -> 11 11 fs:Eio.Fs.dir_ty Eio.Path.t -> 12 - git_dir:string -> 12 + git_dir:Fpath.t -> 13 13 Store.Git.t 14 14 (** [import_git ~sw ~fs ~git_dir] opens a bare .git directory as an Irmin store. 15 15 Supports both loose objects and pack files. *) 16 16 17 17 val open_git : 18 - sw:Eio.Switch.t -> fs:Eio.Fs.dir_ty Eio.Path.t -> path:string -> Store.Git.t 18 + sw:Eio.Switch.t -> fs:Eio.Fs.dir_ty Eio.Path.t -> path:Fpath.t -> Store.Git.t 19 19 (** [open_git ~sw ~fs ~path] opens a Git repository (with .git subdirectory) as 20 20 an Irmin store. Supports both loose objects and pack files. *) 21 21 22 22 val init_git : 23 - sw:Eio.Switch.t -> fs:Eio.Fs.dir_ty Eio.Path.t -> path:string -> Store.Git.t 23 + sw:Eio.Switch.t -> fs:Eio.Fs.dir_ty Eio.Path.t -> path:Fpath.t -> Store.Git.t 24 24 (** [init_git ~sw ~fs ~path] initializes a new Git repository at [path] and 25 25 returns an Irmin store for it. *) 26 26 ··· 29 29 val read_object : 30 30 sw:Eio.Switch.t -> 31 31 fs:Eio.Fs.dir_ty Eio.Path.t -> 32 - git_dir:string -> 32 + git_dir:Fpath.t -> 33 33 Hash.sha1 -> 34 34 (string * string, [> `Msg of string ]) result 35 35 (** [read_object ~sw ~fs ~git_dir hash] reads a Git object, returning ··· 39 39 val write_object : 40 40 sw:Eio.Switch.t -> 41 41 fs:Eio.Fs.dir_ty Eio.Path.t -> 42 - git_dir:string -> 42 + git_dir:Fpath.t -> 43 43 typ:string -> 44 44 string -> 45 45 Hash.sha1 ··· 51 51 val read_ref : 52 52 sw:Eio.Switch.t -> 53 53 fs:Eio.Fs.dir_ty Eio.Path.t -> 54 - git_dir:string -> 54 + git_dir:Fpath.t -> 55 55 string -> 56 56 Hash.sha1 option 57 57 (** [read_ref ~sw ~fs ~git_dir name] reads a Git reference. Follows symbolic ··· 60 60 val write_ref : 61 61 sw:Eio.Switch.t -> 62 62 fs:Eio.Fs.dir_ty Eio.Path.t -> 63 - git_dir:string -> 63 + git_dir:Fpath.t -> 64 64 string -> 65 65 Hash.sha1 -> 66 66 unit ··· 69 69 val list_refs : 70 70 sw:Eio.Switch.t -> 71 71 fs:Eio.Fs.dir_ty Eio.Path.t -> 72 - git_dir:string -> 72 + git_dir:Fpath.t -> 73 73 string list 74 74 (** [list_refs ~sw ~fs ~git_dir] lists all references. *)
+1
test/mst_proof.mli
··· 1 + (* empty *)