@@ -423,6 +423,11 @@ def _Options(self, p, show_smart=True):
423
423
help = "use the existing manifest checkout as-is. "
424
424
"(do not update to the latest revision)" ,
425
425
)
426
+ p .add_option (
427
+ "--interleaved" ,
428
+ action = "store_true" ,
429
+ help = "fetch and checkout projects in parallel (experimental)" ,
430
+ )
426
431
p .add_option (
427
432
"-n" ,
428
433
"--network-only" ,
@@ -1772,8 +1777,6 @@ def _ExecuteHelper(self, opt, args, errors):
1772
1777
e ,
1773
1778
)
1774
1779
1775
- err_event = multiprocessing .Event ()
1776
-
1777
1780
rp = manifest .repoProject
1778
1781
rp .PreSync ()
1779
1782
cb = rp .CurrentBranch
@@ -1825,6 +1828,64 @@ def _ExecuteHelper(self, opt, args, errors):
1825
1828
all_manifests = not opt .this_manifest_only ,
1826
1829
)
1827
1830
1831
+ if opt .interleaved :
1832
+ sync_method = self ._SyncInterleaved
1833
+ else :
1834
+ sync_method = self ._SyncPhased
1835
+
1836
+ sync_method (
1837
+ opt ,
1838
+ args ,
1839
+ errors ,
1840
+ manifest ,
1841
+ mp ,
1842
+ all_projects ,
1843
+ superproject_logging_data ,
1844
+ )
1845
+
1846
+ # Log the previous sync analysis state from the config.
1847
+ self .git_event_log .LogDataConfigEvents (
1848
+ mp .config .GetSyncAnalysisStateData (), "previous_sync_state"
1849
+ )
1850
+
1851
+ # Update and log with the new sync analysis state.
1852
+ mp .config .UpdateSyncAnalysisState (opt , superproject_logging_data )
1853
+ self .git_event_log .LogDataConfigEvents (
1854
+ mp .config .GetSyncAnalysisStateData (), "current_sync_state"
1855
+ )
1856
+
1857
+ self ._local_sync_state .PruneRemovedProjects ()
1858
+ if self ._local_sync_state .IsPartiallySynced ():
1859
+ logger .warning (
1860
+ "warning: Partial syncs are not supported. For the best "
1861
+ "experience, sync the entire tree."
1862
+ )
1863
+
1864
+ if not opt .quiet :
1865
+ print ("repo sync has finished successfully." )
1866
+
1867
+ def _SyncPhased (
1868
+ self ,
1869
+ opt ,
1870
+ args ,
1871
+ errors ,
1872
+ manifest ,
1873
+ mp ,
1874
+ all_projects ,
1875
+ superproject_logging_data ,
1876
+ ):
1877
+ """Sync projects by separating network and local operations.
1878
+
1879
+ This method performs sync in two distinct, sequential phases:
1880
+ 1. Network Phase: Fetches updates for all projects from their remotes.
1881
+ 2. Local Phase: Checks out the updated revisions into the local
1882
+ worktrees for all projects.
1883
+
1884
+ This approach ensures that the local work-tree is not modified until
1885
+ all network operations are complete, providing a transactional-like
1886
+ safety net for the checkout state.
1887
+ """
1888
+ err_event = multiprocessing .Event ()
1828
1889
err_network_sync = False
1829
1890
err_update_projects = False
1830
1891
err_update_linkfiles = False
@@ -1942,26 +2003,30 @@ def print_and_log(err_msg):
1942
2003
)
1943
2004
raise SyncError (aggregate_errors = errors )
1944
2005
1945
- # Log the previous sync analysis state from the config.
1946
- self .git_event_log .LogDataConfigEvents (
1947
- mp .config .GetSyncAnalysisStateData (), "previous_sync_state"
1948
- )
1949
-
1950
- # Update and log with the new sync analysis state.
1951
- mp .config .UpdateSyncAnalysisState (opt , superproject_logging_data )
1952
- self .git_event_log .LogDataConfigEvents (
1953
- mp .config .GetSyncAnalysisStateData (), "current_sync_state"
1954
- )
1955
-
1956
- self ._local_sync_state .PruneRemovedProjects ()
1957
- if self ._local_sync_state .IsPartiallySynced ():
1958
- logger .warning (
1959
- "warning: Partial syncs are not supported. For the best "
1960
- "experience, sync the entire tree."
1961
- )
1962
-
1963
- if not opt .quiet :
1964
- print ("repo sync has finished successfully." )
2006
+ def _SyncInterleaved (
2007
+ self ,
2008
+ opt ,
2009
+ args ,
2010
+ errors ,
2011
+ manifest ,
2012
+ mp ,
2013
+ all_projects ,
2014
+ superproject_logging_data ,
2015
+ ):
2016
+ """Sync projects by performing network and local operations in parallel.
2017
+
2018
+ This method processes each project (or groups of projects that share git
2019
+ objects) independently. For each project, it performs the fetch and
2020
+ checkout operations back-to-back. These independent tasks are run in
2021
+ parallel.
2022
+
2023
+ It respects two constraints for correctness:
2024
+ 1. Projects in nested directories (e.g. 'foo' and 'foo/bar') are
2025
+ processed in hierarchical order.
2026
+ 2. Projects that share git objects are processed serially to prevent
2027
+ race conditions.
2028
+ """
2029
+ raise NotImplementedError ("Interleaved sync is not implemented yet." )
1965
2030
1966
2031
1967
2032
def _PostRepoUpgrade (manifest , quiet = False ):
0 commit comments