diff options
Diffstat (limited to 'project.py')
| -rw-r--r-- | project.py | 45 | 
1 files changed, 35 insertions, 10 deletions
| @@ -484,7 +484,8 @@ class Project(object): | |||
| 484 | revisionId, | 484 | revisionId, | 
| 485 | rebase = True, | 485 | rebase = True, | 
| 486 | groups = None, | 486 | groups = None, | 
| 487 | sync_c = False): | 487 | sync_c = False, | 
| 488 | upstream = None): | ||
| 488 | self.manifest = manifest | 489 | self.manifest = manifest | 
| 489 | self.name = name | 490 | self.name = name | 
| 490 | self.remote = remote | 491 | self.remote = remote | 
| @@ -506,6 +507,7 @@ class Project(object): | |||
| 506 | self.rebase = rebase | 507 | self.rebase = rebase | 
| 507 | self.groups = groups | 508 | self.groups = groups | 
| 508 | self.sync_c = sync_c | 509 | self.sync_c = sync_c | 
| 510 | self.upstream = upstream | ||
| 509 | 511 | ||
| 510 | self.snapshots = {} | 512 | self.snapshots = {} | 
| 511 | self.copyfiles = [] | 513 | self.copyfiles = [] | 
| @@ -1373,6 +1375,16 @@ class Project(object): | |||
| 1373 | is_sha1 = False | 1375 | is_sha1 = False | 
| 1374 | tag_name = None | 1376 | tag_name = None | 
| 1375 | 1377 | ||
| 1378 | def CheckForSha1(): | ||
| 1379 | try: | ||
| 1380 | # if revision (sha or tag) is not present then following function | ||
| 1381 | # throws an error. | ||
| 1382 | self.bare_git.rev_parse('--verify', '%s^0' % self.revisionExpr) | ||
| 1383 | return True | ||
| 1384 | except GitError: | ||
| 1385 | # There is no such persistent revision. We have to fetch it. | ||
| 1386 | return False | ||
| 1387 | |||
| 1376 | if current_branch_only: | 1388 | if current_branch_only: | 
| 1377 | if ID_RE.match(self.revisionExpr) is not None: | 1389 | if ID_RE.match(self.revisionExpr) is not None: | 
| 1378 | is_sha1 = True | 1390 | is_sha1 = True | 
| @@ -1381,14 +1393,10 @@ class Project(object): | |||
| 1381 | tag_name = self.revisionExpr[len(R_TAGS):] | 1393 | tag_name = self.revisionExpr[len(R_TAGS):] | 
| 1382 | 1394 | ||
| 1383 | if is_sha1 or tag_name is not None: | 1395 | if is_sha1 or tag_name is not None: | 
| 1384 | try: | 1396 | if CheckForSha1(): | 
| 1385 | # if revision (sha or tag) is not present then following function | ||
| 1386 | # throws an error. | ||
| 1387 | self.bare_git.rev_parse('--verify', '%s^0' % self.revisionExpr) | ||
| 1388 | return True | 1397 | return True | 
| 1389 | except GitError: | 1398 | if is_sha1 and (not self.upstream or ID_RE.match(self.upstream)): | 
| 1390 | # There is no such persistent revision. We have to fetch it. | 1399 | current_branch_only = False | 
| 1391 | pass | ||
| 1392 | 1400 | ||
| 1393 | if not name: | 1401 | if not name: | 
| 1394 | name = self.remote.name | 1402 | name = self.remote.name | 
| @@ -1453,7 +1461,7 @@ class Project(object): | |||
| 1453 | cmd.append('--update-head-ok') | 1461 | cmd.append('--update-head-ok') | 
| 1454 | cmd.append(name) | 1462 | cmd.append(name) | 
| 1455 | 1463 | ||
| 1456 | if not current_branch_only or is_sha1: | 1464 | if not current_branch_only: | 
| 1457 | # Fetch whole repo | 1465 | # Fetch whole repo | 
| 1458 | cmd.append('--tags') | 1466 | cmd.append('--tags') | 
| 1459 | cmd.append((u'+refs/heads/*:') + remote.ToLocal('refs/heads/*')) | 1467 | cmd.append((u'+refs/heads/*:') + remote.ToLocal('refs/heads/*')) | 
| @@ -1462,15 +1470,23 @@ class Project(object): | |||
| 1462 | cmd.append(tag_name) | 1470 | cmd.append(tag_name) | 
| 1463 | else: | 1471 | else: | 
| 1464 | branch = self.revisionExpr | 1472 | branch = self.revisionExpr | 
| 1473 | if is_sha1: | ||
| 1474 | branch = self.upstream | ||
| 1465 | if branch.startswith(R_HEADS): | 1475 | if branch.startswith(R_HEADS): | 
| 1466 | branch = branch[len(R_HEADS):] | 1476 | branch = branch[len(R_HEADS):] | 
| 1467 | cmd.append((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch)) | 1477 | cmd.append((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch)) | 
| 1468 | 1478 | ||
| 1469 | ok = False | 1479 | ok = False | 
| 1470 | for i in range(2): | 1480 | for i in range(2): | 
| 1471 | if GitCommand(self, cmd, bare=True, ssh_proxy=ssh_proxy).Wait() == 0: | 1481 | ret = GitCommand(self, cmd, bare=True, ssh_proxy=ssh_proxy).Wait() | 
| 1482 | if ret == 0: | ||
| 1472 | ok = True | 1483 | ok = True | 
| 1473 | break | 1484 | break | 
| 1485 | elif current_branch_only and is_sha1 and ret == 128: | ||
| 1486 | # Exit code 128 means "couldn't find the ref you asked for"; if we're in sha1 | ||
| 1487 | # mode, we just tried sync'ing from the upstream field; it doesn't exist, thus | ||
| 1488 | # abort the optimization attempt and do a full sync. | ||
| 1489 | break | ||
| 1474 | time.sleep(random.randint(30, 45)) | 1490 | time.sleep(random.randint(30, 45)) | 
| 1475 | 1491 | ||
| 1476 | if initial: | 1492 | if initial: | 
| @@ -1480,6 +1496,15 @@ class Project(object): | |||
| 1480 | else: | 1496 | else: | 
| 1481 | os.remove(packed_refs) | 1497 | os.remove(packed_refs) | 
| 1482 | self.bare_git.pack_refs('--all', '--prune') | 1498 | self.bare_git.pack_refs('--all', '--prune') | 
| 1499 | |||
| 1500 | if is_sha1 and current_branch_only and self.upstream: | ||
| 1501 | # We just synced the upstream given branch; verify we | ||
| 1502 | # got what we wanted, else trigger a second run of all | ||
| 1503 | # refs. | ||
| 1504 | if not CheckForSha1(): | ||
| 1505 | return self._RemoteFetch(name=name, current_branch_only=False, | ||
| 1506 | initial=False, quiet=quiet, alt_dir=alt_dir) | ||
| 1507 | |||
| 1483 | return ok | 1508 | return ok | 
| 1484 | 1509 | ||
| 1485 | def _ApplyCloneBundle(self, initial=False, quiet=False): | 1510 | def _ApplyCloneBundle(self, initial=False, quiet=False): | 
