Merge with crew
authorMatt Mackall <mpm@selenic.com>
Tue, 24 Nov 2009 10:14:27 -0600
changeset 9917 1746909b8878
parent 9909 369592fdc2e4 (current diff)
parent 9916 3d718761157b (diff)
child 9920 04148e7915ac
Merge with crew
--- 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