diff options
| author | Brian Harring <ferringb@google.com> | 2012-09-28 20:21:57 -0700 |
|---|---|---|
| committer | Brian Harring <ferringb@google.com> | 2012-09-28 22:31:27 -0700 |
| commit | 14a6674e32b3000dbe8b7c96b0d1bb4fb0021720 (patch) | |
| tree | 024482226fefd4c188f20f56047325b69d388a9f /project.py | |
| parent | 34acdd253439448b6c08c3abfc5e7b8bd03f383f (diff) | |
| download | git-repo-14a6674e32b3000dbe8b7c96b0d1bb4fb0021720.tar.gz | |
manifest: record the original revision when in -r mode.
Currently when doing a sync against a revision locked manifest,
sync has no option but to fall back to sync'ing the entire refs space;
it doesn't know which ref to ask for that contains the sha1 it wants.
This sucks if we're in -c mode; thus when we generate a revision
locked manifest, record the originating branch- and try syncing that
branch first. If the sha1 is found within that branch, this saves
us having to pull down the rest of the repo- a potentially heavy
saving.
If that branch doesn't have the desired sha1, we fallback to sync'ing
everything.
Change-Id: I99a5e44fa1d792dfcada76956a2363187df94cf1
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): |
