summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--git_config.py10
-rw-r--r--manifest.py57
-rw-r--r--project.py36
-rwxr-xr-xrepo5
-rw-r--r--subcmds/init.py16
-rw-r--r--subcmds/sync.py5
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')
diff --git a/project.py b/project.py
index 0637f4bf..1cfaaae5 100644
--- a/project.py
+++ b/project.py
@@ -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):
diff --git a/repo b/repo
index 9f107a93..bfa4ca3c 100755
--- a/repo
+++ b/repo
@@ -28,7 +28,7 @@ if __name__ == '__main__':
28del magic 28del 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
31VERSION = (1, 6) 31VERSION = (1, 7)
32 32
33# increment this if the MAINTAINER_KEYS block is modified 33# increment this if the MAINTAINER_KEYS block is modified
34KEYRING_VERSION = (1,0) 34KEYRING_VERSION = (1,0)
@@ -115,6 +115,9 @@ group.add_option('-b', '--manifest-branch',
115group.add_option('-m', '--manifest-name', 115group.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')
118group.add_option('--mirror',
119 dest='mirror', action='store_true',
120 help='mirror the forrest')
118 121
119# Tool 122# Tool
120group = init_optparse.add_option_group('Version options') 123group = 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
109def _VerifyTag(project): 110def _VerifyTag(project):