summaryrefslogtreecommitdiffstats
path: root/project.py
diff options
context:
space:
mode:
Diffstat (limited to 'project.py')
-rw-r--r--project.py314
1 files changed, 156 insertions, 158 deletions
diff --git a/project.py b/project.py
index b9a53dce..49db02e3 100644
--- a/project.py
+++ b/project.py
@@ -13,7 +13,7 @@
13# limitations under the License. 13# limitations under the License.
14 14
15from __future__ import print_function 15from __future__ import print_function
16import traceback 16import contextlib
17import errno 17import errno
18import filecmp 18import filecmp
19import os 19import os
@@ -26,6 +26,7 @@ import sys
26import tarfile 26import tarfile
27import tempfile 27import tempfile
28import time 28import time
29import traceback
29 30
30from color import Coloring 31from color import Coloring
31from git_command import GitCommand, git_require 32from git_command import GitCommand, git_require
@@ -84,7 +85,7 @@ def _ProjectHooks():
84 global _project_hook_list 85 global _project_hook_list
85 if _project_hook_list is None: 86 if _project_hook_list is None:
86 d = os.path.realpath(os.path.abspath(os.path.dirname(__file__))) 87 d = os.path.realpath(os.path.abspath(os.path.dirname(__file__)))
87 d = os.path.join(d , 'hooks') 88 d = os.path.join(d, 'hooks')
88 _project_hook_list = [os.path.join(d, x) for x in os.listdir(d)] 89 _project_hook_list = [os.path.join(d, x) for x in os.listdir(d)]
89 return _project_hook_list 90 return _project_hook_list
90 91
@@ -182,28 +183,28 @@ class ReviewableBranch(object):
182class StatusColoring(Coloring): 183class StatusColoring(Coloring):
183 def __init__(self, config): 184 def __init__(self, config):
184 Coloring.__init__(self, config, 'status') 185 Coloring.__init__(self, config, 'status')
185 self.project = self.printer('header', attr = 'bold') 186 self.project = self.printer('header', attr='bold')
186 self.branch = self.printer('header', attr = 'bold') 187 self.branch = self.printer('header', attr='bold')
187 self.nobranch = self.printer('nobranch', fg = 'red') 188 self.nobranch = self.printer('nobranch', fg='red')
188 self.important = self.printer('important', fg = 'red') 189 self.important = self.printer('important', fg='red')
189 190
190 self.added = self.printer('added', fg = 'green') 191 self.added = self.printer('added', fg='green')
191 self.changed = self.printer('changed', fg = 'red') 192 self.changed = self.printer('changed', fg='red')
192 self.untracked = self.printer('untracked', fg = 'red') 193 self.untracked = self.printer('untracked', fg='red')
193 194
194 195
195class DiffColoring(Coloring): 196class DiffColoring(Coloring):
196 def __init__(self, config): 197 def __init__(self, config):
197 Coloring.__init__(self, config, 'diff') 198 Coloring.__init__(self, config, 'diff')
198 self.project = self.printer('header', attr = 'bold') 199 self.project = self.printer('header', attr='bold')
199 200
200class _Annotation: 201class _Annotation(object):
201 def __init__(self, name, value, keep): 202 def __init__(self, name, value, keep):
202 self.name = name 203 self.name = name
203 self.value = value 204 self.value = value
204 self.keep = keep 205 self.keep = keep
205 206
206class _CopyFile: 207class _CopyFile(object):
207 def __init__(self, src, dest, abssrc, absdest): 208 def __init__(self, src, dest, abssrc, absdest):
208 self.src = src 209 self.src = src
209 self.dest = dest 210 self.dest = dest
@@ -231,7 +232,7 @@ class _CopyFile:
231 except IOError: 232 except IOError:
232 _error('Cannot copy file %s to %s', src, dest) 233 _error('Cannot copy file %s to %s', src, dest)
233 234
234class _LinkFile: 235class _LinkFile(object):
235 def __init__(self, src, dest, abssrc, absdest): 236 def __init__(self, src, dest, abssrc, absdest):
236 self.src = src 237 self.src = src
237 self.dest = dest 238 self.dest = dest
@@ -258,9 +259,9 @@ class _LinkFile:
258class RemoteSpec(object): 259class RemoteSpec(object):
259 def __init__(self, 260 def __init__(self,
260 name, 261 name,
261 url = None, 262 url=None,
262 review = None, 263 review=None,
263 revision = None): 264 revision=None):
264 self.name = name 265 self.name = name
265 self.url = url 266 self.url = url
266 self.review = review 267 self.review = review
@@ -520,15 +521,15 @@ class Project(object):
520 relpath, 521 relpath,
521 revisionExpr, 522 revisionExpr,
522 revisionId, 523 revisionId,
523 rebase = True, 524 rebase=True,
524 groups = None, 525 groups=None,
525 sync_c = False, 526 sync_c=False,
526 sync_s = False, 527 sync_s=False,
527 clone_depth = None, 528 clone_depth=None,
528 upstream = None, 529 upstream=None,
529 parent = None, 530 parent=None,
530 is_derived = False, 531 is_derived=False,
531 dest_branch = None): 532 dest_branch=None):
532 """Init a Project object. 533 """Init a Project object.
533 534
534 Args: 535 Args:
@@ -585,8 +586,8 @@ class Project(object):
585 self.linkfiles = [] 586 self.linkfiles = []
586 self.annotations = [] 587 self.annotations = []
587 self.config = GitConfig.ForRepository( 588 self.config = GitConfig.ForRepository(
588 gitdir = self.gitdir, 589 gitdir=self.gitdir,
589 defaults = self.manifest.globalConfig) 590 defaults=self.manifest.globalConfig)
590 591
591 if self.worktree: 592 if self.worktree:
592 self.work_git = self._GitGetByExec(self, bare=False, gitdir=gitdir) 593 self.work_git = self._GitGetByExec(self, bare=False, gitdir=gitdir)
@@ -879,8 +880,8 @@ class Project(object):
879 cmd.append('--') 880 cmd.append('--')
880 p = GitCommand(self, 881 p = GitCommand(self,
881 cmd, 882 cmd,
882 capture_stdout = True, 883 capture_stdout=True,
883 capture_stderr = True) 884 capture_stderr=True)
884 has_diff = False 885 has_diff = False
885 for line in p.process.stdout: 886 for line in p.process.stdout:
886 if not has_diff: 887 if not has_diff:
@@ -965,7 +966,7 @@ class Project(object):
965 return None 966 return None
966 967
967 def UploadForReview(self, branch=None, 968 def UploadForReview(self, branch=None,
968 people=([],[]), 969 people=([], []),
969 auto_topic=False, 970 auto_topic=False,
970 draft=False, 971 draft=False,
971 dest_branch=None): 972 dest_branch=None):
@@ -1026,13 +1027,13 @@ class Project(object):
1026 ref_spec = ref_spec + '%' + ','.join(rp) 1027 ref_spec = ref_spec + '%' + ','.join(rp)
1027 cmd.append(ref_spec) 1028 cmd.append(ref_spec)
1028 1029
1029 if GitCommand(self, cmd, bare = True).Wait() != 0: 1030 if GitCommand(self, cmd, bare=True).Wait() != 0:
1030 raise UploadError('Upload failed') 1031 raise UploadError('Upload failed')
1031 1032
1032 msg = "posted to %s for %s" % (branch.remote.review, dest_branch) 1033 msg = "posted to %s for %s" % (branch.remote.review, dest_branch)
1033 self.bare_git.UpdateRef(R_PUB + branch.name, 1034 self.bare_git.UpdateRef(R_PUB + branch.name,
1034 R_HEADS + branch.name, 1035 R_HEADS + branch.name,
1035 message = msg) 1036 message=msg)
1036 1037
1037 1038
1038## Sync ## 1039## Sync ##
@@ -1133,7 +1134,7 @@ class Project(object):
1133 and not self._RemoteFetch(initial=is_new, quiet=quiet, alt_dir=alt_dir, 1134 and not self._RemoteFetch(initial=is_new, quiet=quiet, alt_dir=alt_dir,
1134 current_branch_only=current_branch_only, 1135 current_branch_only=current_branch_only,
1135 no_tags=no_tags)): 1136 no_tags=no_tags)):
1136 return False 1137 return False
1137 1138
1138 if self.worktree: 1139 if self.worktree:
1139 self._InitMRef() 1140 self._InitMRef()
@@ -1329,7 +1330,7 @@ class Project(object):
1329 1330
1330 if cnt_mine > 0 and self.rebase: 1331 if cnt_mine > 0 and self.rebase:
1331 def _dorebase(): 1332 def _dorebase():
1332 self._Rebase(upstream = '%s^1' % last_mine, onto = revid) 1333 self._Rebase(upstream='%s^1' % last_mine, onto=revid)
1333 self._CopyAndLinkFiles() 1334 self._CopyAndLinkFiles()
1334 syncbuf.later2(self, _dorebase) 1335 syncbuf.later2(self, _dorebase)
1335 elif local_changes: 1336 elif local_changes:
@@ -1384,11 +1385,11 @@ class Project(object):
1384 return True 1385 return True
1385 1386
1386 all_refs = self.bare_ref.all 1387 all_refs = self.bare_ref.all
1387 if (R_HEADS + name) in all_refs: 1388 if R_HEADS + name in all_refs:
1388 return GitCommand(self, 1389 return GitCommand(self,
1389 ['checkout', name, '--'], 1390 ['checkout', name, '--'],
1390 capture_stdout = True, 1391 capture_stdout=True,
1391 capture_stderr = True).Wait() == 0 1392 capture_stderr=True).Wait() == 0
1392 1393
1393 branch = self.GetBranch(name) 1394 branch = self.GetBranch(name)
1394 branch.remote = self.GetRemote(self.remote.name) 1395 branch.remote = self.GetRemote(self.remote.name)
@@ -1415,8 +1416,8 @@ class Project(object):
1415 1416
1416 if GitCommand(self, 1417 if GitCommand(self,
1417 ['checkout', '-b', branch.name, revid], 1418 ['checkout', '-b', branch.name, revid],
1418 capture_stdout = True, 1419 capture_stdout=True,
1419 capture_stderr = True).Wait() == 0: 1420 capture_stderr=True).Wait() == 0:
1420 branch.Save() 1421 branch.Save()
1421 return True 1422 return True
1422 return False 1423 return False
@@ -1462,8 +1463,8 @@ class Project(object):
1462 1463
1463 return GitCommand(self, 1464 return GitCommand(self,
1464 ['checkout', name, '--'], 1465 ['checkout', name, '--'],
1465 capture_stdout = True, 1466 capture_stdout=True,
1466 capture_stderr = True).Wait() == 0 1467 capture_stderr=True).Wait() == 0
1467 1468
1468 def AbandonBranch(self, name): 1469 def AbandonBranch(self, name):
1469 """Destroy a local topic branch. 1470 """Destroy a local topic branch.
@@ -1497,8 +1498,8 @@ class Project(object):
1497 1498
1498 return GitCommand(self, 1499 return GitCommand(self,
1499 ['branch', '-D', name], 1500 ['branch', '-D', name],
1500 capture_stdout = True, 1501 capture_stdout=True,
1501 capture_stderr = True).Wait() == 0 1502 capture_stderr=True).Wait() == 0
1502 1503
1503 def PruneHeads(self): 1504 def PruneHeads(self):
1504 """Prune any topic branches already merged into upstream. 1505 """Prune any topic branches already merged into upstream.
@@ -1515,7 +1516,7 @@ class Project(object):
1515 rev = self.GetRevisionId(left) 1516 rev = self.GetRevisionId(left)
1516 if cb is not None \ 1517 if cb is not None \
1517 and not self._revlist(HEAD + '...' + rev) \ 1518 and not self._revlist(HEAD + '...' + rev) \
1518 and not self.IsDirty(consider_untracked = False): 1519 and not self.IsDirty(consider_untracked=False):
1519 self.work_git.DetachHead(HEAD) 1520 self.work_git.DetachHead(HEAD)
1520 kill.append(cb) 1521 kill.append(cb)
1521 1522
@@ -1548,7 +1549,7 @@ class Project(object):
1548 1549
1549 kept = [] 1550 kept = []
1550 for branch in kill: 1551 for branch in kill:
1551 if (R_HEADS + branch) in left: 1552 if R_HEADS + branch in left:
1552 branch = self.GetBranch(branch) 1553 branch = self.GetBranch(branch)
1553 base = branch.LocalMerge 1554 base = branch.LocalMerge
1554 if not base: 1555 if not base:
@@ -1598,8 +1599,8 @@ class Project(object):
1598 def parse_gitmodules(gitdir, rev): 1599 def parse_gitmodules(gitdir, rev):
1599 cmd = ['cat-file', 'blob', '%s:.gitmodules' % rev] 1600 cmd = ['cat-file', 'blob', '%s:.gitmodules' % rev]
1600 try: 1601 try:
1601 p = GitCommand(None, cmd, capture_stdout = True, capture_stderr = True, 1602 p = GitCommand(None, cmd, capture_stdout=True, capture_stderr=True,
1602 bare = True, gitdir = gitdir) 1603 bare=True, gitdir=gitdir)
1603 except GitError: 1604 except GitError:
1604 return [], [] 1605 return [], []
1605 if p.Wait() != 0: 1606 if p.Wait() != 0:
@@ -1611,8 +1612,8 @@ class Project(object):
1611 os.write(fd, p.stdout) 1612 os.write(fd, p.stdout)
1612 os.close(fd) 1613 os.close(fd)
1613 cmd = ['config', '--file', temp_gitmodules_path, '--list'] 1614 cmd = ['config', '--file', temp_gitmodules_path, '--list']
1614 p = GitCommand(None, cmd, capture_stdout = True, capture_stderr = True, 1615 p = GitCommand(None, cmd, capture_stdout=True, capture_stderr=True,
1615 bare = True, gitdir = gitdir) 1616 bare=True, gitdir=gitdir)
1616 if p.Wait() != 0: 1617 if p.Wait() != 0:
1617 return [], [] 1618 return [], []
1618 gitmodules_lines = p.stdout.split('\n') 1619 gitmodules_lines = p.stdout.split('\n')
@@ -1645,8 +1646,8 @@ class Project(object):
1645 cmd = ['ls-tree', rev, '--'] 1646 cmd = ['ls-tree', rev, '--']
1646 cmd.extend(paths) 1647 cmd.extend(paths)
1647 try: 1648 try:
1648 p = GitCommand(None, cmd, capture_stdout = True, capture_stderr = True, 1649 p = GitCommand(None, cmd, capture_stdout=True, capture_stderr=True,
1649 bare = True, gitdir = gitdir) 1650 bare=True, gitdir=gitdir)
1650 except GitError: 1651 except GitError:
1651 return [] 1652 return []
1652 if p.Wait() != 0: 1653 if p.Wait() != 0:
@@ -1681,24 +1682,24 @@ class Project(object):
1681 continue 1682 continue
1682 1683
1683 remote = RemoteSpec(self.remote.name, 1684 remote = RemoteSpec(self.remote.name,
1684 url = url, 1685 url=url,
1685 review = self.remote.review, 1686 review=self.remote.review,
1686 revision = self.remote.revision) 1687 revision=self.remote.revision)
1687 subproject = Project(manifest = self.manifest, 1688 subproject = Project(manifest=self.manifest,
1688 name = name, 1689 name=name,
1689 remote = remote, 1690 remote=remote,
1690 gitdir = gitdir, 1691 gitdir=gitdir,
1691 objdir = objdir, 1692 objdir=objdir,
1692 worktree = worktree, 1693 worktree=worktree,
1693 relpath = relpath, 1694 relpath=relpath,
1694 revisionExpr = self.revisionExpr, 1695 revisionExpr=self.revisionExpr,
1695 revisionId = rev, 1696 revisionId=rev,
1696 rebase = self.rebase, 1697 rebase=self.rebase,
1697 groups = self.groups, 1698 groups=self.groups,
1698 sync_c = self.sync_c, 1699 sync_c=self.sync_c,
1699 sync_s = self.sync_s, 1700 sync_s=self.sync_s,
1700 parent = self, 1701 parent=self,
1701 is_derived = True) 1702 is_derived=True)
1702 result.append(subproject) 1703 result.append(subproject)
1703 result.extend(subproject.GetDerivedSubprojects()) 1704 result.extend(subproject.GetDerivedSubprojects())
1704 return result 1705 return result
@@ -1866,9 +1867,9 @@ class Project(object):
1866 GitCommand(self, ['fetch', '--unshallow', name] + shallowfetch.split(), 1867 GitCommand(self, ['fetch', '--unshallow', name] + shallowfetch.split(),
1867 bare=True, ssh_proxy=ssh_proxy).Wait() 1868 bare=True, ssh_proxy=ssh_proxy).Wait()
1868 if depth: 1869 if depth:
1869 self.config.SetString('repo.shallowfetch', ' '.join(spec)) 1870 self.config.SetString('repo.shallowfetch', ' '.join(spec))
1870 else: 1871 else:
1871 self.config.SetString('repo.shallowfetch', None) 1872 self.config.SetString('repo.shallowfetch', None)
1872 1873
1873 ok = False 1874 ok = False
1874 for _i in range(2): 1875 for _i in range(2):
@@ -1958,34 +1959,34 @@ class Project(object):
1958 os.remove(tmpPath) 1959 os.remove(tmpPath)
1959 if 'http_proxy' in os.environ and 'darwin' == sys.platform: 1960 if 'http_proxy' in os.environ and 'darwin' == sys.platform:
1960 cmd += ['--proxy', os.environ['http_proxy']] 1961 cmd += ['--proxy', os.environ['http_proxy']]
1961 cookiefile = self._GetBundleCookieFile(srcUrl) 1962 with self._GetBundleCookieFile(srcUrl, quiet) as cookiefile:
1962 if cookiefile: 1963 if cookiefile:
1963 cmd += ['--cookie', cookiefile] 1964 cmd += ['--cookie', cookiefile, '--cookie-jar', cookiefile]
1964 if srcUrl.startswith('persistent-'): 1965 if srcUrl.startswith('persistent-'):
1965 srcUrl = srcUrl[len('persistent-'):] 1966 srcUrl = srcUrl[len('persistent-'):]
1966 cmd += [srcUrl] 1967 cmd += [srcUrl]
1967 1968
1968 if IsTrace(): 1969 if IsTrace():
1969 Trace('%s', ' '.join(cmd)) 1970 Trace('%s', ' '.join(cmd))
1970 try: 1971 try:
1971 proc = subprocess.Popen(cmd) 1972 proc = subprocess.Popen(cmd)
1972 except OSError: 1973 except OSError:
1973 return False 1974 return False
1974 1975
1975 curlret = proc.wait() 1976 curlret = proc.wait()
1976 1977
1977 if curlret == 22: 1978 if curlret == 22:
1978 # From curl man page: 1979 # From curl man page:
1979 # 22: HTTP page not retrieved. The requested url was not found or 1980 # 22: HTTP page not retrieved. The requested url was not found or
1980 # returned another error with the HTTP error code being 400 or above. 1981 # returned another error with the HTTP error code being 400 or above.
1981 # This return code only appears if -f, --fail is used. 1982 # This return code only appears if -f, --fail is used.
1982 if not quiet: 1983 if not quiet:
1983 print("Server does not provide clone.bundle; ignoring.", 1984 print("Server does not provide clone.bundle; ignoring.",
1984 file=sys.stderr) 1985 file=sys.stderr)
1985 return False 1986 return False
1986 1987
1987 if os.path.exists(tmpPath): 1988 if os.path.exists(tmpPath):
1988 if curlret == 0 and self._IsValidBundle(tmpPath): 1989 if curlret == 0 and self._IsValidBundle(tmpPath, quiet):
1989 os.rename(tmpPath, dstPath) 1990 os.rename(tmpPath, dstPath)
1990 return True 1991 return True
1991 else: 1992 else:
@@ -1994,45 +1995,51 @@ class Project(object):
1994 else: 1995 else:
1995 return False 1996 return False
1996 1997
1997 def _IsValidBundle(self, path): 1998 def _IsValidBundle(self, path, quiet):
1998 try: 1999 try:
1999 with open(path) as f: 2000 with open(path) as f:
2000 if f.read(16) == '# v2 git bundle\n': 2001 if f.read(16) == '# v2 git bundle\n':
2001 return True 2002 return True
2002 else: 2003 else:
2003 print("Invalid clone.bundle file; ignoring.", file=sys.stderr) 2004 if not quiet:
2005 print("Invalid clone.bundle file; ignoring.", file=sys.stderr)
2004 return False 2006 return False
2005 except OSError: 2007 except OSError:
2006 return False 2008 return False
2007 2009
2008 def _GetBundleCookieFile(self, url): 2010 @contextlib.contextmanager
2011 def _GetBundleCookieFile(self, url, quiet):
2009 if url.startswith('persistent-'): 2012 if url.startswith('persistent-'):
2010 try: 2013 try:
2011 p = subprocess.Popen( 2014 p = subprocess.Popen(
2012 ['git-remote-persistent-https', '-print_config', url], 2015 ['git-remote-persistent-https', '-print_config', url],
2013 stdin=subprocess.PIPE, stdout=subprocess.PIPE, 2016 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
2014 stderr=subprocess.PIPE) 2017 stderr=subprocess.PIPE)
2015 p.stdin.close() # Tell subprocess it's ok to close. 2018 try:
2016 prefix = 'http.cookiefile=' 2019 prefix = 'http.cookiefile='
2017 cookiefile = None 2020 cookiefile = None
2018 for line in p.stdout: 2021 for line in p.stdout:
2019 line = line.strip() 2022 line = line.strip()
2020 if line.startswith(prefix): 2023 if line.startswith(prefix):
2021 cookiefile = line[len(prefix):] 2024 cookiefile = line[len(prefix):]
2022 break 2025 break
2023 if p.wait(): 2026 # Leave subprocess open, as cookie file may be transient.
2024 err_msg = p.stderr.read() 2027 if cookiefile:
2025 if ' -print_config' in err_msg: 2028 yield cookiefile
2026 pass # Persistent proxy doesn't support -print_config. 2029 return
2027 else: 2030 finally:
2028 print(err_msg, file=sys.stderr) 2031 p.stdin.close()
2029 if cookiefile: 2032 if p.wait():
2030 return cookiefile 2033 err_msg = p.stderr.read()
2034 if ' -print_config' in err_msg:
2035 pass # Persistent proxy doesn't support -print_config.
2036 elif not quiet:
2037 print(err_msg, file=sys.stderr)
2031 except OSError as e: 2038 except OSError as e:
2032 if e.errno == errno.ENOENT: 2039 if e.errno == errno.ENOENT:
2033 pass # No persistent proxy. 2040 pass # No persistent proxy.
2034 raise 2041 raise
2035 return GitConfig.ForUser().GetString('http.cookiefile') 2042 yield GitConfig.ForUser().GetString('http.cookiefile')
2036 2043
2037 def _Checkout(self, rev, quiet=False): 2044 def _Checkout(self, rev, quiet=False):
2038 cmd = ['checkout'] 2045 cmd = ['checkout']
@@ -2044,7 +2051,7 @@ class Project(object):
2044 if self._allrefs: 2051 if self._allrefs:
2045 raise GitError('%s checkout %s ' % (self.name, rev)) 2052 raise GitError('%s checkout %s ' % (self.name, rev))
2046 2053
2047 def _CherryPick(self, rev, quiet=False): 2054 def _CherryPick(self, rev):
2048 cmd = ['cherry-pick'] 2055 cmd = ['cherry-pick']
2049 cmd.append(rev) 2056 cmd.append(rev)
2050 cmd.append('--') 2057 cmd.append('--')
@@ -2052,7 +2059,7 @@ class Project(object):
2052 if self._allrefs: 2059 if self._allrefs:
2053 raise GitError('%s cherry-pick %s ' % (self.name, rev)) 2060 raise GitError('%s cherry-pick %s ' % (self.name, rev))
2054 2061
2055 def _Revert(self, rev, quiet=False): 2062 def _Revert(self, rev):
2056 cmd = ['revert'] 2063 cmd = ['revert']
2057 cmd.append('--no-edit') 2064 cmd.append('--no-edit')
2058 cmd.append(rev) 2065 cmd.append(rev)
@@ -2069,7 +2076,7 @@ class Project(object):
2069 if GitCommand(self, cmd).Wait() != 0: 2076 if GitCommand(self, cmd).Wait() != 0:
2070 raise GitError('%s reset --hard %s ' % (self.name, rev)) 2077 raise GitError('%s reset --hard %s ' % (self.name, rev))
2071 2078
2072 def _Rebase(self, upstream, onto = None): 2079 def _Rebase(self, upstream, onto=None):
2073 cmd = ['rebase'] 2080 cmd = ['rebase']
2074 if onto is not None: 2081 if onto is not None:
2075 cmd.extend(['--onto', onto]) 2082 cmd.extend(['--onto', onto])
@@ -2124,7 +2131,7 @@ class Project(object):
2124 2131
2125 m = self.manifest.manifestProject.config 2132 m = self.manifest.manifestProject.config
2126 for key in ['user.name', 'user.email']: 2133 for key in ['user.name', 'user.email']:
2127 if m.Has(key, include_defaults = False): 2134 if m.Has(key, include_defaults=False):
2128 self.config.SetString(key, m.GetString(key)) 2135 self.config.SetString(key, m.GetString(key))
2129 if self.manifest.IsMirror: 2136 if self.manifest.IsMirror:
2130 self.config.SetString('core.bare', 'true') 2137 self.config.SetString('core.bare', 'true')
@@ -2133,15 +2140,6 @@ class Project(object):
2133 2140
2134 def _UpdateHooks(self): 2141 def _UpdateHooks(self):
2135 if os.path.exists(self.gitdir): 2142 if os.path.exists(self.gitdir):
2136 # Always recreate hooks since they can have been changed
2137 # since the latest update.
2138 hooks = self._gitdir_path('hooks')
2139 try:
2140 to_rm = os.listdir(hooks)
2141 except OSError:
2142 to_rm = []
2143 for old_hook in to_rm:
2144 os.remove(os.path.join(hooks, old_hook))
2145 self._InitHooks() 2143 self._InitHooks()
2146 2144
2147 def _InitHooks(self): 2145 def _InitHooks(self):
@@ -2204,7 +2202,7 @@ class Project(object):
2204 if cur != '' or self.bare_ref.get(ref) != self.revisionId: 2202 if cur != '' or self.bare_ref.get(ref) != self.revisionId:
2205 msg = 'manifest set to %s' % self.revisionId 2203 msg = 'manifest set to %s' % self.revisionId
2206 dst = self.revisionId + '^0' 2204 dst = self.revisionId + '^0'
2207 self.bare_git.UpdateRef(ref, dst, message = msg, detach = True) 2205 self.bare_git.UpdateRef(ref, dst, message=msg, detach=True)
2208 else: 2206 else:
2209 remote = self.GetRemote(self.remote.name) 2207 remote = self.GetRemote(self.remote.name)
2210 dst = remote.ToLocal(self.revisionExpr) 2208 dst = remote.ToLocal(self.revisionExpr)
@@ -2348,10 +2346,10 @@ class Project(object):
2348 '-z', 2346 '-z',
2349 '--others', 2347 '--others',
2350 '--exclude-standard'], 2348 '--exclude-standard'],
2351 bare = False, 2349 bare=False,
2352 gitdir=self._gitdir, 2350 gitdir=self._gitdir,
2353 capture_stdout = True, 2351 capture_stdout=True,
2354 capture_stderr = True) 2352 capture_stderr=True)
2355 if p.Wait() == 0: 2353 if p.Wait() == 0:
2356 out = p.stdout 2354 out = p.stdout
2357 if out: 2355 if out:
@@ -2366,9 +2364,9 @@ class Project(object):
2366 p = GitCommand(self._project, 2364 p = GitCommand(self._project,
2367 cmd, 2365 cmd,
2368 gitdir=self._gitdir, 2366 gitdir=self._gitdir,
2369 bare = False, 2367 bare=False,
2370 capture_stdout = True, 2368 capture_stdout=True,
2371 capture_stderr = True) 2369 capture_stderr=True)
2372 try: 2370 try:
2373 out = p.process.stdout.read() 2371 out = p.process.stdout.read()
2374 r = {} 2372 r = {}
@@ -2474,10 +2472,10 @@ class Project(object):
2474 cmdv.extend(args) 2472 cmdv.extend(args)
2475 p = GitCommand(self._project, 2473 p = GitCommand(self._project,
2476 cmdv, 2474 cmdv,
2477 bare = self._bare, 2475 bare=self._bare,
2478 gitdir=self._gitdir, 2476 gitdir=self._gitdir,
2479 capture_stdout = True, 2477 capture_stdout=True,
2480 capture_stderr = True) 2478 capture_stderr=True)
2481 r = [] 2479 r = []
2482 for line in p.process.stdout: 2480 for line in p.process.stdout:
2483 if line[-1] == '\n': 2481 if line[-1] == '\n':
@@ -2527,10 +2525,10 @@ class Project(object):
2527 cmdv.extend(args) 2525 cmdv.extend(args)
2528 p = GitCommand(self._project, 2526 p = GitCommand(self._project,
2529 cmdv, 2527 cmdv,
2530 bare = self._bare, 2528 bare=self._bare,
2531 gitdir=self._gitdir, 2529 gitdir=self._gitdir,
2532 capture_stdout = True, 2530 capture_stdout=True,
2533 capture_stderr = True) 2531 capture_stderr=True)
2534 if p.Wait() != 0: 2532 if p.Wait() != 0:
2535 raise GitError('%s %s: %s' % ( 2533 raise GitError('%s %s: %s' % (
2536 self._project.name, 2534 self._project.name,
@@ -2595,9 +2593,9 @@ class _Later(object):
2595class _SyncColoring(Coloring): 2593class _SyncColoring(Coloring):
2596 def __init__(self, config): 2594 def __init__(self, config):
2597 Coloring.__init__(self, config, 'reposync') 2595 Coloring.__init__(self, config, 'reposync')
2598 self.project = self.printer('header', attr = 'bold') 2596 self.project = self.printer('header', attr='bold')
2599 self.info = self.printer('info') 2597 self.info = self.printer('info')
2600 self.fail = self.printer('fail', fg='red') 2598 self.fail = self.printer('fail', fg='red')
2601 2599
2602class SyncBuffer(object): 2600class SyncBuffer(object):
2603 def __init__(self, config, detach_head=False): 2601 def __init__(self, config, detach_head=False):
@@ -2659,16 +2657,16 @@ class MetaProject(Project):
2659 """ 2657 """
2660 def __init__(self, manifest, name, gitdir, worktree): 2658 def __init__(self, manifest, name, gitdir, worktree):
2661 Project.__init__(self, 2659 Project.__init__(self,
2662 manifest = manifest, 2660 manifest=manifest,
2663 name = name, 2661 name=name,
2664 gitdir = gitdir, 2662 gitdir=gitdir,
2665 objdir = gitdir, 2663 objdir=gitdir,
2666 worktree = worktree, 2664 worktree=worktree,
2667 remote = RemoteSpec('origin'), 2665 remote=RemoteSpec('origin'),
2668 relpath = '.repo/%s' % name, 2666 relpath='.repo/%s' % name,
2669 revisionExpr = 'refs/heads/master', 2667 revisionExpr='refs/heads/master',
2670 revisionId = None, 2668 revisionId=None,
2671 groups = None) 2669 groups=None)
2672 2670
2673 def PreSync(self): 2671 def PreSync(self):
2674 if self.Exists: 2672 if self.Exists:
@@ -2679,20 +2677,20 @@ class MetaProject(Project):
2679 self.revisionExpr = base 2677 self.revisionExpr = base
2680 self.revisionId = None 2678 self.revisionId = None
2681 2679
2682 def MetaBranchSwitch(self, target): 2680 def MetaBranchSwitch(self):
2683 """ Prepare MetaProject for manifest branch switch 2681 """ Prepare MetaProject for manifest branch switch
2684 """ 2682 """
2685 2683
2686 # detach and delete manifest branch, allowing a new 2684 # detach and delete manifest branch, allowing a new
2687 # branch to take over 2685 # branch to take over
2688 syncbuf = SyncBuffer(self.config, detach_head = True) 2686 syncbuf = SyncBuffer(self.config, detach_head=True)
2689 self.Sync_LocalHalf(syncbuf) 2687 self.Sync_LocalHalf(syncbuf)
2690 syncbuf.Finish() 2688 syncbuf.Finish()
2691 2689
2692 return GitCommand(self, 2690 return GitCommand(self,
2693 ['update-ref', '-d', 'refs/heads/default'], 2691 ['update-ref', '-d', 'refs/heads/default'],
2694 capture_stdout = True, 2692 capture_stdout=True,
2695 capture_stderr = True).Wait() == 0 2693 capture_stderr=True).Wait() == 0
2696 2694
2697 2695
2698 @property 2696 @property