diff options
Diffstat (limited to 'project.py')
| -rw-r--r-- | project.py | 164 |
1 files changed, 120 insertions, 44 deletions
| @@ -36,6 +36,12 @@ from trace import IsTrace, Trace | |||
| 36 | 36 | ||
| 37 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M | 37 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M |
| 38 | 38 | ||
| 39 | from pyversion import is_python3 | ||
| 40 | if not is_python3(): | ||
| 41 | # pylint:disable=W0622 | ||
| 42 | input = raw_input | ||
| 43 | # pylint:enable=W0622 | ||
| 44 | |||
| 39 | def _lwrite(path, content): | 45 | def _lwrite(path, content): |
| 40 | lock = '%s.lock' % path | 46 | lock = '%s.lock' % path |
| 41 | 47 | ||
| @@ -78,7 +84,7 @@ def _ProjectHooks(): | |||
| 78 | if _project_hook_list is None: | 84 | if _project_hook_list is None: |
| 79 | d = os.path.abspath(os.path.dirname(__file__)) | 85 | d = os.path.abspath(os.path.dirname(__file__)) |
| 80 | d = os.path.join(d , 'hooks') | 86 | d = os.path.join(d , 'hooks') |
| 81 | _project_hook_list = map(lambda x: os.path.join(d, x), os.listdir(d)) | 87 | _project_hook_list = [os.path.join(d, x) for x in os.listdir(d)] |
| 82 | return _project_hook_list | 88 | return _project_hook_list |
| 83 | 89 | ||
| 84 | 90 | ||
| @@ -151,11 +157,12 @@ class ReviewableBranch(object): | |||
| 151 | R_HEADS + self.name, | 157 | R_HEADS + self.name, |
| 152 | '--') | 158 | '--') |
| 153 | 159 | ||
| 154 | def UploadForReview(self, people, auto_topic=False, draft=False): | 160 | def UploadForReview(self, people, auto_topic=False, draft=False, dest_branch=None): |
| 155 | self.project.UploadForReview(self.name, | 161 | self.project.UploadForReview(self.name, |
| 156 | people, | 162 | people, |
| 157 | auto_topic=auto_topic, | 163 | auto_topic=auto_topic, |
| 158 | draft=draft) | 164 | draft=draft, |
| 165 | dest_branch=dest_branch) | ||
| 159 | 166 | ||
| 160 | def GetPublishedRefs(self): | 167 | def GetPublishedRefs(self): |
| 161 | refs = {} | 168 | refs = {} |
| @@ -361,7 +368,7 @@ class RepoHook(object): | |||
| 361 | 'Do you want to allow this script to run ' | 368 | 'Do you want to allow this script to run ' |
| 362 | '(yes/yes-never-ask-again/NO)? ') % ( | 369 | '(yes/yes-never-ask-again/NO)? ') % ( |
| 363 | self._GetMustVerb(), self._script_fullpath) | 370 | self._GetMustVerb(), self._script_fullpath) |
| 364 | response = raw_input(prompt).lower() | 371 | response = input(prompt).lower() |
| 365 | print() | 372 | print() |
| 366 | 373 | ||
| 367 | # User is doing a one-time approval. | 374 | # User is doing a one-time approval. |
| @@ -488,9 +495,11 @@ class Project(object): | |||
| 488 | groups = None, | 495 | groups = None, |
| 489 | sync_c = False, | 496 | sync_c = False, |
| 490 | sync_s = False, | 497 | sync_s = False, |
| 498 | clone_depth = None, | ||
| 491 | upstream = None, | 499 | upstream = None, |
| 492 | parent = None, | 500 | parent = None, |
| 493 | is_derived = False): | 501 | is_derived = False, |
| 502 | dest_branch = None): | ||
| 494 | """Init a Project object. | 503 | """Init a Project object. |
| 495 | 504 | ||
| 496 | Args: | 505 | Args: |
| @@ -510,6 +519,7 @@ class Project(object): | |||
| 510 | parent: The parent Project object. | 519 | parent: The parent Project object. |
| 511 | is_derived: False if the project was explicitly defined in the manifest; | 520 | is_derived: False if the project was explicitly defined in the manifest; |
| 512 | True if the project is a discovered submodule. | 521 | True if the project is a discovered submodule. |
| 522 | dest_branch: The branch to which to push changes for review by default. | ||
| 513 | """ | 523 | """ |
| 514 | self.manifest = manifest | 524 | self.manifest = manifest |
| 515 | self.name = name | 525 | self.name = name |
| @@ -533,6 +543,7 @@ class Project(object): | |||
| 533 | self.groups = groups | 543 | self.groups = groups |
| 534 | self.sync_c = sync_c | 544 | self.sync_c = sync_c |
| 535 | self.sync_s = sync_s | 545 | self.sync_s = sync_s |
| 546 | self.clone_depth = clone_depth | ||
| 536 | self.upstream = upstream | 547 | self.upstream = upstream |
| 537 | self.parent = parent | 548 | self.parent = parent |
| 538 | self.is_derived = is_derived | 549 | self.is_derived = is_derived |
| @@ -551,6 +562,7 @@ class Project(object): | |||
| 551 | self.work_git = None | 562 | self.work_git = None |
| 552 | self.bare_git = self._GitGetByExec(self, bare=True) | 563 | self.bare_git = self._GitGetByExec(self, bare=True) |
| 553 | self.bare_ref = GitRefs(gitdir) | 564 | self.bare_ref = GitRefs(gitdir) |
| 565 | self.dest_branch = dest_branch | ||
| 554 | 566 | ||
| 555 | # This will be filled in if a project is later identified to be the | 567 | # This will be filled in if a project is later identified to be the |
| 556 | # project containing repo hooks. | 568 | # project containing repo hooks. |
| @@ -644,7 +656,7 @@ class Project(object): | |||
| 644 | all_refs = self._allrefs | 656 | all_refs = self._allrefs |
| 645 | heads = {} | 657 | heads = {} |
| 646 | 658 | ||
| 647 | for name, ref_id in all_refs.iteritems(): | 659 | for name, ref_id in all_refs.items(): |
| 648 | if name.startswith(R_HEADS): | 660 | if name.startswith(R_HEADS): |
| 649 | name = name[len(R_HEADS):] | 661 | name = name[len(R_HEADS):] |
| 650 | b = self.GetBranch(name) | 662 | b = self.GetBranch(name) |
| @@ -653,7 +665,7 @@ class Project(object): | |||
| 653 | b.revision = ref_id | 665 | b.revision = ref_id |
| 654 | heads[name] = b | 666 | heads[name] = b |
| 655 | 667 | ||
| 656 | for name, ref_id in all_refs.iteritems(): | 668 | for name, ref_id in all_refs.items(): |
| 657 | if name.startswith(R_PUB): | 669 | if name.startswith(R_PUB): |
| 658 | name = name[len(R_PUB):] | 670 | name = name[len(R_PUB):] |
| 659 | b = heads.get(name) | 671 | b = heads.get(name) |
| @@ -672,9 +684,14 @@ class Project(object): | |||
| 672 | project_groups: "all,group1,group2" | 684 | project_groups: "all,group1,group2" |
| 673 | manifest_groups: "-group1,group2" | 685 | manifest_groups: "-group1,group2" |
| 674 | the project will be matched. | 686 | the project will be matched. |
| 687 | |||
| 688 | The special manifest group "default" will match any project that | ||
| 689 | does not have the special project group "notdefault" | ||
| 675 | """ | 690 | """ |
| 676 | expanded_manifest_groups = manifest_groups or ['all', '-notdefault'] | 691 | expanded_manifest_groups = manifest_groups or ['default'] |
| 677 | expanded_project_groups = ['all'] + (self.groups or []) | 692 | expanded_project_groups = ['all'] + (self.groups or []) |
| 693 | if not 'notdefault' in expanded_project_groups: | ||
| 694 | expanded_project_groups += ['default'] | ||
| 678 | 695 | ||
| 679 | matched = False | 696 | matched = False |
| 680 | for group in expanded_manifest_groups: | 697 | for group in expanded_manifest_groups: |
| @@ -754,10 +771,7 @@ class Project(object): | |||
| 754 | paths.extend(df.keys()) | 771 | paths.extend(df.keys()) |
| 755 | paths.extend(do) | 772 | paths.extend(do) |
| 756 | 773 | ||
| 757 | paths = list(set(paths)) | 774 | for p in sorted(set(paths)): |
| 758 | paths.sort() | ||
| 759 | |||
| 760 | for p in paths: | ||
| 761 | try: | 775 | try: |
| 762 | i = di[p] | 776 | i = di[p] |
| 763 | except KeyError: | 777 | except KeyError: |
| @@ -849,13 +863,13 @@ class Project(object): | |||
| 849 | all_refs = self._allrefs | 863 | all_refs = self._allrefs |
| 850 | heads = set() | 864 | heads = set() |
| 851 | canrm = {} | 865 | canrm = {} |
| 852 | for name, ref_id in all_refs.iteritems(): | 866 | for name, ref_id in all_refs.items(): |
| 853 | if name.startswith(R_HEADS): | 867 | if name.startswith(R_HEADS): |
| 854 | heads.add(name) | 868 | heads.add(name) |
| 855 | elif name.startswith(R_PUB): | 869 | elif name.startswith(R_PUB): |
| 856 | canrm[name] = ref_id | 870 | canrm[name] = ref_id |
| 857 | 871 | ||
| 858 | for name, ref_id in canrm.iteritems(): | 872 | for name, ref_id in canrm.items(): |
| 859 | n = name[len(R_PUB):] | 873 | n = name[len(R_PUB):] |
| 860 | if R_HEADS + n not in heads: | 874 | if R_HEADS + n not in heads: |
| 861 | self.bare_git.DeleteRef(name, ref_id) | 875 | self.bare_git.DeleteRef(name, ref_id) |
| @@ -866,14 +880,14 @@ class Project(object): | |||
| 866 | heads = {} | 880 | heads = {} |
| 867 | pubed = {} | 881 | pubed = {} |
| 868 | 882 | ||
| 869 | for name, ref_id in self._allrefs.iteritems(): | 883 | for name, ref_id in self._allrefs.items(): |
| 870 | if name.startswith(R_HEADS): | 884 | if name.startswith(R_HEADS): |
| 871 | heads[name[len(R_HEADS):]] = ref_id | 885 | heads[name[len(R_HEADS):]] = ref_id |
| 872 | elif name.startswith(R_PUB): | 886 | elif name.startswith(R_PUB): |
| 873 | pubed[name[len(R_PUB):]] = ref_id | 887 | pubed[name[len(R_PUB):]] = ref_id |
| 874 | 888 | ||
| 875 | ready = [] | 889 | ready = [] |
| 876 | for branch, ref_id in heads.iteritems(): | 890 | for branch, ref_id in heads.items(): |
| 877 | if branch in pubed and pubed[branch] == ref_id: | 891 | if branch in pubed and pubed[branch] == ref_id: |
| 878 | continue | 892 | continue |
| 879 | if selected_branch and branch != selected_branch: | 893 | if selected_branch and branch != selected_branch: |
| @@ -898,7 +912,8 @@ class Project(object): | |||
| 898 | def UploadForReview(self, branch=None, | 912 | def UploadForReview(self, branch=None, |
| 899 | people=([],[]), | 913 | people=([],[]), |
| 900 | auto_topic=False, | 914 | auto_topic=False, |
| 901 | draft=False): | 915 | draft=False, |
| 916 | dest_branch=None): | ||
| 902 | """Uploads the named branch for code review. | 917 | """Uploads the named branch for code review. |
| 903 | """ | 918 | """ |
| 904 | if branch is None: | 919 | if branch is None: |
| @@ -912,7 +927,10 @@ class Project(object): | |||
| 912 | if not branch.remote.review: | 927 | if not branch.remote.review: |
| 913 | raise GitError('remote %s has no review url' % branch.remote.name) | 928 | raise GitError('remote %s has no review url' % branch.remote.name) |
| 914 | 929 | ||
| 915 | dest_branch = branch.merge | 930 | if dest_branch is None: |
| 931 | dest_branch = self.dest_branch | ||
| 932 | if dest_branch is None: | ||
| 933 | dest_branch = branch.merge | ||
| 916 | if not dest_branch.startswith(R_HEADS): | 934 | if not dest_branch.startswith(R_HEADS): |
| 917 | dest_branch = R_HEADS + dest_branch | 935 | dest_branch = R_HEADS + dest_branch |
| 918 | 936 | ||
| @@ -977,6 +995,8 @@ class Project(object): | |||
| 977 | is_new = not self.Exists | 995 | is_new = not self.Exists |
| 978 | if is_new: | 996 | if is_new: |
| 979 | self._InitGitDir() | 997 | self._InitGitDir() |
| 998 | else: | ||
| 999 | self._UpdateHooks() | ||
| 980 | self._InitRemote() | 1000 | self._InitRemote() |
| 981 | 1001 | ||
| 982 | if is_new: | 1002 | if is_new: |
| @@ -1216,7 +1236,6 @@ class Project(object): | |||
| 1216 | cmd = ['fetch', remote.name] | 1236 | cmd = ['fetch', remote.name] |
| 1217 | cmd.append('refs/changes/%2.2d/%d/%d' \ | 1237 | cmd.append('refs/changes/%2.2d/%d/%d' \ |
| 1218 | % (change_id % 100, change_id, patch_id)) | 1238 | % (change_id % 100, change_id, patch_id)) |
| 1219 | cmd.extend(map(str, remote.fetch)) | ||
| 1220 | if GitCommand(self, cmd, bare=True).Wait() != 0: | 1239 | if GitCommand(self, cmd, bare=True).Wait() != 0: |
| 1221 | return None | 1240 | return None |
| 1222 | return DownloadedChange(self, | 1241 | return DownloadedChange(self, |
| @@ -1605,7 +1624,7 @@ class Project(object): | |||
| 1605 | ids = set(all_refs.values()) | 1624 | ids = set(all_refs.values()) |
| 1606 | tmp = set() | 1625 | tmp = set() |
| 1607 | 1626 | ||
| 1608 | for r, ref_id in GitRefs(ref_dir).all.iteritems(): | 1627 | for r, ref_id in GitRefs(ref_dir).all.items(): |
| 1609 | if r not in all_refs: | 1628 | if r not in all_refs: |
| 1610 | if r.startswith(R_TAGS) or remote.WritesTo(r): | 1629 | if r.startswith(R_TAGS) or remote.WritesTo(r): |
| 1611 | all_refs[r] = ref_id | 1630 | all_refs[r] = ref_id |
| @@ -1620,13 +1639,10 @@ class Project(object): | |||
| 1620 | ids.add(ref_id) | 1639 | ids.add(ref_id) |
| 1621 | tmp.add(r) | 1640 | tmp.add(r) |
| 1622 | 1641 | ||
| 1623 | ref_names = list(all_refs.keys()) | ||
| 1624 | ref_names.sort() | ||
| 1625 | |||
| 1626 | tmp_packed = '' | 1642 | tmp_packed = '' |
| 1627 | old_packed = '' | 1643 | old_packed = '' |
| 1628 | 1644 | ||
| 1629 | for r in ref_names: | 1645 | for r in sorted(all_refs): |
| 1630 | line = '%s %s\n' % (all_refs[r], r) | 1646 | line = '%s %s\n' % (all_refs[r], r) |
| 1631 | tmp_packed += line | 1647 | tmp_packed += line |
| 1632 | if r not in tmp: | 1648 | if r not in tmp: |
| @@ -1640,7 +1656,10 @@ class Project(object): | |||
| 1640 | 1656 | ||
| 1641 | # The --depth option only affects the initial fetch; after that we'll do | 1657 | # The --depth option only affects the initial fetch; after that we'll do |
| 1642 | # full fetches of changes. | 1658 | # full fetches of changes. |
| 1643 | depth = self.manifest.manifestProject.config.GetString('repo.depth') | 1659 | if self.clone_depth: |
| 1660 | depth = self.clone_depth | ||
| 1661 | else: | ||
| 1662 | depth = self.manifest.manifestProject.config.GetString('repo.depth') | ||
| 1644 | if depth and initial: | 1663 | if depth and initial: |
| 1645 | cmd.append('--depth=%s' % depth) | 1664 | cmd.append('--depth=%s' % depth) |
| 1646 | 1665 | ||
| @@ -1652,11 +1671,13 @@ class Project(object): | |||
| 1652 | 1671 | ||
| 1653 | if not current_branch_only: | 1672 | if not current_branch_only: |
| 1654 | # Fetch whole repo | 1673 | # Fetch whole repo |
| 1655 | if no_tags: | 1674 | # If using depth then we should not get all the tags since they may |
| 1675 | # be outside of the depth. | ||
| 1676 | if no_tags or depth: | ||
| 1656 | cmd.append('--no-tags') | 1677 | cmd.append('--no-tags') |
| 1657 | else: | 1678 | else: |
| 1658 | cmd.append('--tags') | 1679 | cmd.append('--tags') |
| 1659 | cmd.append((u'+refs/heads/*:') + remote.ToLocal('refs/heads/*')) | 1680 | cmd.append(str((u'+refs/heads/*:') + remote.ToLocal('refs/heads/*'))) |
| 1660 | elif tag_name is not None: | 1681 | elif tag_name is not None: |
| 1661 | cmd.append('tag') | 1682 | cmd.append('tag') |
| 1662 | cmd.append(tag_name) | 1683 | cmd.append(tag_name) |
| @@ -1666,7 +1687,7 @@ class Project(object): | |||
| 1666 | branch = self.upstream | 1687 | branch = self.upstream |
| 1667 | if branch.startswith(R_HEADS): | 1688 | if branch.startswith(R_HEADS): |
| 1668 | branch = branch[len(R_HEADS):] | 1689 | branch = branch[len(R_HEADS):] |
| 1669 | cmd.append((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch)) | 1690 | cmd.append(str((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch))) |
| 1670 | 1691 | ||
| 1671 | ok = False | 1692 | ok = False |
| 1672 | for _i in range(2): | 1693 | for _i in range(2): |
| @@ -1700,15 +1721,14 @@ class Project(object): | |||
| 1700 | return ok | 1721 | return ok |
| 1701 | 1722 | ||
| 1702 | def _ApplyCloneBundle(self, initial=False, quiet=False): | 1723 | def _ApplyCloneBundle(self, initial=False, quiet=False): |
| 1703 | if initial and self.manifest.manifestProject.config.GetString('repo.depth'): | 1724 | if initial and (self.manifest.manifestProject.config.GetString('repo.depth') or self.clone_depth): |
| 1704 | return False | 1725 | return False |
| 1705 | 1726 | ||
| 1706 | remote = self.GetRemote(self.remote.name) | 1727 | remote = self.GetRemote(self.remote.name) |
| 1707 | bundle_url = remote.url + '/clone.bundle' | 1728 | bundle_url = remote.url + '/clone.bundle' |
| 1708 | bundle_url = GitConfig.ForUser().UrlInsteadOf(bundle_url) | 1729 | bundle_url = GitConfig.ForUser().UrlInsteadOf(bundle_url) |
| 1709 | if GetSchemeFromUrl(bundle_url) in ('persistent-http', 'persistent-https'): | 1730 | if GetSchemeFromUrl(bundle_url) not in ( |
| 1710 | bundle_url = bundle_url[len('persistent-'):] | 1731 | 'http', 'https', 'persistent-http', 'persistent-https'): |
| 1711 | if GetSchemeFromUrl(bundle_url) not in ('http', 'https'): | ||
| 1712 | return False | 1732 | return False |
| 1713 | 1733 | ||
| 1714 | bundle_dst = os.path.join(self.gitdir, 'clone.bundle') | 1734 | bundle_dst = os.path.join(self.gitdir, 'clone.bundle') |
| @@ -1757,9 +1777,11 @@ class Project(object): | |||
| 1757 | os.remove(tmpPath) | 1777 | os.remove(tmpPath) |
| 1758 | if 'http_proxy' in os.environ and 'darwin' == sys.platform: | 1778 | if 'http_proxy' in os.environ and 'darwin' == sys.platform: |
| 1759 | cmd += ['--proxy', os.environ['http_proxy']] | 1779 | cmd += ['--proxy', os.environ['http_proxy']] |
| 1760 | cookiefile = GitConfig.ForUser().GetString('http.cookiefile') | 1780 | cookiefile = self._GetBundleCookieFile(srcUrl) |
| 1761 | if cookiefile: | 1781 | if cookiefile: |
| 1762 | cmd += ['--cookie', cookiefile] | 1782 | cmd += ['--cookie', cookiefile] |
| 1783 | if srcUrl.startswith('persistent-'): | ||
| 1784 | srcUrl = srcUrl[len('persistent-'):] | ||
| 1763 | cmd += [srcUrl] | 1785 | cmd += [srcUrl] |
| 1764 | 1786 | ||
| 1765 | if IsTrace(): | 1787 | if IsTrace(): |
| @@ -1782,7 +1804,7 @@ class Project(object): | |||
| 1782 | return False | 1804 | return False |
| 1783 | 1805 | ||
| 1784 | if os.path.exists(tmpPath): | 1806 | if os.path.exists(tmpPath): |
| 1785 | if curlret == 0 and os.stat(tmpPath).st_size > 16: | 1807 | if curlret == 0 and self._IsValidBundle(tmpPath): |
| 1786 | os.rename(tmpPath, dstPath) | 1808 | os.rename(tmpPath, dstPath) |
| 1787 | return True | 1809 | return True |
| 1788 | else: | 1810 | else: |
| @@ -1791,6 +1813,46 @@ class Project(object): | |||
| 1791 | else: | 1813 | else: |
| 1792 | return False | 1814 | return False |
| 1793 | 1815 | ||
| 1816 | def _IsValidBundle(self, path): | ||
| 1817 | try: | ||
| 1818 | with open(path) as f: | ||
| 1819 | if f.read(16) == '# v2 git bundle\n': | ||
| 1820 | return True | ||
| 1821 | else: | ||
| 1822 | print("Invalid clone.bundle file; ignoring.", file=sys.stderr) | ||
| 1823 | return False | ||
| 1824 | except OSError: | ||
| 1825 | return False | ||
| 1826 | |||
| 1827 | def _GetBundleCookieFile(self, url): | ||
| 1828 | if url.startswith('persistent-'): | ||
| 1829 | try: | ||
| 1830 | p = subprocess.Popen( | ||
| 1831 | ['git-remote-persistent-https', '-print_config', url], | ||
| 1832 | stdin=subprocess.PIPE, stdout=subprocess.PIPE, | ||
| 1833 | stderr=subprocess.PIPE) | ||
| 1834 | p.stdin.close() # Tell subprocess it's ok to close. | ||
| 1835 | prefix = 'http.cookiefile=' | ||
| 1836 | cookiefile = None | ||
| 1837 | for line in p.stdout: | ||
| 1838 | line = line.strip() | ||
| 1839 | if line.startswith(prefix): | ||
| 1840 | cookiefile = line[len(prefix):] | ||
| 1841 | break | ||
| 1842 | if p.wait(): | ||
| 1843 | line = iter(p.stderr).next() | ||
| 1844 | if ' -print_config' in line: | ||
| 1845 | pass # Persistent proxy doesn't support -print_config. | ||
| 1846 | else: | ||
| 1847 | print(line + p.stderr.read(), file=sys.stderr) | ||
| 1848 | if cookiefile: | ||
| 1849 | return cookiefile | ||
| 1850 | except OSError as e: | ||
| 1851 | if e.errno == errno.ENOENT: | ||
| 1852 | pass # No persistent proxy. | ||
| 1853 | raise | ||
| 1854 | return GitConfig.ForUser().GetString('http.cookiefile') | ||
| 1855 | |||
| 1794 | def _Checkout(self, rev, quiet=False): | 1856 | def _Checkout(self, rev, quiet=False): |
| 1795 | cmd = ['checkout'] | 1857 | cmd = ['checkout'] |
| 1796 | if quiet: | 1858 | if quiet: |
| @@ -1841,16 +1903,17 @@ class Project(object): | |||
| 1841 | if GitCommand(self, cmd).Wait() != 0: | 1903 | if GitCommand(self, cmd).Wait() != 0: |
| 1842 | raise GitError('%s merge %s ' % (self.name, head)) | 1904 | raise GitError('%s merge %s ' % (self.name, head)) |
| 1843 | 1905 | ||
| 1844 | def _InitGitDir(self): | 1906 | def _InitGitDir(self, mirror_git=None): |
| 1845 | if not os.path.exists(self.gitdir): | 1907 | if not os.path.exists(self.gitdir): |
| 1846 | os.makedirs(self.gitdir) | 1908 | os.makedirs(self.gitdir) |
| 1847 | self.bare_git.init() | 1909 | self.bare_git.init() |
| 1848 | 1910 | ||
| 1849 | mp = self.manifest.manifestProject | 1911 | mp = self.manifest.manifestProject |
| 1850 | ref_dir = mp.config.GetString('repo.reference') | 1912 | ref_dir = mp.config.GetString('repo.reference') or '' |
| 1851 | 1913 | ||
| 1852 | if ref_dir: | 1914 | if ref_dir or mirror_git: |
| 1853 | mirror_git = os.path.join(ref_dir, self.name + '.git') | 1915 | if not mirror_git: |
| 1916 | mirror_git = os.path.join(ref_dir, self.name + '.git') | ||
| 1854 | repo_git = os.path.join(ref_dir, '.repo', 'projects', | 1917 | repo_git = os.path.join(ref_dir, '.repo', 'projects', |
| 1855 | self.relpath + '.git') | 1918 | self.relpath + '.git') |
| 1856 | 1919 | ||
| @@ -1867,11 +1930,21 @@ class Project(object): | |||
| 1867 | _lwrite(os.path.join(self.gitdir, 'objects/info/alternates'), | 1930 | _lwrite(os.path.join(self.gitdir, 'objects/info/alternates'), |
| 1868 | os.path.join(ref_dir, 'objects') + '\n') | 1931 | os.path.join(ref_dir, 'objects') + '\n') |
| 1869 | 1932 | ||
| 1933 | self._UpdateHooks() | ||
| 1934 | |||
| 1935 | m = self.manifest.manifestProject.config | ||
| 1936 | for key in ['user.name', 'user.email']: | ||
| 1937 | if m.Has(key, include_defaults = False): | ||
| 1938 | self.config.SetString(key, m.GetString(key)) | ||
| 1870 | if self.manifest.IsMirror: | 1939 | if self.manifest.IsMirror: |
| 1871 | self.config.SetString('core.bare', 'true') | 1940 | self.config.SetString('core.bare', 'true') |
| 1872 | else: | 1941 | else: |
| 1873 | self.config.SetString('core.bare', None) | 1942 | self.config.SetString('core.bare', None) |
| 1874 | 1943 | ||
| 1944 | def _UpdateHooks(self): | ||
| 1945 | if os.path.exists(self.gitdir): | ||
| 1946 | # Always recreate hooks since they can have been changed | ||
| 1947 | # since the latest update. | ||
| 1875 | hooks = self._gitdir_path('hooks') | 1948 | hooks = self._gitdir_path('hooks') |
| 1876 | try: | 1949 | try: |
| 1877 | to_rm = os.listdir(hooks) | 1950 | to_rm = os.listdir(hooks) |
| @@ -1881,11 +1954,6 @@ class Project(object): | |||
| 1881 | os.remove(os.path.join(hooks, old_hook)) | 1954 | os.remove(os.path.join(hooks, old_hook)) |
| 1882 | self._InitHooks() | 1955 | self._InitHooks() |
| 1883 | 1956 | ||
| 1884 | m = self.manifest.manifestProject.config | ||
| 1885 | for key in ['user.name', 'user.email']: | ||
| 1886 | if m.Has(key, include_defaults = False): | ||
| 1887 | self.config.SetString(key, m.GetString(key)) | ||
| 1888 | |||
| 1889 | def _InitHooks(self): | 1957 | def _InitHooks(self): |
| 1890 | hooks = self._gitdir_path('hooks') | 1958 | hooks = self._gitdir_path('hooks') |
| 1891 | if not os.path.exists(hooks): | 1959 | if not os.path.exists(hooks): |
| @@ -2092,6 +2160,10 @@ class Project(object): | |||
| 2092 | line = fd.read() | 2160 | line = fd.read() |
| 2093 | finally: | 2161 | finally: |
| 2094 | fd.close() | 2162 | fd.close() |
| 2163 | try: | ||
| 2164 | line = line.decode() | ||
| 2165 | except AttributeError: | ||
| 2166 | pass | ||
| 2095 | if line.startswith('ref: '): | 2167 | if line.startswith('ref: '): |
| 2096 | return line[5:-1] | 2168 | return line[5:-1] |
| 2097 | return line[:-1] | 2169 | return line[:-1] |
| @@ -2185,7 +2257,7 @@ class Project(object): | |||
| 2185 | if not git_require((1, 7, 2)): | 2257 | if not git_require((1, 7, 2)): |
| 2186 | raise ValueError('cannot set config on command line for %s()' | 2258 | raise ValueError('cannot set config on command line for %s()' |
| 2187 | % name) | 2259 | % name) |
| 2188 | for k, v in config.iteritems(): | 2260 | for k, v in config.items(): |
| 2189 | cmdv.append('-c') | 2261 | cmdv.append('-c') |
| 2190 | cmdv.append('%s=%s' % (k, v)) | 2262 | cmdv.append('%s=%s' % (k, v)) |
| 2191 | cmdv.append(name) | 2263 | cmdv.append(name) |
| @@ -2201,6 +2273,10 @@ class Project(object): | |||
| 2201 | name, | 2273 | name, |
| 2202 | p.stderr)) | 2274 | p.stderr)) |
| 2203 | r = p.stdout | 2275 | r = p.stdout |
| 2276 | try: | ||
| 2277 | r = r.decode('utf-8') | ||
| 2278 | except AttributeError: | ||
| 2279 | pass | ||
| 2204 | if r.endswith('\n') and r.index('\n') == len(r) - 1: | 2280 | if r.endswith('\n') and r.index('\n') == len(r) - 1: |
| 2205 | return r[:-1] | 2281 | return r[:-1] |
| 2206 | return r | 2282 | return r |
