Monorepo management for opam overlays
0
fork

Configure Feed

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

Fix monopam sync idempotency: skip subtree pulls when already in sync

The push phase checked status to skip already-synced repos, but the
subtree pull phase didn't - it pulled ALL repos unconditionally with
--squash, creating new merge commits even when already in sync. This
caused conflicts on subsequent syncs.

Add needs_pull check that skips subtree pulls when:
- In_sync: trees match, nothing to do
- Subtree_ahead: monorepo is ahead, need push not pull
- Unknown: can't determine, conservative skip

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

+19 -3
+19 -3
lib/monopam.ml
··· 1620 1620 |> Option.fold ~none:true ~some:(fun s -> 1621 1621 sync_needs_push s.Status.subtree_sync) 1622 1622 in 1623 + let sync_needs_pull = function 1624 + | Status.Subtree_behind _ | Status.Trees_differ -> true 1625 + | Status.In_sync | Status.Subtree_ahead _ | Status.Unknown -> 1626 + false 1627 + in 1628 + let needs_pull pkg = 1629 + List.assoc_opt (Package.name pkg) status_by_name 1630 + |> Option.fold ~none:true ~some:(fun s -> 1631 + sync_needs_pull s.Status.subtree_sync) 1632 + in 1623 1633 1624 1634 (* Step 2: Push phase - export monorepo changes to checkouts (PARALLEL) *) 1625 1635 (* git subtree push is read-only on the monorepo, so safe to parallelize *) ··· 1767 1777 m " Skipping subtree updates (local modifications)...") 1768 1778 end 1769 1779 else begin 1780 + (* OPTIMIZATION: skip packages already in sync *) 1781 + let to_pull, to_skip = List.partition needs_pull successfully_fetched in 1770 1782 Log.app (fun m -> m " Updating subtrees..."); 1771 - let fetched_count = List.length successfully_fetched in 1783 + if to_skip <> [] then 1784 + Log.app (fun m -> 1785 + m " Skipping %d already-synced subtrees" 1786 + (List.length to_skip)); 1787 + let pull_count = List.length to_pull in 1772 1788 List.iteri 1773 1789 (fun i pkg -> 1774 1790 Log.info (fun m -> 1775 - m "[%d/%d] Subtree %s" (i + 1) fetched_count 1791 + m "[%d/%d] Subtree %s" (i + 1) pull_count 1776 1792 (Package.subtree_prefix pkg)); 1777 1793 match pull_subtree ~proc ~fs ~config pkg with 1778 1794 | Ok _ -> () ··· 1785 1801 } 1786 1802 :: !subtree_errs 1787 1803 | Error _ -> ()) 1788 - successfully_fetched 1804 + to_pull 1789 1805 end; 1790 1806 ( fetch_errs, 1791 1807 unchanged,