Monorepo management for opam overlays

Fix sync: pull subtree from local checkout, not remote URL

The sync workflow is:
1. Push: mono/ → local src/ (subtree push to checkout_dir)
2. Pull: local src/ → mono/ (subtree pull from checkout_dir)

Previously, step 2 was pulling from the remote URL (Package.dev_repo),
which could have different commits than the local checkout, causing
conflicts when the remote was out of sync.

Now both push and pull use the same local checkout as the source of
truth, ensuring the round-trip is consistent.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+6 -3
+6 -3
lib/monopam.ml
··· 890 let pull_subtree ~proc ~fs ~config pkg = 891 let fs = fs_typed fs in 892 let monorepo = Config.Paths.monorepo config in 893 let prefix = Package.subtree_prefix pkg in 894 let branch = get_branch ~config pkg in 895 - let url = Package.dev_repo pkg in 896 if Git.Subtree.exists ~fs ~repo:monorepo ~prefix then begin 897 - Log.info (fun m -> m "Pulling subtree %s" prefix); 898 match Git.Subtree.pull ~proc ~fs ~repo:monorepo ~prefix ~url ~branch () with 899 | Ok () -> Ok false (* not newly added *) 900 | Error e -> Error (Git_error e) 901 end 902 else begin 903 - Log.info (fun m -> m "Adding subtree %s" prefix); 904 match Git.Subtree.add ~proc ~fs ~repo:monorepo ~prefix ~url ~branch () with 905 | Ok () -> Ok true (* newly added *) 906 | Error e -> Error (Git_error e)
··· 890 let pull_subtree ~proc ~fs ~config pkg = 891 let fs = fs_typed fs in 892 let monorepo = Config.Paths.monorepo config in 893 + let checkouts_root = Config.Paths.checkouts config in 894 let prefix = Package.subtree_prefix pkg in 895 let branch = get_branch ~config pkg in 896 + (* Pull from local checkout, not remote URL - ensures push/pull use same source *) 897 + let checkout_dir = Package.checkout_dir ~checkouts_root pkg in 898 + let url = Uri.of_string (Fpath.to_string checkout_dir) in 899 if Git.Subtree.exists ~fs ~repo:monorepo ~prefix then begin 900 + Log.info (fun m -> m "Pulling subtree %s from %a" prefix Fpath.pp checkout_dir); 901 match Git.Subtree.pull ~proc ~fs ~repo:monorepo ~prefix ~url ~branch () with 902 | Ok () -> Ok false (* not newly added *) 903 | Error e -> Error (Git_error e) 904 end 905 else begin 906 + Log.info (fun m -> m "Adding subtree %s from %a" prefix Fpath.pp checkout_dir); 907 match Git.Subtree.add ~proc ~fs ~repo:monorepo ~prefix ~url ~branch () with 908 | Ok () -> Ok true (* newly added *) 909 | Error e -> Error (Git_error e)