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 |