diff options
Diffstat (limited to 'repo')
-rwxr-xr-x | repo | 146 |
1 files changed, 126 insertions, 20 deletions
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | ## repo default configuration | 3 | ## repo default configuration |
4 | ## | 4 | ## |
5 | REPO_URL='git://android.git.kernel.org/tools/repo.git' | 5 | REPO_URL='https://gerrit.googlesource.com/git-repo' |
6 | REPO_REV='stable' | 6 | REPO_REV='stable' |
7 | 7 | ||
8 | # Copyright (C) 2008 Google Inc. | 8 | # Copyright (C) 2008 Google Inc. |
@@ -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, 10) | 31 | VERSION = (1, 17) |
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) |
@@ -91,6 +91,7 @@ import re | |||
91 | import readline | 91 | import readline |
92 | import subprocess | 92 | import subprocess |
93 | import sys | 93 | import sys |
94 | import urllib2 | ||
94 | 95 | ||
95 | home_dot_repo = os.path.expanduser('~/.repoconfig') | 96 | home_dot_repo = os.path.expanduser('~/.repoconfig') |
96 | gpg_dir = os.path.join(home_dot_repo, 'gnupg') | 97 | gpg_dir = os.path.join(home_dot_repo, 'gnupg') |
@@ -109,23 +110,31 @@ group = init_optparse.add_option_group('Manifest options') | |||
109 | group.add_option('-u', '--manifest-url', | 110 | group.add_option('-u', '--manifest-url', |
110 | dest='manifest_url', | 111 | dest='manifest_url', |
111 | help='manifest repository location', metavar='URL') | 112 | help='manifest repository location', metavar='URL') |
112 | group.add_option('-o', '--origin', | ||
113 | dest='manifest_origin', | ||
114 | help="use REMOTE instead of 'origin' to track upstream", | ||
115 | metavar='REMOTE') | ||
116 | group.add_option('-b', '--manifest-branch', | 113 | group.add_option('-b', '--manifest-branch', |
117 | dest='manifest_branch', | 114 | dest='manifest_branch', |
118 | help='manifest branch or revision', metavar='REVISION') | 115 | help='manifest branch or revision', metavar='REVISION') |
119 | group.add_option('-m', '--manifest-name', | 116 | group.add_option('-m', '--manifest-name', |
120 | dest='manifest_name', | 117 | dest='manifest_name', |
121 | help='initial manifest file (deprecated)', | 118 | help='initial manifest file', metavar='NAME.xml') |
122 | metavar='NAME.xml') | ||
123 | group.add_option('--mirror', | 119 | group.add_option('--mirror', |
124 | dest='mirror', action='store_true', | 120 | dest='mirror', action='store_true', |
125 | help='mirror the forrest') | 121 | help='mirror the forrest') |
126 | group.add_option('--reference', | 122 | group.add_option('--reference', |
127 | dest='reference', | 123 | dest='reference', |
128 | help='location of mirror directory', metavar='DIR') | 124 | help='location of mirror directory', metavar='DIR') |
125 | group.add_option('--depth', type='int', default=None, | ||
126 | dest='depth', | ||
127 | help='create a shallow clone with given depth; see git clone') | ||
128 | group.add_option('-g', '--groups', | ||
129 | dest='groups', default='default', | ||
130 | help='restrict manifest projects to ones with a specified group', | ||
131 | metavar='GROUP') | ||
132 | group.add_option('-p', '--platform', | ||
133 | dest='platform', default="auto", | ||
134 | help='restrict manifest projects to ones with a specified' | ||
135 | 'platform group [auto|all|none|linux|darwin|...]', | ||
136 | metavar='PLATFORM') | ||
137 | |||
129 | 138 | ||
130 | # Tool | 139 | # Tool |
131 | group = init_optparse.add_option_group('repo Version options') | 140 | group = init_optparse.add_option_group('repo Version options') |
@@ -139,6 +148,11 @@ group.add_option('--no-repo-verify', | |||
139 | dest='no_repo_verify', action='store_true', | 148 | dest='no_repo_verify', action='store_true', |
140 | help='do not verify repo source code') | 149 | help='do not verify repo source code') |
141 | 150 | ||
151 | # Other | ||
152 | group = init_optparse.add_option_group('Other options') | ||
153 | group.add_option('--config-name', | ||
154 | dest='config_name', action="store_true", default=False, | ||
155 | help='Always prompt for name/e-mail') | ||
142 | 156 | ||
143 | class CloneFailure(Exception): | 157 | class CloneFailure(Exception): |
144 | """Indicate the remote clone of repo itself failed. | 158 | """Indicate the remote clone of repo itself failed. |
@@ -149,7 +163,7 @@ def _Init(args): | |||
149 | """Installs repo by cloning it over the network. | 163 | """Installs repo by cloning it over the network. |
150 | """ | 164 | """ |
151 | opt, args = init_optparse.parse_args(args) | 165 | opt, args = init_optparse.parse_args(args) |
152 | if args or not opt.manifest_url: | 166 | if args: |
153 | init_optparse.print_usage() | 167 | init_optparse.print_usage() |
154 | sys.exit(1) | 168 | sys.exit(1) |
155 | 169 | ||
@@ -188,10 +202,6 @@ def _Init(args): | |||
188 | else: | 202 | else: |
189 | can_verify = True | 203 | can_verify = True |
190 | 204 | ||
191 | if not opt.quiet: | ||
192 | print >>sys.stderr, 'Getting repo ...' | ||
193 | print >>sys.stderr, ' from %s' % url | ||
194 | |||
195 | dst = os.path.abspath(os.path.join(repodir, S_repo)) | 205 | dst = os.path.abspath(os.path.join(repodir, S_repo)) |
196 | _Clone(url, dst, opt.quiet) | 206 | _Clone(url, dst, opt.quiet) |
197 | 207 | ||
@@ -210,7 +220,17 @@ def _Init(args): | |||
210 | 220 | ||
211 | def _CheckGitVersion(): | 221 | def _CheckGitVersion(): |
212 | cmd = [GIT, '--version'] | 222 | cmd = [GIT, '--version'] |
213 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) | 223 | try: |
224 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) | ||
225 | except OSError, e: | ||
226 | print >>sys.stderr | ||
227 | print >>sys.stderr, "fatal: '%s' is not available" % GIT | ||
228 | print >>sys.stderr, 'fatal: %s' % e | ||
229 | print >>sys.stderr | ||
230 | print >>sys.stderr, 'Please make sure %s is installed'\ | ||
231 | ' and in your path.' % GIT | ||
232 | raise CloneFailure() | ||
233 | |||
214 | ver_str = proc.stdout.read().strip() | 234 | ver_str = proc.stdout.read().strip() |
215 | proc.stdout.close() | 235 | proc.stdout.close() |
216 | proc.wait() | 236 | proc.wait() |
@@ -301,15 +321,43 @@ def _SetConfig(local, name, value): | |||
301 | raise CloneFailure() | 321 | raise CloneFailure() |
302 | 322 | ||
303 | 323 | ||
304 | def _Fetch(local, quiet, *args): | 324 | def _InitHttp(): |
325 | handlers = [] | ||
326 | |||
327 | mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() | ||
328 | try: | ||
329 | import netrc | ||
330 | n = netrc.netrc() | ||
331 | for host in n.hosts: | ||
332 | p = n.hosts[host] | ||
333 | mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2]) | ||
334 | mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2]) | ||
335 | except: | ||
336 | pass | ||
337 | handlers.append(urllib2.HTTPBasicAuthHandler(mgr)) | ||
338 | handlers.append(urllib2.HTTPDigestAuthHandler(mgr)) | ||
339 | |||
340 | if 'http_proxy' in os.environ: | ||
341 | url = os.environ['http_proxy'] | ||
342 | handlers.append(urllib2.ProxyHandler({'http': url, 'https': url})) | ||
343 | if 'REPO_CURL_VERBOSE' in os.environ: | ||
344 | handlers.append(urllib2.HTTPHandler(debuglevel=1)) | ||
345 | handlers.append(urllib2.HTTPSHandler(debuglevel=1)) | ||
346 | urllib2.install_opener(urllib2.build_opener(*handlers)) | ||
347 | |||
348 | def _Fetch(url, local, src, quiet): | ||
349 | if not quiet: | ||
350 | print >>sys.stderr, 'Get %s' % url | ||
351 | |||
305 | cmd = [GIT, 'fetch'] | 352 | cmd = [GIT, 'fetch'] |
306 | if quiet: | 353 | if quiet: |
307 | cmd.append('--quiet') | 354 | cmd.append('--quiet') |
308 | err = subprocess.PIPE | 355 | err = subprocess.PIPE |
309 | else: | 356 | else: |
310 | err = None | 357 | err = None |
311 | cmd.extend(args) | 358 | cmd.append(src) |
312 | cmd.append('origin') | 359 | cmd.append('+refs/heads/*:refs/remotes/origin/*') |
360 | cmd.append('refs/tags/*:refs/tags/*') | ||
313 | 361 | ||
314 | proc = subprocess.Popen(cmd, cwd = local, stderr = err) | 362 | proc = subprocess.Popen(cmd, cwd = local, stderr = err) |
315 | if err: | 363 | if err: |
@@ -318,6 +366,62 @@ def _Fetch(local, quiet, *args): | |||
318 | if proc.wait() != 0: | 366 | if proc.wait() != 0: |
319 | raise CloneFailure() | 367 | raise CloneFailure() |
320 | 368 | ||
369 | def _DownloadBundle(url, local, quiet): | ||
370 | if not url.endswith('/'): | ||
371 | url += '/' | ||
372 | url += 'clone.bundle' | ||
373 | |||
374 | proc = subprocess.Popen( | ||
375 | [GIT, 'config', '--get-regexp', 'url.*.insteadof'], | ||
376 | cwd = local, | ||
377 | stdout = subprocess.PIPE) | ||
378 | for line in proc.stdout: | ||
379 | m = re.compile(r'^url\.(.*)\.insteadof (.*)$').match(line) | ||
380 | if m: | ||
381 | new_url = m.group(1) | ||
382 | old_url = m.group(2) | ||
383 | if url.startswith(old_url): | ||
384 | url = new_url + url[len(old_url):] | ||
385 | break | ||
386 | proc.stdout.close() | ||
387 | proc.wait() | ||
388 | |||
389 | if not url.startswith('http:') and not url.startswith('https:'): | ||
390 | return False | ||
391 | |||
392 | dest = open(os.path.join(local, '.git', 'clone.bundle'), 'w+b') | ||
393 | try: | ||
394 | try: | ||
395 | r = urllib2.urlopen(url) | ||
396 | except urllib2.HTTPError, e: | ||
397 | if e.code == 404: | ||
398 | return False | ||
399 | print >>sys.stderr, 'fatal: Cannot get %s' % url | ||
400 | print >>sys.stderr, 'fatal: HTTP error %s' % e.code | ||
401 | raise CloneFailure() | ||
402 | except urllib2.URLError, e: | ||
403 | print >>sys.stderr, 'fatal: Cannot get %s' % url | ||
404 | print >>sys.stderr, 'fatal: error %s' % e.reason | ||
405 | raise CloneFailure() | ||
406 | try: | ||
407 | if not quiet: | ||
408 | print >>sys.stderr, 'Get %s' % url | ||
409 | while True: | ||
410 | buf = r.read(8192) | ||
411 | if buf == '': | ||
412 | return True | ||
413 | dest.write(buf) | ||
414 | finally: | ||
415 | r.close() | ||
416 | finally: | ||
417 | dest.close() | ||
418 | |||
419 | def _ImportBundle(local): | ||
420 | path = os.path.join(local, '.git', 'clone.bundle') | ||
421 | try: | ||
422 | _Fetch(local, local, path, True) | ||
423 | finally: | ||
424 | os.remove(path) | ||
321 | 425 | ||
322 | def _Clone(url, local, quiet): | 426 | def _Clone(url, local, quiet): |
323 | """Clones a git repository to a new subdirectory of repodir | 427 | """Clones a git repository to a new subdirectory of repodir |
@@ -345,11 +449,14 @@ def _Clone(url, local, quiet): | |||
345 | print >>sys.stderr, 'fatal: could not create %s' % local | 449 | print >>sys.stderr, 'fatal: could not create %s' % local |
346 | raise CloneFailure() | 450 | raise CloneFailure() |
347 | 451 | ||
452 | _InitHttp() | ||
348 | _SetConfig(local, 'remote.origin.url', url) | 453 | _SetConfig(local, 'remote.origin.url', url) |
349 | _SetConfig(local, 'remote.origin.fetch', | 454 | _SetConfig(local, 'remote.origin.fetch', |
350 | '+refs/heads/*:refs/remotes/origin/*') | 455 | '+refs/heads/*:refs/remotes/origin/*') |
351 | _Fetch(local, quiet) | 456 | if _DownloadBundle(url, local, quiet): |
352 | _Fetch(local, quiet, '--tags') | 457 | _ImportBundle(local) |
458 | else: | ||
459 | _Fetch(url, local, 'origin', quiet) | ||
353 | 460 | ||
354 | 461 | ||
355 | def _Verify(cwd, branch, quiet): | 462 | def _Verify(cwd, branch, quiet): |
@@ -601,4 +708,3 @@ def main(orig_args): | |||
601 | 708 | ||
602 | if __name__ == '__main__': | 709 | if __name__ == '__main__': |
603 | main(sys.argv[1:]) | 710 | main(sys.argv[1:]) |
604 | |||