commits
Remove genuinely stale deps (merlin, duration, digestif, eio_main,
dune-configurator, printbox, printbox-text, tls-eio, ocamlformat,
bytesrw-eio) and add missing library declarations to dune files
(eio+logs in ocaml-oci/src, logs in ocaml-git/lib+bin).
Keep js_of_ocaml in space-ground (needed for modes js) and add it
to implicit_deps in lint since it's a compiler, not a library.
commit_pending was calling add_all on the monorepo (300k files including
_build/ and _opam/), causing push to hang. The monorepo is already
committed by the user, so skip it entirely. Also add .gitignore parsing
to add_all so ignored directories are never traversed, and only run
verify_cache on cache hits to avoid scanning 361k entries on every split.
- Replace full cache clear with selective removal of bad entries, so
valid split commits are preserved and the chain stays connected to
checkout history
- Clean untracked files in checkouts before pushing to prevent
"working tree file would be overwritten" errors with updateInstead
Subtree split produced orphaned commits (no parents) when the monorepo
history contained "gap" commits — commits with empty trees or only a
single subtree's content. These break the parent chain for all other
prefixes, causing non-fast-forward push failures for every package.
- Add find_ancestor_split to walk backward through ancestors and find
the nearest cached non-null split, bridging over gap commits
- Add parent-consistency check to verify_cache: detect orphaned splits
where the split has no parents but the original has reachable ancestors
- Move verify_cache before split and call it on every split, so the
cache self-heals without requiring external callers to verify first
- Remove duplicate verify+clear from monopam push (now handled by split)
- Add opam-repo cleaning to monopam clean
Add a unit test that catches the duplicate-entry bug (add same name twice
should replace, not accumulate). Add a Crowbar model-based fuzz suite that
applies random Add/Remove sequences to both Git.Tree.t and a Map reference,
checking no-duplicates, sorted-order, and model-agreement invariants after
every step. The roundtrip-after-ops test also exercises serialization across
arbitrary op sequences.
Tree.add was prepending the new entry without removing any existing
entry with the same name. Every re-write of a blob (e.g. approving a
timesheet writes it twice: initial write + approve) therefore doubled
the entry in the git tree object, leading to 2x inflated counts when
iterating the tree.
Fix: filter out existing same-name entries before prepending.
- common.ml: replace Mst_tree + per-backend modules with Mst_store functor;
all backends now use module S = Store.Git/Store.Mst so ops are S.*
- config: add Disk backend (append-only WAL); single canonical name per backend
- git_interop: skip write if object exists; fix blob/tree detection with try-parse
- pds_interop: add mst_backend bridging Pds.t to Backend.t
- irmin.ml: add Git.open_/init/import and Mst.of_pds/disk/memory builders
- ocaml-git/repository: mkdirs instead of mkdir in init (handles nested paths)
- cmd_info/export: use Git.open_ instead of import_git ~git_dir
Rename make_superblock → superblock, make_inode_buf → inode_buf,
make_image → image, make_key → key in squashfs and streaming-aead.
Rename create/make to v in rpmsg, error, proxy, auth, version, and
other modules. Fix doc style issues in error.mli, requests.mli, and
expect_continue.mli. Update all callers.
Delete fuzz_common.ml from ocaml-git and ocaml-merlin (inline trivial
truncate helper). Merge openamp firmware/remoteproc into single suite.
Add test_pds_interop.mli for E600.
Standardize fuzz and test conventions across 30+ packages:
- E715/E718: Add fuzz.ml runners referencing Fuzz_*.suite instead of
calling Fuzz_*.run() directly; update dune files accordingly
- E725: Fix fuzz_paseto suite name from "crowbar" to "paseto"
- E600: Create .mli interfaces for test modules (test_firmware,
test_remoteproc, test_pbkdf2, test_paseto) with single-group suites
- E605: Add missing test files (test_skills, test_monitor, test_openamp,
test_xrpc_server) with proper module extraction from inline test.ml
- E415: Add pp pretty-printer to xrpc_server type t
- E405: Add doc comment for pp_sync_action in skills.mli
- E205: Replace Printf with Fmt in fuzz_paseto and gen_corpus
- E331: Rename make_key to key in fuzz_paseto
- Change `run` signature to `string -> (string * test_case list) list -> unit`
matching Alcotest's grouping convention
- Fix `_name` bug: pass the name through to Alcotest.run_with_args
- Each fuzz module now exports `let suite = ("name", [test_case ...])`
- Entry points (fuzz.ml) collect suites: `Crowbar.run "pkg" [Fuzz_X.suite]`
- Remove stale `add_test`/`suite` API, keep only `test_case`/`run`
- Remove `let run () = ()` from fuzz_common.ml files
- Update merlint E725 rule to match new `let suite = ("name", ...)` pattern
- Update E725 test fixtures and expected output
- Restore cursor on exit via at_exit in Tty.Progress (fixes TTY corruption)
- Install SIGINT handler in monopam test for clean Ctrl-C
- Add 2s per-iteration timeout and 2s total budget to crowbar
- Group crowbar alcotest output by module prefix ("mdns: foo" → group "mdns")
- Skip fuzz runtest in afl context (enabled_if <> profile afl)
- Add merlint E725: enforce "module: description" fuzz test name convention
Extract subtree_dirs, opam_package_names, generate_dune_project helpers
from update_root_deps (E005). Replace catch-all exception handlers with
specific Eio.Io _ (E105). Add err_prefix_not_found helper (E340).
Fix three bugs in `monopam add`:
1. Use checkout_prefix instead of full checkout after subtree add, so only
the new subtree's files are materialized — avoiding permission crashes
on other subtrees' files.
2. Stage and commit sources.toml after writing it, using ocaml-git with a
fallback monopam user when git config is not set.
3. After a successful add, scan all subtrees for .opam dependencies and
update dune-project with the external deps, staged and committed via
ocaml-git.
Add (enabled_if (= %{profile} afl)), (source_tree corpus), and
gen_corpus.exe deps to all 25 fuzz directories
Replace Printf.fprintf with Fmt.pf in test_pack.ml and add missing
documentation for public values in test_helpers.mli.
Fmt.pf expects a Format.formatter, not an out_channel.
Rename module to match the library name, removing need for
(wrapped false). Update all 12 test files to use Test_helpers.
Move test_common to test/helpers/ as a private unwrapped library
(test_helpers) to fix E606 wrong-directory warning. Replace
fail(Fmt.str) with failf in delegation and git test files.
Replace Printf/Format with Fmt across bench, test, and bin files.
Extract err_* helpers in gpt.ml for consistent error patterns.
E718: Add gen_corpus.ml to ocaml-crypto, ocaml-csrf, ocaml-git,
ocaml-github-oauth, ocaml-gpt
E724: Add (rule (alias runtest) ...) for property-based testing
Adds interface file for test_common helper module exposing hash
testable, with_temp_repo, and commit utilities.
- E618 rule: allow filenames matching the test stanza name (fixes false
positives for fuzz_*.ml runners, tests.ml, *_test.ml stanza runners)
- Rename ocaml-git/test/common.ml -> test_common.ml and update all
references from Common to Test_common
ahead_behind in ocaml-git returned {ahead=0; behind=0} when the remote
ref didn't exist, making never-pushed repos appear fully synced. Now
returns None, and status shows these as "remote:new" so push correctly
identifies them as needing upstream push.
- E330: rename redundant module-prefixed functions (Calls.calls -> list_all,
Downloads.downloads -> list_all, Hash.hash -> v, Tag.tag -> name)
- E331: remove redundant get_/find_/make_ prefixes across freebox and hap
- E005: extract helpers from long functions in gpt.ml (validate_inputs,
prepare_partitions) and hap.ml (build_m5, verify_m6, srp_verify,
build_verify_m3, derive_session_keys, verify_m2)
E325 naming convention:
- freebox: find_correlated → correlated (returns list, not option)
- git: Config.get → Config.find (returns string option)
- hap: get_accessory_info → find_accessory_info, get_bool_value → find_bool_value
E330 redundant module prefix:
- freebox: auth_result → result, wifi_config → config
- git: Diff.diff_trees → trees, diff_commits → commits,
diff_tree_to_empty → tree_to_empty, diff_empty_to_tree → empty_to_tree,
Pack_index.pack_index_magic → magic, Remote.remote_head → head,
remote_matches_local → matches_local, Worktree.worktree_name → name
- hap: hap_request → request
E340 error patterns: crow/bin/main.ml err_* helpers
E300 variant naming: conpool AllPresets → All_presets, ListPresets → List_presets
E405 missing docs: freebox, hap, git, gpt .mli files
- E410: fix doc style for of_string_exn, v, inflate, bool_codec,
access_token_url and 5 repository.mli @param missing periods
- E415: add pp to Config, Index, Repository types
- E510: add Logs source to Subtree module
- E331 auto-fixes: Config rename get_all→all, get_bool→bool,
get_int→int, find_sections→sections, get_remotes→remotes,
get_remote→remote, get_branches→branches, get_user→user;
cascading updates in repository, tests, fuzz, monopam, precommit
- Auto-fixes in freebox, gpt, hap
Modernize the memtrace package for the monorepo: convert Printf to Fmt,
restructure tests into alcotest pattern with suite exports, add cmdliner
term (--memtrace, --memtrace-rate, --memtrace-context), and add
argv-peeking trace_if_requested. Integrate Memtrace.term into setup
terms across all binaries that previously called trace_if_requested().
- License -> Licence
- color -> colour (in prose, not API/code)
- behavior -> behaviour
- analyze -> analyse
- organized -> organised
- Remove marketing buzzwords (leveraging)
- Remove emojis from prose
An empty repo (no HEAD) has no uncommitted changes - it just has no
commits yet. Returning false allows monopam to push to newly created
empty checkouts.
Convert all packages from:
(source (uri https://tangled.org/handle/repo))
to:
(source (tangled handle/repo))
This uses dune 3.21's native tangled support for cleaner source
declarations. Also removes redundant homepage/bug_reports fields
that are auto-generated from tangled sources.
- Add Subtree.check_mono and fix_mono to detect/remove empty commits
- Add `monopam clean` command with --dry-run and --force options
- Clean removes empty commits from mono and unrelated merges from checkouts
- Add show_patch: generates unified diffs with stat summary
- Add cherry_pick: applies commit changes and creates new commit
- Add merge: fast-forward only merge implementation
- Update monopam callers to use Git.Repository functions
- Remove ported functions from Git_cli
- Clean up unused mainline hash code in subtree.ml
- Update fork_join.ml and monopam.ml to use Git.Repository
- Remove add_all, commit, rm from Git_cli
- Add 14 tests for add_all, commit, rm
- Simplify test code using unwrap helper
Add high-level commit function that reads author from git config,
and rm function for removing files from index and working tree.
Includes comprehensive tests for both functions.
- Add tests for tree_hash_at_path: root, subdir, not_found
- Add tests for subtree_last_upstream_commit: squash, add, not_found
- Add tests for has_subtree_history: true, false
- Add Changes.week_timestamps_of_ptime and day_timestamps_of_ptime
- Use Ptime directly for date filtering instead of string parsing
- Add log_filtered function for filtering commits by since/until timestamps
and by path (commits that touch specific files/directories)
- Add commit_touches_path helper for path-based filtering
- Rename test_git.ml to test.ml (merlint convention)
- Simplify test/dune to auto-discover modules
- Port Git_cli.log to use ocaml-git internally instead of git CLI
- Add comprehensive tests for log_filtered
- Add 4 tests for resolve_ref (HEAD, branch, remote, not_found)
- Add 3 tests for log_range_refs (basic, HEAD, error)
- Add resolve_ref to handle various ref formats (HEAD, origin/main, etc.)
- Add log_range_refs that resolves ref names before calling log_range
- Make Git_cli.log_entry a type alias for Git.Repository.log_entry
- Update monopam to use Git.Repository.log_range_refs instead of Git_cli.log_range
- Remove ~proc parameter from doctor.ml analyze_remote and analyze_checkout_remotes
- Remove log_range from Git_cli (no longer used)
- Add subtree_last_upstream_commit and has_subtree_history to Repository
- These functions search commit history for subtree merge/squash messages
- Update monopam cross_status.ml to use Git.Repository.subtree_last_upstream_commit
- Update monopam fork_join.ml to use Git.Repository.has_subtree_history
- Remove ~proc parameter from cross_status.compute (no longer needs CLI)
- Remove subtree_last_upstream_commit and has_subtree_history from Git_cli
Split the monolithic 2600+ line test file into modular test files:
- test_common.ml: shared helpers (with_temp_repo, make_commit, hash)
- test_hash.ml, test_blob.ml, test_user.ml, test_tree.ml
- test_commit.ml, test_tag.ml, test_value.ml, test_reference.ml
- test_pack.ml (includes Pack_index tests)
- test_config.ml, test_index.ml, test_repository.ml
- test_subtree.ml, test_worktree.ml
Also exports Worktree and Diff modules from the Git library.
Add new functions to Repository module:
- rename_branch: rename current branch
- is_ancestor: check if commit is ancestor of another
- count_commits_between: count commits between two refs
- merge_base: find common ancestor of two commits
- set_push_url: set push URL for a remote
These replace equivalent Git CLI operations in monopam.
The `sync` function is no longer exported. The `pull` command now uses
`Monopam.pull` directly instead of calling sync with skip_push=true.
This simplifies the API to just pull and push.
Add commands to detect and remove unrelated subtree merge commits from
split histories. These commits have git-subtree-dir metadata for a
different package and pollute checkout histories.
- check: scans history and reports unrelated merge commits
- fix: rewrites history, skipping commits where git-subtree-dir doesn't
match prefix and tree is unchanged from first parent
Also refactors split to only include mainline parent for relevant
subtree merges (where git-subtree-dir matches prefix).
- Rename directory: ocaml-build-info -> monopam-info
- Rename module: Mono_info -> Monopam_info
- Rename package: ocaml-build-info -> monopam-info
- Update all consumers to use new module name
- Remove "Skipping pull" log noise from push output
When a push to checkout fails with non-fast-forward error:
1. Verify the subtree cache
2. If invalid, clear it and re-split
3. Retry the push
This handles stale caches transparently without user intervention.
Rename ocaml-version to ocaml-build-info with Mono_info module.
All homebrew binaries now use Mono_info.version for consistent
version reporting across the monorepo.
The library wraps dune-build-info and falls back to git hash
in dev mode. Can be extended with SBOM or other metadata later.
Remove genuinely stale deps (merlin, duration, digestif, eio_main,
dune-configurator, printbox, printbox-text, tls-eio, ocamlformat,
bytesrw-eio) and add missing library declarations to dune files
(eio+logs in ocaml-oci/src, logs in ocaml-git/lib+bin).
Keep js_of_ocaml in space-ground (needed for modes js) and add it
to implicit_deps in lint since it's a compiler, not a library.
commit_pending was calling add_all on the monorepo (300k files including
_build/ and _opam/), causing push to hang. The monorepo is already
committed by the user, so skip it entirely. Also add .gitignore parsing
to add_all so ignored directories are never traversed, and only run
verify_cache on cache hits to avoid scanning 361k entries on every split.
Subtree split produced orphaned commits (no parents) when the monorepo
history contained "gap" commits — commits with empty trees or only a
single subtree's content. These break the parent chain for all other
prefixes, causing non-fast-forward push failures for every package.
- Add find_ancestor_split to walk backward through ancestors and find
the nearest cached non-null split, bridging over gap commits
- Add parent-consistency check to verify_cache: detect orphaned splits
where the split has no parents but the original has reachable ancestors
- Move verify_cache before split and call it on every split, so the
cache self-heals without requiring external callers to verify first
- Remove duplicate verify+clear from monopam push (now handled by split)
- Add opam-repo cleaning to monopam clean
Add a unit test that catches the duplicate-entry bug (add same name twice
should replace, not accumulate). Add a Crowbar model-based fuzz suite that
applies random Add/Remove sequences to both Git.Tree.t and a Map reference,
checking no-duplicates, sorted-order, and model-agreement invariants after
every step. The roundtrip-after-ops test also exercises serialization across
arbitrary op sequences.
Tree.add was prepending the new entry without removing any existing
entry with the same name. Every re-write of a blob (e.g. approving a
timesheet writes it twice: initial write + approve) therefore doubled
the entry in the git tree object, leading to 2x inflated counts when
iterating the tree.
Fix: filter out existing same-name entries before prepending.
- common.ml: replace Mst_tree + per-backend modules with Mst_store functor;
all backends now use module S = Store.Git/Store.Mst so ops are S.*
- config: add Disk backend (append-only WAL); single canonical name per backend
- git_interop: skip write if object exists; fix blob/tree detection with try-parse
- pds_interop: add mst_backend bridging Pds.t to Backend.t
- irmin.ml: add Git.open_/init/import and Mst.of_pds/disk/memory builders
- ocaml-git/repository: mkdirs instead of mkdir in init (handles nested paths)
- cmd_info/export: use Git.open_ instead of import_git ~git_dir
Standardize fuzz and test conventions across 30+ packages:
- E715/E718: Add fuzz.ml runners referencing Fuzz_*.suite instead of
calling Fuzz_*.run() directly; update dune files accordingly
- E725: Fix fuzz_paseto suite name from "crowbar" to "paseto"
- E600: Create .mli interfaces for test modules (test_firmware,
test_remoteproc, test_pbkdf2, test_paseto) with single-group suites
- E605: Add missing test files (test_skills, test_monitor, test_openamp,
test_xrpc_server) with proper module extraction from inline test.ml
- E415: Add pp pretty-printer to xrpc_server type t
- E405: Add doc comment for pp_sync_action in skills.mli
- E205: Replace Printf with Fmt in fuzz_paseto and gen_corpus
- E331: Rename make_key to key in fuzz_paseto
- Change `run` signature to `string -> (string * test_case list) list -> unit`
matching Alcotest's grouping convention
- Fix `_name` bug: pass the name through to Alcotest.run_with_args
- Each fuzz module now exports `let suite = ("name", [test_case ...])`
- Entry points (fuzz.ml) collect suites: `Crowbar.run "pkg" [Fuzz_X.suite]`
- Remove stale `add_test`/`suite` API, keep only `test_case`/`run`
- Remove `let run () = ()` from fuzz_common.ml files
- Update merlint E725 rule to match new `let suite = ("name", ...)` pattern
- Update E725 test fixtures and expected output
- Restore cursor on exit via at_exit in Tty.Progress (fixes TTY corruption)
- Install SIGINT handler in monopam test for clean Ctrl-C
- Add 2s per-iteration timeout and 2s total budget to crowbar
- Group crowbar alcotest output by module prefix ("mdns: foo" → group "mdns")
- Skip fuzz runtest in afl context (enabled_if <> profile afl)
- Add merlint E725: enforce "module: description" fuzz test name convention
Fix three bugs in `monopam add`:
1. Use checkout_prefix instead of full checkout after subtree add, so only
the new subtree's files are materialized — avoiding permission crashes
on other subtrees' files.
2. Stage and commit sources.toml after writing it, using ocaml-git with a
fallback monopam user when git config is not set.
3. After a successful add, scan all subtrees for .opam dependencies and
update dune-project with the external deps, staged and committed via
ocaml-git.
- E330: rename redundant module-prefixed functions (Calls.calls -> list_all,
Downloads.downloads -> list_all, Hash.hash -> v, Tag.tag -> name)
- E331: remove redundant get_/find_/make_ prefixes across freebox and hap
- E005: extract helpers from long functions in gpt.ml (validate_inputs,
prepare_partitions) and hap.ml (build_m5, verify_m6, srp_verify,
build_verify_m3, derive_session_keys, verify_m2)
E325 naming convention:
- freebox: find_correlated → correlated (returns list, not option)
- git: Config.get → Config.find (returns string option)
- hap: get_accessory_info → find_accessory_info, get_bool_value → find_bool_value
E330 redundant module prefix:
- freebox: auth_result → result, wifi_config → config
- git: Diff.diff_trees → trees, diff_commits → commits,
diff_tree_to_empty → tree_to_empty, diff_empty_to_tree → empty_to_tree,
Pack_index.pack_index_magic → magic, Remote.remote_head → head,
remote_matches_local → matches_local, Worktree.worktree_name → name
- hap: hap_request → request
E340 error patterns: crow/bin/main.ml err_* helpers
E300 variant naming: conpool AllPresets → All_presets, ListPresets → List_presets
E405 missing docs: freebox, hap, git, gpt .mli files
- E410: fix doc style for of_string_exn, v, inflate, bool_codec,
access_token_url and 5 repository.mli @param missing periods
- E415: add pp to Config, Index, Repository types
- E510: add Logs source to Subtree module
- E331 auto-fixes: Config rename get_all→all, get_bool→bool,
get_int→int, find_sections→sections, get_remotes→remotes,
get_remote→remote, get_branches→branches, get_user→user;
cascading updates in repository, tests, fuzz, monopam, precommit
- Auto-fixes in freebox, gpt, hap
Modernize the memtrace package for the monorepo: convert Printf to Fmt,
restructure tests into alcotest pattern with suite exports, add cmdliner
term (--memtrace, --memtrace-rate, --memtrace-context), and add
argv-peeking trace_if_requested. Integrate Memtrace.term into setup
terms across all binaries that previously called trace_if_requested().
- Add show_patch: generates unified diffs with stat summary
- Add cherry_pick: applies commit changes and creates new commit
- Add merge: fast-forward only merge implementation
- Update monopam callers to use Git.Repository functions
- Remove ported functions from Git_cli
- Clean up unused mainline hash code in subtree.ml
- Add tests for tree_hash_at_path: root, subdir, not_found
- Add tests for subtree_last_upstream_commit: squash, add, not_found
- Add tests for has_subtree_history: true, false
- Add Changes.week_timestamps_of_ptime and day_timestamps_of_ptime
- Use Ptime directly for date filtering instead of string parsing
- Add log_filtered function for filtering commits by since/until timestamps
and by path (commits that touch specific files/directories)
- Add commit_touches_path helper for path-based filtering
- Rename test_git.ml to test.ml (merlint convention)
- Simplify test/dune to auto-discover modules
- Port Git_cli.log to use ocaml-git internally instead of git CLI
- Add comprehensive tests for log_filtered
- Add resolve_ref to handle various ref formats (HEAD, origin/main, etc.)
- Add log_range_refs that resolves ref names before calling log_range
- Make Git_cli.log_entry a type alias for Git.Repository.log_entry
- Update monopam to use Git.Repository.log_range_refs instead of Git_cli.log_range
- Remove ~proc parameter from doctor.ml analyze_remote and analyze_checkout_remotes
- Remove log_range from Git_cli (no longer used)
- Add subtree_last_upstream_commit and has_subtree_history to Repository
- These functions search commit history for subtree merge/squash messages
- Update monopam cross_status.ml to use Git.Repository.subtree_last_upstream_commit
- Update monopam fork_join.ml to use Git.Repository.has_subtree_history
- Remove ~proc parameter from cross_status.compute (no longer needs CLI)
- Remove subtree_last_upstream_commit and has_subtree_history from Git_cli
Split the monolithic 2600+ line test file into modular test files:
- test_common.ml: shared helpers (with_temp_repo, make_commit, hash)
- test_hash.ml, test_blob.ml, test_user.ml, test_tree.ml
- test_commit.ml, test_tag.ml, test_value.ml, test_reference.ml
- test_pack.ml (includes Pack_index tests)
- test_config.ml, test_index.ml, test_repository.ml
- test_subtree.ml, test_worktree.ml
Also exports Worktree and Diff modules from the Git library.
Add new functions to Repository module:
- rename_branch: rename current branch
- is_ancestor: check if commit is ancestor of another
- count_commits_between: count commits between two refs
- merge_base: find common ancestor of two commits
- set_push_url: set push URL for a remote
These replace equivalent Git CLI operations in monopam.
Add commands to detect and remove unrelated subtree merge commits from
split histories. These commits have git-subtree-dir metadata for a
different package and pollute checkout histories.
- check: scans history and reports unrelated merge commits
- fix: rewrites history, skipping commits where git-subtree-dir doesn't
match prefix and tree is unchanged from first parent
Also refactors split to only include mainline parent for relevant
subtree merges (where git-subtree-dir matches prefix).