Monorepo management for opam overlays
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

monopam push: drop the trees-match early return

Push.one used to skip the split + upstream push whenever the
monorepo subtree tree matched the local checkout tree. That
optimization silently dropped the upstream push step when the
upstream had diverged: the local split would match the checkout,
Push.one returned Skipped, and to_upstream never got a chance to
run. A subsequent monopam push --force would also skip, so
there was no recovery path short of manually re-cloning the
checkout.

The fix is to always fall through to split_and_push + to_upstream.
split_and_push is near no-op when the refspec already matches the
checkout (git rejects the no-op push cheaply), and to_upstream now
runs regardless so a divergent upstream gets reconciled.

+17 -24
+17 -24
lib/push.ml
··· 279 279 ~prefix ~path ~branch 280 280 |> Result.map (fun () -> Pushed) 281 281 | None -> 282 - let mono_tree = 283 - Git.Repository.tree_hash_at_path git_repo ~rev:"HEAD" ~path:prefix 282 + let checkout_tree = checkout_tree_hash ~sw ~fs checkout_dir in 283 + (* Always run the split + push flow. [split_and_push] is a 284 + near no-op when the refspec already matches the checkout, 285 + and [to_upstream] still needs to run even if the local 286 + trees are in sync, in case the upstream has diverged. *) 287 + Log.info (fun m -> 288 + m "Subtree push %s -> %a" prefix Fpath.pp checkout_dir); 289 + let* () = 290 + Git_cli.ensure_receive_config ~proc 291 + ~fs:(fs :> _ Eio.Path.t) 292 + checkout_dir 284 293 in 285 - let checkout_tree = checkout_tree_hash ~sw ~fs checkout_dir in 286 - if mono_tree = checkout_tree && mono_tree <> None then begin 287 - Log.debug (fun m -> m "Skipping %s (trees match)" prefix); 288 - Ok Skipped 289 - end 290 - else begin 291 - Log.info (fun m -> 292 - m "Subtree push %s -> %a" prefix Fpath.pp checkout_dir); 293 - let* () = 294 - Git_cli.ensure_receive_config ~proc 295 - ~fs:(fs :> _ Eio.Path.t) 296 - checkout_dir 297 - in 298 - let* () = 299 - Git_cli.clean_untracked ~proc 300 - ~fs:(fs :> _ Eio.Path.t) 301 - checkout_dir 302 - in 303 - split_and_push ~proc ~fs ~monorepo ~git_repo ~prefix ~checkout_url 304 - ~checkout_tree ~clean ~force ~branch 305 - |> Result.map (fun () -> Pushed) 306 - end 294 + let* () = 295 + Git_cli.clean_untracked ~proc ~fs:(fs :> _ Eio.Path.t) checkout_dir 296 + in 297 + split_and_push ~proc ~fs ~monorepo ~git_repo ~prefix ~checkout_url 298 + ~checkout_tree ~clean ~force ~branch 299 + |> Result.map (fun () -> Pushed) 307 300 end 308 301 309 302 (** {1 Workspace Repo Push} *)