# HG changeset patch # User Peter van Dijk # Date 2006-03-06 17:01:34 # Node ID 819a2508f2c655124d59d908b6f568c79696c6e3 # Parent 70be7489933836ec61e33eefe4e4fea9e01b04bf # Parent d17f19d84fd391cecc02e57e0db2323dbc5de872 merge with crew diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -852,7 +852,7 @@ class queue: def qrepo(self, create=False): if create or os.path.isdir(os.path.join(self.path, ".hg")): - return hg.repository(ui=self.ui, path=self.path, create=create) + return hg.repository(self.ui, path=self.path, create=create) def restore(self, repo, rev, delete=None, qupdate=None): c = repo.changelog.read(rev) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -780,7 +780,7 @@ def clone(ui, source, dest=None, **opts) f.close() if not opts['noupdate']: - update(ui, repo) + update(repo.ui, repo) d.close() @@ -1067,6 +1067,7 @@ def debugconfig(ui): """show combined config settings from all hgrc files""" try: repo = hg.repository(ui) + ui = repo.ui except hg.RepoError: pass for section, name, value in ui.walkconfig(): @@ -1777,7 +1778,8 @@ def paths(ui, search=None): and $HOME/.hgrc. If run inside a repository, .hg/hgrc is used, too. """ try: - repo = hg.repository(ui=ui) + repo = hg.repository(ui) + ui = repo.ui except hg.RepoError: pass @@ -2852,7 +2854,8 @@ def dispatch(args): if cmd not in norepo.split(): path = options["repository"] or "" - repo = hg.repository(ui=u, path=path) + repo = hg.repository(u, path=path) + u = repo.ui for x in external: if hasattr(x, 'reposetup'): x.reposetup(u, repo) @@ -2860,27 +2863,30 @@ def dispatch(args): else: d = lambda: func(u, *args, **cmdoptions) - if options['profile']: - import hotshot, hotshot.stats - prof = hotshot.Profile("hg.prof") - try: + try: + if options['profile']: + import hotshot, hotshot.stats + prof = hotshot.Profile("hg.prof") try: - return prof.runcall(d) - except: try: - u.warn(_('exception raised - generating profile ' - 'anyway\n')) + return prof.runcall(d) except: - pass - raise - finally: - prof.close() - stats = hotshot.stats.load("hg.prof") - stats.strip_dirs() - stats.sort_stats('time', 'calls') - stats.print_stats(40) - else: - return d() + try: + u.warn(_('exception raised - generating ' + 'profile anyway\n')) + except: + pass + raise + finally: + prof.close() + stats = hotshot.stats.load("hg.prof") + stats.strip_dirs() + stats.sort_stats('time', 'calls') + stats.print_stats(40) + else: + return d() + finally: + u.flush() except: # enter the debugger when we hit an exception if options['debugger']: diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -10,12 +10,12 @@ import filelog, manifest, changelog, dir from node import * from i18n import gettext as _ from demandload import * -demandload(globals(), "re lock transaction tempfile stat mdiff errno") +demandload(globals(), "re lock transaction tempfile stat mdiff errno ui") class localrepository(object): def __del__(self): self.transhandle = None - def __init__(self, ui, path=None, create=0): + def __init__(self, parentui, path=None, create=0): if not path: p = os.getcwd() while not os.path.isdir(os.path.join(p, ".hg")): @@ -30,7 +30,7 @@ class localrepository(object): raise repo.RepoError(_("repository %s not found") % path) self.root = os.path.abspath(path) - self.ui = ui + self.ui = ui.ui(parentui=parentui) self.opener = util.opener(self.path) self.wopener = util.opener(self.root) self.manifest = manifest.manifest(self.opener) @@ -45,7 +45,7 @@ class localrepository(object): os.mkdir(self.path) os.mkdir(self.join("data")) - self.dirstate = dirstate.dirstate(self.opener, ui, self.root) + self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root) try: self.ui.readconfig(self.join("hgrc")) except IOError: @@ -85,10 +85,11 @@ class localrepository(object): return True r = True - for hname, cmd in self.ui.configitems("hooks"): - s = hname.split(".") - if s[0] == name and cmd: - r = runhook(hname, cmd) and r + hooks = [(hname, cmd) for hname, cmd in self.ui.configitems("hooks") + if hname.split(".", 1)[0] == name and cmd] + hooks.sort() + for hname, cmd in hooks: + r = runhook(hname, cmd) and r return r def tags(self): diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -12,18 +12,23 @@ demandload(globals(), "re socket sys uti class ui(object): def __init__(self, verbose=False, debug=False, quiet=False, - interactive=True): + interactive=True, parentui=None): self.overlay = {} self.cdata = ConfigParser.SafeConfigParser() - self.readconfig(util.rcpath) + self.parentui = parentui and parentui.parentui or parentui + if parentui is None: + self.readconfig(util.rcpath) - self.quiet = self.configbool("ui", "quiet") - self.verbose = self.configbool("ui", "verbose") - self.debugflag = self.configbool("ui", "debug") - self.interactive = self.configbool("ui", "interactive", True) + self.quiet = self.configbool("ui", "quiet") + self.verbose = self.configbool("ui", "verbose") + self.debugflag = self.configbool("ui", "debug") + self.interactive = self.configbool("ui", "interactive", True) - self.updateopts(verbose, debug, quiet, interactive) - self.diffcache = None + self.updateopts(verbose, debug, quiet, interactive) + self.diffcache = None + + def __getattr__(self, key): + return getattr(self.parentui, key) def updateopts(self, verbose=False, debug=False, quiet=False, interactive=True): @@ -49,22 +54,34 @@ class ui(object): return self.overlay[(section, name)] if self.cdata.has_option(section, name): return self.cdata.get(section, name) - return default + if self.parentui is None: + return default + else: + return self.parentui.config(section, name, default) def configbool(self, section, name, default=False): if self.overlay.has_key((section, name)): return self.overlay[(section, name)] if self.cdata.has_option(section, name): return self.cdata.getboolean(section, name) - return default + if self.parentui is None: + return default + else: + return self.parentui.configbool(section, name, default) def configitems(self, section): + items = {} + if self.parentui is not None: + items = dict(self.parentui.configitems(section)) if self.cdata.has_section(section): - return self.cdata.items(section) - return [] + items.update(dict(self.cdata.items(section))) + x = items.items() + x.sort() + return x - def walkconfig(self): - seen = {} + def walkconfig(self, seen=None): + if seen is None: + seen = {} for (section, name), value in self.overlay.iteritems(): yield section, name, value seen[section, name] = 1 @@ -73,6 +90,9 @@ class ui(object): if (section, name) in seen: continue yield section, name, value.replace('\n', '\\n') seen[section, name] = 1 + if self.parentui is not None: + for parent in self.parentui.walkconfig(seen): + yield parent def extensions(self): return self.configitems("extensions") @@ -132,6 +152,12 @@ class ui(object): for a in args: sys.stderr.write(str(a)) + def flush(self): + try: + sys.stdout.flush() + finally: + sys.stderr.flush() + def readline(self): return sys.stdin.readline()[:-1] def prompt(self, msg, pat, default="y"): @@ -171,3 +197,4 @@ class ui(object): os.unlink(name) return t + diff --git a/tests/test-hook.out b/tests/test-hook.out --- a/tests/test-hook.out +++ b/tests/test-hook.out @@ -1,23 +1,23 @@ precommit hook: p1=0000000000000000000000000000000000000000 p2= pretxncommit hook: n=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p1=0000000000000000000000000000000000000000 p2= 0:cb9a9f314b8b +commit hook: n=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p1=0000000000000000000000000000000000000000 p2= commit hook b -commit hook: n=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p1=0000000000000000000000000000000000000000 p2= precommit hook: p1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p2= pretxncommit hook: n=ab228980c14deea8b9555d91c9581127383e40fd p1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p2= 1:ab228980c14d +commit hook: n=ab228980c14deea8b9555d91c9581127383e40fd p1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p2= commit hook b -commit hook: n=ab228980c14deea8b9555d91c9581127383e40fd p1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p2= precommit hook: p1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p2= pretxncommit hook: n=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 p1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p2= 2:ee9deb46ab31 +commit hook: n=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 p1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p2= commit hook b -commit hook: n=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 p1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b p2= precommit hook: p1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 p2=ab228980c14deea8b9555d91c9581127383e40fd pretxncommit hook: n=07f3376c1e655977439df2a814e3cc14b27abac2 p1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 p2=ab228980c14deea8b9555d91c9581127383e40fd 3:07f3376c1e65 +commit hook: n=07f3376c1e655977439df2a814e3cc14b27abac2 p1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 p2=ab228980c14deea8b9555d91c9581127383e40fd commit hook b -commit hook: n=07f3376c1e655977439df2a814e3cc14b27abac2 p1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 p2=ab228980c14deea8b9555d91c9581127383e40fd prechangegroup hook changegroup hook: n=ab228980c14deea8b9555d91c9581127383e40fd incoming hook: n=ab228980c14deea8b9555d91c9581127383e40fd @@ -34,8 +34,8 @@ pretag hook: t=a n=07f3376c1e655977439df precommit hook: p1=07f3376c1e655977439df2a814e3cc14b27abac2 p2= pretxncommit hook: n=3cd2c6a5a36c5908aad3bc0d717c29873a05dfc2 p1=07f3376c1e655977439df2a814e3cc14b27abac2 p2= 4:3cd2c6a5a36c +commit hook: n=3cd2c6a5a36c5908aad3bc0d717c29873a05dfc2 p1=07f3376c1e655977439df2a814e3cc14b27abac2 p2= commit hook b -commit hook: n=3cd2c6a5a36c5908aad3bc0d717c29873a05dfc2 p1=07f3376c1e655977439df2a814e3cc14b27abac2 p2= tag hook: t=a n=07f3376c1e655977439df2a814e3cc14b27abac2 l=0 pretag hook: t=la n=3cd2c6a5a36c5908aad3bc0d717c29873a05dfc2 l=1 tag hook: t=la n=3cd2c6a5a36c5908aad3bc0d717c29873a05dfc2 l=1 @@ -47,11 +47,14 @@ pretag.forbid hook abort: pretag.forbid hook exited with status 1 4:3cd2c6a5a36c precommit hook: p1=3cd2c6a5a36c5908aad3bc0d717c29873a05dfc2 p2= +pretxncommit hook: n=469a61fe67d64df9a5023e4c2b8a0b85c61e9b69 p1=3cd2c6a5a36c5908aad3bc0d717c29873a05dfc2 p2= +5:469a61fe67d6 pretxncommit.forbid hook: tip=5:469a61fe67d6 abort: pretxncommit.forbid hook exited with status 1 transaction abort! rollback completed 4:3cd2c6a5a36c +precommit hook: p1=3cd2c6a5a36c5908aad3bc0d717c29873a05dfc2 p2= precommit.forbid hook abort: precommit.forbid hook exited with status 1 4:3cd2c6a5a36c diff --git a/tests/test-push-hook-lock b/tests/test-push-hook-lock new file mode 100755 --- /dev/null +++ b/tests/test-push-hook-lock @@ -0,0 +1,13 @@ +#!/bin/sh +hg init 1 +echo '[ui]' >> 1/.hg/hgrc +echo 'timeout = 10' >> 1/.hg/hgrc +echo foo > 1/foo +hg --cwd 1 ci -A -m foo +hg clone 1 2 +hg clone 2 3 +echo '[hooks]' >> 2/.hg/hgrc +echo 'changegroup.push = hg push -qf ../1' >> 2/.hg/hgrc +echo bar >> 3/foo +hg --cwd 3 ci -m bar +hg --cwd 3 push ../2 diff --git a/tests/test-push-hook-lock.out b/tests/test-push-hook-lock.out new file mode 100644 --- /dev/null +++ b/tests/test-push-hook-lock.out @@ -0,0 +1,7 @@ +adding foo +pushing to ../2 +searching for changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files