--- 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
--- 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:
--- 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"]:
--- 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)
--- 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)
--- 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 <foo.bar@example.com>"
os.environ['CDPATH'] = ''
+ os.environ['COLUMNS'] = '80'
global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
TESTDIR = os.environ["TESTDIR"] = os.getcwd()
--- 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
--- 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