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): |