summaryrefslogtreecommitdiffstats
path: root/subcmds/sync.py
diff options
context:
space:
mode:
authorChe-Liang Chiou <clchiou@google.com>2012-01-11 11:28:42 +0800
committerChe-Liang Chiou <clchiou@google.com>2012-11-19 10:45:21 -0800
commitb2bd91c99b9435cf950ecf8efbb8439f31d3fcbc (patch)
tree5d26d3943317c11c1cd913fc5640074a5bc7910b /subcmds/sync.py
parent3f5ea0b18207a81f58595b1a2e10e5ffb784b74f (diff)
downloadgit-repo-b2bd91c99b9435cf950ecf8efbb8439f31d3fcbc.tar.gz
Represent git-submodule as nested projects, take 2
(Previous submission of this change broke Android buildbot due to incorrect regular expression for parsing git-config output. During investigation, we also found that Android, which pulls Chromium, has a workaround for Chromium's submodules; its manifest includes Chromium's submodules. This new change, in addition to fixing the regex, also take this type of workarounds into consideration; it adds a new attribute that makes repo not fetch submodules unless submodules have a project element defined in the manifest, or this attribute is overridden by a parent project element or by the default element.) We need a representation of git-submodule in repo; otherwise repo will not sync submodules, and leave workspace in a broken state. Of course this will not be a problem if all projects are owned by the owner of the manifest file, who may simply choose not to use git-submodule in all projects. However, this is not possible in practice because manifest file owner is unlikely to own all upstream projects. As git submodules are simply git repositories, it is natural to treat them as plain repo projects that live inside a repo project. That is, we could use recursively declared projects to denote the is-submodule relation of git repositories. The behavior of repo remains the same to projects that do not have a sub-project within. As for parent projects, repo fetches them and their sub-projects as normal projects, and then checks out subprojects at the commit specified in parent's commit object. The sub-project is fetched at a path relative to parent project's working directory; so the path specified in manifest file should match that of .gitmodules file. If a submodule is not registered in repo manifest, repo will derive its properties from itself and its parent project, which might not always be correct. In such cases, the subproject is called a derived subproject. To a user, a sub-project is merely a git-submodule; so all tips of working with a git-submodule apply here, too. For example, you should not run `repo sync` in a parent repository if its submodule is dirty. Change-Id: I4b8344c1b9ccad2f58ad304573133e5d52e1faef
Diffstat (limited to 'subcmds/sync.py')
-rw-r--r--subcmds/sync.py33
1 files changed, 31 insertions, 2 deletions
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 5b3dca78..f8094738 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -114,6 +114,9 @@ resumeable bundle file on a content delivery network. This
114may be necessary if there are problems with the local Python 114may be necessary if there are problems with the local Python
115HTTP client or proxy configuration, but the Git binary works. 115HTTP client or proxy configuration, but the Git binary works.
116 116
117The --fetch-submodules option enables fetching Git submodules
118of a project from server.
119
117SSH Connections 120SSH Connections
118--------------- 121---------------
119 122
@@ -180,6 +183,9 @@ later is required to fix a server side protocol bug.
180 p.add_option('-p', '--manifest-server-password', action='store', 183 p.add_option('-p', '--manifest-server-password', action='store',
181 dest='manifest_server_password', 184 dest='manifest_server_password',
182 help='password to authenticate with the manifest server') 185 help='password to authenticate with the manifest server')
186 p.add_option('--fetch-submodules',
187 dest='fetch_submodules', action='store_true',
188 help='fetch submodules from server')
183 if show_smart: 189 if show_smart:
184 p.add_option('-s', '--smart-sync', 190 p.add_option('-s', '--smart-sync',
185 dest='smart_sync', action='store_true', 191 dest='smart_sync', action='store_true',
@@ -559,7 +565,9 @@ later is required to fix a server side protocol bug.
559 self.manifest._Unload() 565 self.manifest._Unload()
560 if opt.jobs is None: 566 if opt.jobs is None:
561 self.jobs = self.manifest.default.sync_j 567 self.jobs = self.manifest.default.sync_j
562 all_projects = self.GetProjects(args, missing_ok=True) 568 all_projects = self.GetProjects(args,
569 missing_ok=True,
570 submodules_ok=opt.fetch_submodules)
563 571
564 self._fetch_times = _FetchTimes(self.manifest) 572 self._fetch_times = _FetchTimes(self.manifest)
565 if not opt.local_only: 573 if not opt.local_only:
@@ -570,12 +578,33 @@ later is required to fix a server side protocol bug.
570 to_fetch.extend(all_projects) 578 to_fetch.extend(all_projects)
571 to_fetch.sort(key=self._fetch_times.Get, reverse=True) 579 to_fetch.sort(key=self._fetch_times.Get, reverse=True)
572 580
573 self._Fetch(to_fetch, opt) 581 fetched = self._Fetch(to_fetch, opt)
574 _PostRepoFetch(rp, opt.no_repo_verify) 582 _PostRepoFetch(rp, opt.no_repo_verify)
575 if opt.network_only: 583 if opt.network_only:
576 # bail out now; the rest touches the working tree 584 # bail out now; the rest touches the working tree
577 return 585 return
578 586
587 # Iteratively fetch missing and/or nested unregistered submodules
588 previously_missing_set = set()
589 while True:
590 self.manifest._Unload()
591 all_projects = self.GetProjects(args,
592 missing_ok=True,
593 submodules_ok=opt.fetch_submodules)
594 missing = []
595 for project in all_projects:
596 if project.gitdir not in fetched:
597 missing.append(project)
598 if not missing:
599 break
600 # Stop us from non-stopped fetching actually-missing repos: If set of
601 # missing repos has not been changed from last fetch, we break.
602 missing_set = set(p.name for p in missing)
603 if previously_missing_set == missing_set:
604 break
605 previously_missing_set = missing_set
606 fetched.update(self._Fetch(missing, opt))
607
579 if self.manifest.IsMirror: 608 if self.manifest.IsMirror:
580 # bail out now, we have no working tree 609 # bail out now, we have no working tree
581 return 610 return