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): |