# HG changeset patch # User Matt Mackall # Date 1259079267 21600 # Node ID 1746909b887845a9d7d47d620f9a8a994b55a7b2 # Parent 369592fdc2e48fa9538f76fb0efa16fe1fc87dbb# Parent 3d718761157b9dba2b7a9e1a45858bcc4d493766 Merge with crew diff -r 369592fdc2e4 -r 1746909b8878 contrib/win32/mercurial.iss --- a/contrib/win32/mercurial.iss Sun Nov 22 15:36:22 2009 -0600 +++ b/contrib/win32/mercurial.iss Tue Nov 24 10:14:27 2009 -0600 @@ -62,6 +62,7 @@ Source: dist\add_path.exe; DestDir: {app} Source: doc\*.html; DestDir: {app}\Docs Source: doc\style.css; DestDir: {app}\Docs +Source: help\*.txt; DestDir: {app}\help Source: locale\*.*; DestDir: {app}\locale; Flags: recursesubdirs createallsubdirs Source: templates\*.*; DestDir: {app}\Templates; Flags: recursesubdirs createallsubdirs Source: CONTRIBUTORS; DestDir: {app}; DestName: Contributors.txt diff -r 369592fdc2e4 -r 1746909b8878 mercurial/ancestor.py --- a/mercurial/ancestor.py Sun Nov 22 15:36:22 2009 -0600 +++ b/mercurial/ancestor.py Tue Nov 24 10:14:27 2009 -0600 @@ -9,10 +9,11 @@ def ancestor(a, b, pfunc): """ - return the least common ancestor of nodes a and b or None if there - is no such ancestor. + return a minimal-distance ancestor of nodes a and b, or None if there is no + such ancestor. Note that there can be several ancestors with the same + (minimal) distance, and the one returned is arbitrary. - pfunc must return a list of parent vertices + pfunc must return a list of parent vertices for a given vertex """ if a == b: diff -r 369592fdc2e4 -r 1746909b8878 mercurial/commands.py --- a/mercurial/commands.py Sun Nov 22 15:36:22 2009 -0600 +++ b/mercurial/commands.py Tue Nov 24 10:14:27 2009 -0600 @@ -2017,7 +2017,6 @@ else: endrev = len(repo) rcache = {} - ncache = {} def getrenamed(fn, rev): '''looks up all renames for a file (up to endrev) the first time the file is given. It indexes on the changerev and only @@ -2025,15 +2024,11 @@ Returns rename info for fn at changerev rev.''' if fn not in rcache: rcache[fn] = {} - ncache[fn] = {} fl = repo.file(fn) for i in fl: - node = fl.node(i) lr = fl.linkrev(i) - renamed = fl.renamed(node) + renamed = fl.renamed(fl.node(i)) rcache[fn][lr] = renamed - if renamed: - ncache[fn][node] = renamed if lr >= endrev: break if rev in rcache[fn]: @@ -2041,12 +2036,10 @@ # If linkrev != rev (i.e. rev not found in rcache) fallback to # filectx logic. - try: return repo[rev][fn].renamed() except error.LookupError: - pass - return None + return None df = False if opts["date"]: diff -r 369592fdc2e4 -r 1746909b8878 mercurial/hgweb/common.py --- a/mercurial/hgweb/common.py Sun Nov 22 15:36:22 2009 -0600 +++ b/mercurial/hgweb/common.py Tue Nov 24 10:14:27 2009 -0600 @@ -16,6 +16,58 @@ HTTP_METHOD_NOT_ALLOWED = 405 HTTP_SERVER_ERROR = 500 +# Hooks for hgweb permission checks; extensions can add hooks here. Each hook +# is invoked like this: hook(hgweb, request, operation), where operation is +# either read, pull or push. Hooks should either raise an ErrorResponse +# exception, or just return. +# It is possible to do both authentication and authorization through this. +permhooks = [] + +def checkauthz(hgweb, req, op): + '''Check permission for operation based on request data (including + authentication info). Return if op allowed, else raise an ErrorResponse + exception.''' + + user = req.env.get('REMOTE_USER') + + deny_read = hgweb.configlist('web', 'deny_read') + if deny_read and (not user or deny_read == ['*'] or user in deny_read): + raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') + + allow_read = hgweb.configlist('web', 'allow_read') + result = (not allow_read) or (allow_read == ['*']) + if not (result or user in allow_read): + raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') + + if op == 'pull' and not hgweb.allowpull: + raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') + elif op == 'pull' or op is None: # op is None for interface requests + return + + # enforce that you can only push using POST requests + if req.env['REQUEST_METHOD'] != 'POST': + msg = 'push requires POST request' + raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg) + + # require ssl by default for pushing, auth info cannot be sniffed + # and replayed + scheme = req.env.get('wsgi.url_scheme') + if hgweb.configbool('web', 'push_ssl', True) and scheme != 'https': + raise ErrorResponse(HTTP_OK, 'ssl required') + + deny = hgweb.configlist('web', 'deny_push') + if deny and (not user or deny == ['*'] or user in deny): + raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') + + allow = hgweb.configlist('web', 'allow_push') + result = allow and (allow == ['*'] or user in allow) + if not result: + raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') + +# Add the default permhook, which provides simple authorization. +permhooks.append(checkauthz) + + class ErrorResponse(Exception): def __init__(self, code, message=None, headers=[]): Exception.__init__(self) diff -r 369592fdc2e4 -r 1746909b8878 mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py Sun Nov 22 15:36:22 2009 -0600 +++ b/mercurial/hgweb/hgweb_mod.py Tue Nov 24 10:14:27 2009 -0600 @@ -8,7 +8,7 @@ import os from mercurial import ui, hg, hook, error, encoding, templater -from common import get_mtime, ErrorResponse +from common import get_mtime, ErrorResponse, permhooks from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR from common import HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED from request import wsgirequest @@ -283,42 +283,5 @@ } def check_perm(self, req, op): - '''Check permission for operation based on request data (including - authentication info). Return if op allowed, else raise an ErrorResponse - exception.''' - - user = req.env.get('REMOTE_USER') - - deny_read = self.configlist('web', 'deny_read') - if deny_read and (not user or deny_read == ['*'] or user in deny_read): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') - - allow_read = self.configlist('web', 'allow_read') - result = (not allow_read) or (allow_read == ['*']) - if not (result or user in allow_read): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') - - if op == 'pull' and not self.allowpull: - raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') - elif op == 'pull' or op is None: # op is None for interface requests - return - - # enforce that you can only push using POST requests - if req.env['REQUEST_METHOD'] != 'POST': - msg = 'push requires POST request' - raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg) - - # require ssl by default for pushing, auth info cannot be sniffed - # and replayed - scheme = req.env.get('wsgi.url_scheme') - if self.configbool('web', 'push_ssl', True) and scheme != 'https': - raise ErrorResponse(HTTP_OK, 'ssl required') - - deny = self.configlist('web', 'deny_push') - if deny and (not user or deny == ['*'] or user in deny): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') - - allow = self.configlist('web', 'allow_push') - result = allow and (allow == ['*'] or user in allow) - if not result: - raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') + for hook in permhooks: + hook(self, req, op) diff -r 369592fdc2e4 -r 1746909b8878 tests/run-tests.py --- a/tests/run-tests.py Sun Nov 22 15:36:22 2009 -0600 +++ b/tests/run-tests.py Tue Nov 24 10:14:27 2009 -0600 @@ -793,6 +793,7 @@ os.environ['TZ'] = 'GMT' os.environ["EMAIL"] = "Foo Bar " os.environ['CDPATH'] = '' + os.environ['COLUMNS'] = '80' global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE TESTDIR = os.environ["TESTDIR"] = os.getcwd() diff -r 369592fdc2e4 -r 1746909b8878 tests/test-churn --- a/tests/test-churn Sun Nov 22 15:36:22 2009 -0600 +++ b/tests/test-churn Tue Nov 24 10:14:27 2009 -0600 @@ -3,8 +3,6 @@ echo "[extensions]" >> $HGRCPATH echo "churn=" >> $HGRCPATH -COLUMNS=80; export COLUMNS - echo % create test repository hg init repo cd repo diff -r 369592fdc2e4 -r 1746909b8878 tests/test-patchbomb --- a/tests/test-patchbomb Sun Nov 22 15:36:22 2009 -0600 +++ b/tests/test-patchbomb Tue Nov 24 10:14:27 2009 -0600 @@ -12,8 +12,6 @@ echo "[extensions]" >> $HGRCPATH echo "patchbomb=" >> $HGRCPATH -COLUMNS=80; export COLUMNS - hg init t cd t echo a > a