diff options
| -rw-r--r-- | git_config.py | 10 | ||||
| -rw-r--r-- | manifest.py | 57 | ||||
| -rw-r--r-- | project.py | 36 | ||||
| -rwxr-xr-x | repo | 5 | ||||
| -rw-r--r-- | subcmds/init.py | 16 | ||||
| -rw-r--r-- | subcmds/sync.py | 5 |
6 files changed, 109 insertions, 20 deletions
diff --git a/git_config.py b/git_config.py index 76031a0e..9d5162e7 100644 --- a/git_config.py +++ b/git_config.py | |||
| @@ -285,12 +285,14 @@ class Remote(object): | |||
| 285 | return True | 285 | return True |
| 286 | return False | 286 | return False |
| 287 | 287 | ||
| 288 | def ResetFetch(self): | 288 | def ResetFetch(self, mirror=False): |
| 289 | """Set the fetch refspec to its default value. | 289 | """Set the fetch refspec to its default value. |
| 290 | """ | 290 | """ |
| 291 | self.fetch = [RefSpec(True, | 291 | if mirror: |
| 292 | 'refs/heads/*', | 292 | dst = 'refs/heads/*' |
| 293 | 'refs/remotes/%s/*' % self.name)] | 293 | else: |
| 294 | dst = 'refs/remotes/%s/*' % self.name | ||
| 295 | self.fetch = [RefSpec(True, 'refs/heads/*', dst)] | ||
| 294 | 296 | ||
| 295 | def Save(self): | 297 | def Save(self): |
| 296 | """Save this remote to the configuration. | 298 | """Save this remote to the configuration. |
diff --git a/manifest.py b/manifest.py index b928cdfe..ea68b682 100644 --- a/manifest.py +++ b/manifest.py | |||
| @@ -88,6 +88,10 @@ class Manifest(object): | |||
| 88 | self._Load() | 88 | self._Load() |
| 89 | return self._default | 89 | return self._default |
| 90 | 90 | ||
| 91 | @property | ||
| 92 | def IsMirror(self): | ||
| 93 | return self.manifestProject.config.GetBoolean('repo.mirror') | ||
| 94 | |||
| 91 | def _Unload(self): | 95 | def _Unload(self): |
| 92 | self._loaded = False | 96 | self._loaded = False |
| 93 | self._projects = {} | 97 | self._projects = {} |
| @@ -114,6 +118,10 @@ class Manifest(object): | |||
| 114 | finally: | 118 | finally: |
| 115 | self.manifestFile = real | 119 | self.manifestFile = real |
| 116 | 120 | ||
| 121 | if self.IsMirror: | ||
| 122 | self._AddMetaProjectMirror(self.repoProject) | ||
| 123 | self._AddMetaProjectMirror(self.manifestProject) | ||
| 124 | |||
| 117 | self._loaded = True | 125 | self._loaded = True |
| 118 | 126 | ||
| 119 | def _ParseManifest(self, is_root_file): | 127 | def _ParseManifest(self, is_root_file): |
| @@ -157,6 +165,40 @@ class Manifest(object): | |||
| 157 | (project.name, self.manifestFile) | 165 | (project.name, self.manifestFile) |
| 158 | self._projects[project.name] = project | 166 | self._projects[project.name] = project |
| 159 | 167 | ||
| 168 | def _AddMetaProjectMirror(self, m): | ||
| 169 | name = None | ||
| 170 | m_url = m.GetRemote(m.remote.name).url | ||
| 171 | if m_url.endswith('/.git'): | ||
| 172 | raise ManifestParseError, 'refusing to mirror %s' % m_url | ||
| 173 | |||
| 174 | if self._default and self._default.remote: | ||
| 175 | url = self._default.remote.fetchUrl | ||
| 176 | if not url.endswith('/'): | ||
| 177 | url += '/' | ||
| 178 | if m_url.startswith(url): | ||
| 179 | remote = self._default.remote | ||
| 180 | name = m_url[len(url):] | ||
| 181 | |||
| 182 | if name is None: | ||
| 183 | s = m_url.rindex('/') + 1 | ||
| 184 | remote = Remote('origin', fetch = m_url[:s]) | ||
| 185 | name = m_url[s:] | ||
| 186 | |||
| 187 | if name.endswith('.git'): | ||
| 188 | name = name[:-4] | ||
| 189 | |||
| 190 | if name not in self._projects: | ||
| 191 | m.PreSync() | ||
| 192 | gitdir = os.path.join(self.topdir, '%s.git' % name) | ||
| 193 | project = Project(manifest = self, | ||
| 194 | name = name, | ||
| 195 | remote = remote, | ||
| 196 | gitdir = gitdir, | ||
| 197 | worktree = None, | ||
| 198 | relpath = None, | ||
| 199 | revision = m.revision) | ||
| 200 | self._projects[project.name] = project | ||
| 201 | |||
| 160 | def _ParseRemote(self, node): | 202 | def _ParseRemote(self, node): |
| 161 | """ | 203 | """ |
| 162 | reads a <remote> element from the manifest file | 204 | reads a <remote> element from the manifest file |
| @@ -214,8 +256,13 @@ class Manifest(object): | |||
| 214 | "project %s path cannot be absolute in %s" % \ | 256 | "project %s path cannot be absolute in %s" % \ |
| 215 | (name, self.manifestFile) | 257 | (name, self.manifestFile) |
| 216 | 258 | ||
| 217 | worktree = os.path.join(self.topdir, path) | 259 | if self.IsMirror: |
| 218 | gitdir = os.path.join(self.repodir, 'projects/%s.git' % path) | 260 | relpath = None |
| 261 | worktree = None | ||
| 262 | gitdir = os.path.join(self.topdir, '%s.git' % name) | ||
| 263 | else: | ||
| 264 | worktree = os.path.join(self.topdir, path) | ||
| 265 | gitdir = os.path.join(self.repodir, 'projects/%s.git' % path) | ||
| 219 | 266 | ||
| 220 | project = Project(manifest = self, | 267 | project = Project(manifest = self, |
| 221 | name = name, | 268 | name = name, |
| @@ -242,8 +289,10 @@ class Manifest(object): | |||
| 242 | def _ParseCopyFile(self, project, node): | 289 | def _ParseCopyFile(self, project, node): |
| 243 | src = self._reqatt(node, 'src') | 290 | src = self._reqatt(node, 'src') |
| 244 | dest = self._reqatt(node, 'dest') | 291 | dest = self._reqatt(node, 'dest') |
| 245 | # src is project relative, and dest is relative to the top of the tree | 292 | if not self.IsMirror: |
| 246 | project.AddCopyFile(src, os.path.join(self.topdir, dest)) | 293 | # src is project relative; |
| 294 | # dest is relative to the top of the tree | ||
| 295 | project.AddCopyFile(src, os.path.join(self.topdir, dest)) | ||
| 247 | 296 | ||
| 248 | def _get_remote(self, node): | 297 | def _get_remote(self, node): |
| 249 | name = node.getAttribute('remote') | 298 | name = node.getAttribute('remote') |
| @@ -211,7 +211,10 @@ class Project(object): | |||
| 211 | gitdir = self.gitdir, | 211 | gitdir = self.gitdir, |
| 212 | defaults = self.manifest.globalConfig) | 212 | defaults = self.manifest.globalConfig) |
| 213 | 213 | ||
| 214 | self.work_git = self._GitGetByExec(self, bare=False) | 214 | if self.worktree: |
| 215 | self.work_git = self._GitGetByExec(self, bare=False) | ||
| 216 | else: | ||
| 217 | self.work_git = None | ||
| 215 | self.bare_git = self._GitGetByExec(self, bare=True) | 218 | self.bare_git = self._GitGetByExec(self, bare=True) |
| 216 | 219 | ||
| 217 | @property | 220 | @property |
| @@ -489,14 +492,23 @@ class Project(object): | |||
| 489 | print >>sys.stderr | 492 | print >>sys.stderr |
| 490 | print >>sys.stderr, 'Initializing project %s ...' % self.name | 493 | print >>sys.stderr, 'Initializing project %s ...' % self.name |
| 491 | self._InitGitDir() | 494 | self._InitGitDir() |
| 495 | |||
| 492 | self._InitRemote() | 496 | self._InitRemote() |
| 493 | for r in self.extraRemotes.values(): | 497 | for r in self.extraRemotes.values(): |
| 494 | if not self._RemoteFetch(r.name): | 498 | if not self._RemoteFetch(r.name): |
| 495 | return False | 499 | return False |
| 496 | if not self._RemoteFetch(): | 500 | if not self._RemoteFetch(): |
| 497 | return False | 501 | return False |
| 498 | self._RepairAndroidImportErrors() | 502 | |
| 499 | self._InitMRef() | 503 | if self.worktree: |
| 504 | self._RepairAndroidImportErrors() | ||
| 505 | self._InitMRef() | ||
| 506 | else: | ||
| 507 | self._InitMirrorHead() | ||
| 508 | try: | ||
| 509 | os.remove(os.path.join(self.gitdir, 'FETCH_HEAD')) | ||
| 510 | except OSError: | ||
| 511 | pass | ||
| 500 | return True | 512 | return True |
| 501 | 513 | ||
| 502 | def PostRepoUpgrade(self): | 514 | def PostRepoUpgrade(self): |
| @@ -792,9 +804,11 @@ class Project(object): | |||
| 792 | def _RemoteFetch(self, name=None): | 804 | def _RemoteFetch(self, name=None): |
| 793 | if not name: | 805 | if not name: |
| 794 | name = self.remote.name | 806 | name = self.remote.name |
| 795 | return GitCommand(self, | 807 | cmd = ['fetch'] |
| 796 | ['fetch', name], | 808 | if not self.worktree: |
| 797 | bare = True).Wait() == 0 | 809 | cmd.append('--update-head-ok') |
| 810 | cmd.append(name) | ||
| 811 | return GitCommand(self, cmd, bare = True).Wait() == 0 | ||
| 798 | 812 | ||
| 799 | def _Checkout(self, rev, quiet=False): | 813 | def _Checkout(self, rev, quiet=False): |
| 800 | cmd = ['checkout'] | 814 | cmd = ['checkout'] |
| @@ -874,7 +888,10 @@ class Project(object): | |||
| 874 | remote.url = url | 888 | remote.url = url |
| 875 | remote.review = self.remote.reviewUrl | 889 | remote.review = self.remote.reviewUrl |
| 876 | 890 | ||
| 877 | remote.ResetFetch() | 891 | if self.worktree: |
| 892 | remote.ResetFetch(mirror=False) | ||
| 893 | else: | ||
| 894 | remote.ResetFetch(mirror=True) | ||
| 878 | remote.Save() | 895 | remote.Save() |
| 879 | 896 | ||
| 880 | for r in self.extraRemotes.values(): | 897 | for r in self.extraRemotes.values(): |
| @@ -897,6 +914,11 @@ class Project(object): | |||
| 897 | dst = remote.ToLocal(self.revision) | 914 | dst = remote.ToLocal(self.revision) |
| 898 | self.bare_git.symbolic_ref('-m', msg, ref, dst) | 915 | self.bare_git.symbolic_ref('-m', msg, ref, dst) |
| 899 | 916 | ||
| 917 | def _InitMirrorHead(self): | ||
| 918 | dst = self.GetRemote(self.remote.name).ToLocal(self.revision) | ||
| 919 | msg = 'manifest set to %s' % self.revision | ||
| 920 | self.bare_git.SetHead(dst, message=msg) | ||
| 921 | |||
| 900 | def _InitWorkTree(self): | 922 | def _InitWorkTree(self): |
| 901 | dotgit = os.path.join(self.worktree, '.git') | 923 | dotgit = os.path.join(self.worktree, '.git') |
| 902 | if not os.path.exists(dotgit): | 924 | if not os.path.exists(dotgit): |
| @@ -28,7 +28,7 @@ if __name__ == '__main__': | |||
| 28 | del magic | 28 | del magic |
| 29 | 29 | ||
| 30 | # increment this whenever we make important changes to this script | 30 | # increment this whenever we make important changes to this script |
| 31 | VERSION = (1, 6) | 31 | VERSION = (1, 7) |
| 32 | 32 | ||
| 33 | # increment this if the MAINTAINER_KEYS block is modified | 33 | # increment this if the MAINTAINER_KEYS block is modified |
| 34 | KEYRING_VERSION = (1,0) | 34 | KEYRING_VERSION = (1,0) |
| @@ -115,6 +115,9 @@ group.add_option('-b', '--manifest-branch', | |||
| 115 | group.add_option('-m', '--manifest-name', | 115 | group.add_option('-m', '--manifest-name', |
| 116 | dest='manifest_name', | 116 | dest='manifest_name', |
| 117 | help='initial manifest file', metavar='NAME.xml') | 117 | help='initial manifest file', metavar='NAME.xml') |
| 118 | group.add_option('--mirror', | ||
| 119 | dest='mirror', action='store_true', | ||
| 120 | help='mirror the forrest') | ||
| 118 | 121 | ||
| 119 | # Tool | 122 | # Tool |
| 120 | group = init_optparse.add_option_group('Version options') | 123 | group = init_optparse.add_option_group('Version options') |
diff --git a/subcmds/init.py b/subcmds/init.py index 03f358d1..ad28a611 100644 --- a/subcmds/init.py +++ b/subcmds/init.py | |||
| @@ -57,6 +57,10 @@ default.xml will be used. | |||
| 57 | g.add_option('-m', '--manifest-name', | 57 | g.add_option('-m', '--manifest-name', |
| 58 | dest='manifest_name', default='default.xml', | 58 | dest='manifest_name', default='default.xml', |
| 59 | help='initial manifest file', metavar='NAME.xml') | 59 | help='initial manifest file', metavar='NAME.xml') |
| 60 | g.add_option('--mirror', | ||
| 61 | dest='mirror', action='store_true', | ||
| 62 | help='mirror the forrest') | ||
| 63 | |||
| 60 | 64 | ||
| 61 | # Tool | 65 | # Tool |
| 62 | g = p.add_option_group('Version options') | 66 | g = p.add_option_group('Version options') |
| @@ -112,6 +116,9 @@ default.xml will be used. | |||
| 112 | r.ResetFetch() | 116 | r.ResetFetch() |
| 113 | r.Save() | 117 | r.Save() |
| 114 | 118 | ||
| 119 | if opt.mirror: | ||
| 120 | m.config.SetString('repo.mirror', 'true') | ||
| 121 | |||
| 115 | m.Sync_NetworkHalf() | 122 | m.Sync_NetworkHalf() |
| 116 | m.Sync_LocalHalf() | 123 | m.Sync_LocalHalf() |
| 117 | m.StartBranch('default') | 124 | m.StartBranch('default') |
| @@ -185,9 +192,14 @@ default.xml will be used. | |||
| 185 | self._SyncManifest(opt) | 192 | self._SyncManifest(opt) |
| 186 | self._LinkManifest(opt.manifest_name) | 193 | self._LinkManifest(opt.manifest_name) |
| 187 | 194 | ||
| 188 | if os.isatty(0) and os.isatty(1): | 195 | if os.isatty(0) and os.isatty(1) and not opt.mirror: |
| 189 | self._ConfigureUser() | 196 | self._ConfigureUser() |
| 190 | self._ConfigureColor() | 197 | self._ConfigureColor() |
| 191 | 198 | ||
| 199 | if opt.mirror: | ||
| 200 | type = 'mirror ' | ||
| 201 | else: | ||
| 202 | type = '' | ||
| 203 | |||
| 192 | print '' | 204 | print '' |
| 193 | print 'repo initialized in %s' % self.manifest.topdir | 205 | print 'repo %sinitialized in %s' % (type, self.manifest.topdir) |
diff --git a/subcmds/sync.py b/subcmds/sync.py index 9af12322..8050e515 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
| @@ -102,8 +102,9 @@ the manifest. | |||
| 102 | self._Fetch(*missing) | 102 | self._Fetch(*missing) |
| 103 | 103 | ||
| 104 | for project in all: | 104 | for project in all: |
| 105 | if not project.Sync_LocalHalf(): | 105 | if project.worktree: |
| 106 | sys.exit(1) | 106 | if not project.Sync_LocalHalf(): |
| 107 | sys.exit(1) | ||
| 107 | 108 | ||
| 108 | 109 | ||
| 109 | def _VerifyTag(project): | 110 | def _VerifyTag(project): |
