diff options
Diffstat (limited to 'project.py')
-rw-r--r-- | project.py | 136 |
1 files changed, 74 insertions, 62 deletions
@@ -16,10 +16,12 @@ import traceback | |||
16 | import errno | 16 | import errno |
17 | import filecmp | 17 | import filecmp |
18 | import os | 18 | import os |
19 | import random | ||
19 | import re | 20 | import re |
20 | import shutil | 21 | import shutil |
21 | import stat | 22 | import stat |
22 | import sys | 23 | import sys |
24 | import time | ||
23 | import urllib2 | 25 | import urllib2 |
24 | 26 | ||
25 | from color import Coloring | 27 | from color import Coloring |
@@ -894,9 +896,25 @@ class Project(object): | |||
894 | is_new = not self.Exists | 896 | is_new = not self.Exists |
895 | if is_new: | 897 | if is_new: |
896 | self._InitGitDir() | 898 | self._InitGitDir() |
897 | |||
898 | self._InitRemote() | 899 | self._InitRemote() |
899 | if not self._RemoteFetch(initial=is_new, quiet=quiet): | 900 | |
901 | if is_new: | ||
902 | alt = os.path.join(self.gitdir, 'objects/info/alternates') | ||
903 | try: | ||
904 | fd = open(alt, 'rb') | ||
905 | try: | ||
906 | alt_dir = fd.readline().rstrip() | ||
907 | finally: | ||
908 | fd.close() | ||
909 | except IOError: | ||
910 | alt_dir = None | ||
911 | else: | ||
912 | alt_dir = None | ||
913 | |||
914 | if alt_dir is None and self._ApplyCloneBundle(initial=is_new, quiet=quiet): | ||
915 | is_new = False | ||
916 | |||
917 | if not self._RemoteFetch(initial=is_new, quiet=quiet, alt_dir=alt_dir): | ||
900 | return False | 918 | return False |
901 | 919 | ||
902 | #Check that the requested ref was found after fetch | 920 | #Check that the requested ref was found after fetch |
@@ -1307,7 +1325,8 @@ class Project(object): | |||
1307 | 1325 | ||
1308 | def _RemoteFetch(self, name=None, tag=None, | 1326 | def _RemoteFetch(self, name=None, tag=None, |
1309 | initial=False, | 1327 | initial=False, |
1310 | quiet=False): | 1328 | quiet=False, |
1329 | alt_dir=None): | ||
1311 | if not name: | 1330 | if not name: |
1312 | name = self.remote.name | 1331 | name = self.remote.name |
1313 | 1332 | ||
@@ -1316,29 +1335,9 @@ class Project(object): | |||
1316 | if remote.PreConnectFetch(): | 1335 | if remote.PreConnectFetch(): |
1317 | ssh_proxy = True | 1336 | ssh_proxy = True |
1318 | 1337 | ||
1319 | bundle_dst = os.path.join(self.gitdir, 'clone.bundle') | ||
1320 | bundle_tmp = os.path.join(self.gitdir, 'clone.bundle.tmp') | ||
1321 | use_bundle = False | ||
1322 | if os.path.exists(bundle_dst) or os.path.exists(bundle_tmp): | ||
1323 | use_bundle = True | ||
1324 | |||
1325 | if initial: | 1338 | if initial: |
1326 | alt = os.path.join(self.gitdir, 'objects/info/alternates') | 1339 | if alt_dir and 'objects' == os.path.basename(alt_dir): |
1327 | try: | 1340 | ref_dir = os.path.dirname(alt_dir) |
1328 | fd = open(alt, 'rb') | ||
1329 | try: | ||
1330 | ref_dir = fd.readline() | ||
1331 | if ref_dir and ref_dir.endswith('\n'): | ||
1332 | ref_dir = ref_dir[:-1] | ||
1333 | finally: | ||
1334 | fd.close() | ||
1335 | except IOError, e: | ||
1336 | ref_dir = None | ||
1337 | |||
1338 | if ref_dir and 'objects' == os.path.basename(ref_dir): | ||
1339 | if use_bundle: | ||
1340 | use_bundle = False | ||
1341 | ref_dir = os.path.dirname(ref_dir) | ||
1342 | packed_refs = os.path.join(self.gitdir, 'packed-refs') | 1341 | packed_refs = os.path.join(self.gitdir, 'packed-refs') |
1343 | remote = self.GetRemote(name) | 1342 | remote = self.GetRemote(name) |
1344 | 1343 | ||
@@ -1374,10 +1373,8 @@ class Project(object): | |||
1374 | old_packed += line | 1373 | old_packed += line |
1375 | 1374 | ||
1376 | _lwrite(packed_refs, tmp_packed) | 1375 | _lwrite(packed_refs, tmp_packed) |
1377 | |||
1378 | else: | 1376 | else: |
1379 | ref_dir = None | 1377 | alt_dir = None |
1380 | use_bundle = True | ||
1381 | 1378 | ||
1382 | cmd = ['fetch'] | 1379 | cmd = ['fetch'] |
1383 | 1380 | ||
@@ -1386,59 +1383,74 @@ class Project(object): | |||
1386 | depth = self.manifest.manifestProject.config.GetString('repo.depth') | 1383 | depth = self.manifest.manifestProject.config.GetString('repo.depth') |
1387 | if depth and initial: | 1384 | if depth and initial: |
1388 | cmd.append('--depth=%s' % depth) | 1385 | cmd.append('--depth=%s' % depth) |
1389 | use_bundle = False | ||
1390 | 1386 | ||
1391 | if quiet: | 1387 | if quiet: |
1392 | cmd.append('--quiet') | 1388 | cmd.append('--quiet') |
1393 | if not self.worktree: | 1389 | if not self.worktree: |
1394 | cmd.append('--update-head-ok') | 1390 | cmd.append('--update-head-ok') |
1395 | 1391 | cmd.append(name) | |
1396 | if use_bundle and not os.path.exists(bundle_dst): | 1392 | if tag is not None: |
1397 | bundle_url = remote.url + '/clone.bundle' | 1393 | cmd.append('tag') |
1398 | bundle_url = GitConfig.ForUser().UrlInsteadOf(bundle_url) | 1394 | cmd.append(tag) |
1399 | if GetSchemeFromUrl(bundle_url) in ('http', 'https'): | 1395 | |
1400 | use_bundle = self._FetchBundle( | 1396 | ok = False |
1401 | bundle_url, | 1397 | for i in range(2): |
1402 | bundle_tmp, | 1398 | if GitCommand(self, cmd, bare=True, ssh_proxy=ssh_proxy).Wait() == 0: |
1403 | bundle_dst, | 1399 | ok = True |
1404 | quiet=quiet) | 1400 | break |
1405 | else: | 1401 | time.sleep(random.randint(30, 45)) |
1406 | use_bundle = False | ||
1407 | |||
1408 | if use_bundle: | ||
1409 | if not quiet: | ||
1410 | cmd.append('--quiet') | ||
1411 | cmd.append(bundle_dst) | ||
1412 | for f in remote.fetch: | ||
1413 | cmd.append(str(f)) | ||
1414 | cmd.append('refs/tags/*:refs/tags/*') | ||
1415 | else: | ||
1416 | cmd.append(name) | ||
1417 | if tag is not None: | ||
1418 | cmd.append('tag') | ||
1419 | cmd.append(tag) | ||
1420 | |||
1421 | ok = GitCommand(self, | ||
1422 | cmd, | ||
1423 | bare = True, | ||
1424 | ssh_proxy = ssh_proxy).Wait() == 0 | ||
1425 | 1402 | ||
1426 | if initial: | 1403 | if initial: |
1427 | if ref_dir: | 1404 | if alt_dir: |
1428 | if old_packed != '': | 1405 | if old_packed != '': |
1429 | _lwrite(packed_refs, old_packed) | 1406 | _lwrite(packed_refs, old_packed) |
1430 | else: | 1407 | else: |
1431 | os.remove(packed_refs) | 1408 | os.remove(packed_refs) |
1432 | self.bare_git.pack_refs('--all', '--prune') | 1409 | self.bare_git.pack_refs('--all', '--prune') |
1410 | return ok | ||
1411 | |||
1412 | def _ApplyCloneBundle(self, initial=False, quiet=False): | ||
1413 | if initial and self.manifest.manifestProject.config.GetString('repo.depth'): | ||
1414 | return False | ||
1415 | |||
1416 | remote = self.GetRemote(self.remote.name) | ||
1417 | bundle_url = remote.url + '/clone.bundle' | ||
1418 | bundle_url = GitConfig.ForUser().UrlInsteadOf(bundle_url) | ||
1419 | if GetSchemeFromUrl(bundle_url) not in ('http', 'https'): | ||
1420 | return False | ||
1421 | |||
1422 | bundle_dst = os.path.join(self.gitdir, 'clone.bundle') | ||
1423 | bundle_tmp = os.path.join(self.gitdir, 'clone.bundle.tmp') | ||
1433 | 1424 | ||
1425 | exist_dst = os.path.exists(bundle_dst) | ||
1426 | exist_tmp = os.path.exists(bundle_tmp) | ||
1427 | |||
1428 | if not initial and not exist_dst and not exist_tmp: | ||
1429 | return False | ||
1430 | |||
1431 | if not exist_dst: | ||
1432 | exist_dst = self._FetchBundle(bundle_url, bundle_tmp, bundle_dst, quiet) | ||
1433 | if not exist_dst: | ||
1434 | return False | ||
1435 | |||
1436 | cmd = ['fetch'] | ||
1437 | if quiet: | ||
1438 | cmd.append('--quiet') | ||
1439 | if not self.worktree: | ||
1440 | cmd.append('--update-head-ok') | ||
1441 | cmd.append(bundle_dst) | ||
1442 | for f in remote.fetch: | ||
1443 | cmd.append(str(f)) | ||
1444 | cmd.append('refs/tags/*:refs/tags/*') | ||
1445 | |||
1446 | ok = GitCommand(self, cmd, bare=True).Wait() == 0 | ||
1434 | if os.path.exists(bundle_dst): | 1447 | if os.path.exists(bundle_dst): |
1435 | os.remove(bundle_dst) | 1448 | os.remove(bundle_dst) |
1436 | if os.path.exists(bundle_tmp): | 1449 | if os.path.exists(bundle_tmp): |
1437 | os.remove(bundle_tmp) | 1450 | os.remove(bundle_tmp) |
1438 | |||
1439 | return ok | 1451 | return ok |
1440 | 1452 | ||
1441 | def _FetchBundle(self, srcUrl, tmpPath, dstPath, quiet=False): | 1453 | def _FetchBundle(self, srcUrl, tmpPath, dstPath, quiet): |
1442 | keep = True | 1454 | keep = True |
1443 | done = False | 1455 | done = False |
1444 | dest = open(tmpPath, 'a+b') | 1456 | dest = open(tmpPath, 'a+b') |