diff options
-rw-r--r-- | git_superproject.py | 3 | ||||
-rw-r--r-- | man/repo-smartsync.1 | 5 | ||||
-rw-r--r-- | man/repo-sync.1 | 5 | ||||
-rw-r--r-- | subcmds/sync.py | 109 |
4 files changed, 97 insertions, 25 deletions
diff --git a/git_superproject.py b/git_superproject.py index 687429ec..d808bb09 100644 --- a/git_superproject.py +++ b/git_superproject.py | |||
@@ -147,7 +147,8 @@ class Superproject: | |||
147 | "git rev-parse call failed, command: git {}, " | 147 | "git rev-parse call failed, command: git {}, " |
148 | "return code: {}, stderr: {}", | 148 | "return code: {}, stderr: {}", |
149 | cmd, | 149 | cmd, |
150 | p.stdwerr, | 150 | retval, |
151 | p.stderr, | ||
151 | ) | 152 | ) |
152 | return None | 153 | return None |
153 | return p.stdout | 154 | return p.stdout |
diff --git a/man/repo-smartsync.1 b/man/repo-smartsync.1 index a793b7bc..6e77f182 100644 --- a/man/repo-smartsync.1 +++ b/man/repo-smartsync.1 | |||
@@ -1,5 +1,5 @@ | |||
1 | .\" DO NOT MODIFY THIS FILE! It was generated by help2man. | 1 | .\" DO NOT MODIFY THIS FILE! It was generated by help2man. |
2 | .TH REPO "1" "September 2024" "repo smartsync" "Repo Manual" | 2 | .TH REPO "1" "June 2025" "repo smartsync" "Repo Manual" |
3 | .SH NAME | 3 | .SH NAME |
4 | repo \- repo smartsync - manual page for repo smartsync | 4 | repo \- repo smartsync - manual page for repo smartsync |
5 | .SH SYNOPSIS | 5 | .SH SYNOPSIS |
@@ -58,6 +58,9 @@ only update working tree, don't fetch | |||
58 | use the existing manifest checkout as\-is. (do not | 58 | use the existing manifest checkout as\-is. (do not |
59 | update to the latest revision) | 59 | update to the latest revision) |
60 | .TP | 60 | .TP |
61 | \fB\-\-interleaved\fR | ||
62 | fetch and checkout projects in parallel (experimental) | ||
63 | .TP | ||
61 | \fB\-n\fR, \fB\-\-network\-only\fR | 64 | \fB\-n\fR, \fB\-\-network\-only\fR |
62 | fetch only, don't update working tree | 65 | fetch only, don't update working tree |
63 | .TP | 66 | .TP |
diff --git a/man/repo-sync.1 b/man/repo-sync.1 index 3ce9ec69..afaee2af 100644 --- a/man/repo-sync.1 +++ b/man/repo-sync.1 | |||
@@ -1,5 +1,5 @@ | |||
1 | .\" DO NOT MODIFY THIS FILE! It was generated by help2man. | 1 | .\" DO NOT MODIFY THIS FILE! It was generated by help2man. |
2 | .TH REPO "1" "September 2024" "repo sync" "Repo Manual" | 2 | .TH REPO "1" "June 2025" "repo sync" "Repo Manual" |
3 | .SH NAME | 3 | .SH NAME |
4 | repo \- repo sync - manual page for repo sync | 4 | repo \- repo sync - manual page for repo sync |
5 | .SH SYNOPSIS | 5 | .SH SYNOPSIS |
@@ -58,6 +58,9 @@ only update working tree, don't fetch | |||
58 | use the existing manifest checkout as\-is. (do not | 58 | use the existing manifest checkout as\-is. (do not |
59 | update to the latest revision) | 59 | update to the latest revision) |
60 | .TP | 60 | .TP |
61 | \fB\-\-interleaved\fR | ||
62 | fetch and checkout projects in parallel (experimental) | ||
63 | .TP | ||
61 | \fB\-n\fR, \fB\-\-network\-only\fR | 64 | \fB\-n\fR, \fB\-\-network\-only\fR |
62 | fetch only, don't update working tree | 65 | fetch only, don't update working tree |
63 | .TP | 66 | .TP |
diff --git a/subcmds/sync.py b/subcmds/sync.py index 3a4151df..6e369a10 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
@@ -424,6 +424,11 @@ later is required to fix a server side protocol bug. | |||
424 | "(do not update to the latest revision)", | 424 | "(do not update to the latest revision)", |
425 | ) | 425 | ) |
426 | p.add_option( | 426 | p.add_option( |
427 | "--interleaved", | ||
428 | action="store_true", | ||
429 | help="fetch and checkout projects in parallel (experimental)", | ||
430 | ) | ||
431 | p.add_option( | ||
427 | "-n", | 432 | "-n", |
428 | "--network-only", | 433 | "--network-only", |
429 | action="store_true", | 434 | action="store_true", |
@@ -1772,8 +1777,6 @@ later is required to fix a server side protocol bug. | |||
1772 | e, | 1777 | e, |
1773 | ) | 1778 | ) |
1774 | 1779 | ||
1775 | err_event = multiprocessing.Event() | ||
1776 | |||
1777 | rp = manifest.repoProject | 1780 | rp = manifest.repoProject |
1778 | rp.PreSync() | 1781 | rp.PreSync() |
1779 | cb = rp.CurrentBranch | 1782 | cb = rp.CurrentBranch |
@@ -1825,6 +1828,64 @@ later is required to fix a server side protocol bug. | |||
1825 | all_manifests=not opt.this_manifest_only, | 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 | err_network_sync = False | 1889 | err_network_sync = False |
1829 | err_update_projects = False | 1890 | err_update_projects = False |
1830 | err_update_linkfiles = False | 1891 | err_update_linkfiles = False |
@@ -1942,26 +2003,30 @@ later is required to fix a server side protocol bug. | |||
1942 | ) | 2003 | ) |
1943 | raise SyncError(aggregate_errors=errors) | 2004 | raise SyncError(aggregate_errors=errors) |
1944 | 2005 | ||
1945 | # Log the previous sync analysis state from the config. | 2006 | def _SyncInterleaved( |
1946 | self.git_event_log.LogDataConfigEvents( | 2007 | self, |
1947 | mp.config.GetSyncAnalysisStateData(), "previous_sync_state" | 2008 | opt, |
1948 | ) | 2009 | args, |
1949 | 2010 | errors, | |
1950 | # Update and log with the new sync analysis state. | 2011 | manifest, |
1951 | mp.config.UpdateSyncAnalysisState(opt, superproject_logging_data) | 2012 | mp, |
1952 | self.git_event_log.LogDataConfigEvents( | 2013 | all_projects, |
1953 | mp.config.GetSyncAnalysisStateData(), "current_sync_state" | 2014 | superproject_logging_data, |
1954 | ) | 2015 | ): |
1955 | 2016 | """Sync projects by performing network and local operations in parallel. | |
1956 | self._local_sync_state.PruneRemovedProjects() | 2017 | |
1957 | if self._local_sync_state.IsPartiallySynced(): | 2018 | This method processes each project (or groups of projects that share git |
1958 | logger.warning( | 2019 | objects) independently. For each project, it performs the fetch and |
1959 | "warning: Partial syncs are not supported. For the best " | 2020 | checkout operations back-to-back. These independent tasks are run in |
1960 | "experience, sync the entire tree." | 2021 | parallel. |
1961 | ) | 2022 | |
1962 | 2023 | It respects two constraints for correctness: | |
1963 | if not opt.quiet: | 2024 | 1. Projects in nested directories (e.g. 'foo' and 'foo/bar') are |
1964 | print("repo sync has finished successfully.") | 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 | def _PostRepoUpgrade(manifest, quiet=False): | 2032 | def _PostRepoUpgrade(manifest, quiet=False): |