changeset 16671:05b55f5ff8d1

merge with main
author Martin Geisler <mg@lazybytes.net>
date Fri, 11 May 2012 15:09:06 +0200
parents 8c3c9031f5aa (diff) 052047753f7d (current diff)
children d046eb97d21e
files
diffstat 14 files changed, 161 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/hg-ssh	Fri May 11 13:42:37 2012 +0200
+++ b/contrib/hg-ssh	Fri May 11 15:09:06 2012 +0200
@@ -40,8 +40,8 @@
 try:
     cmdargv = shlex.split(orig_cmd)
 except ValueError, e:
-    sys.stderr.write("Illegal command %r: %s\n" % (orig_cmd, e))
-    sys.exit(-1)
+    sys.stderr.write('Illegal command "%s": %s\n' % (orig_cmd, e))
+    sys.exit(255)
 
 if cmdargv[:2] == ['hg', '-R'] and cmdargv[3:] == ['serve', '--stdio']:
     path = cmdargv[2]
@@ -49,9 +49,9 @@
     if repo in allowed_paths:
         dispatch.dispatch(dispatch.request(['-R', repo, 'serve', '--stdio']))
     else:
-        sys.stderr.write("Illegal repository %r\n" % repo)
-        sys.exit(-1)
+        sys.stderr.write('Illegal repository "%s"\n' % repo)
+        sys.exit(255)
 else:
-    sys.stderr.write("Illegal command %r\n" % orig_cmd)
-    sys.exit(-1)
+    sys.stderr.write('Illegal command "%s"\n' % orig_cmd)
+    sys.exit(255)
 
--- a/doc/hgmanpage.py	Fri May 11 13:42:37 2012 +0200
+++ b/doc/hgmanpage.py	Fri May 11 15:09:06 2012 +0200
@@ -47,7 +47,10 @@
 import re
 
 from docutils import nodes, writers, languages
-import roman
+try:
+    import roman
+except ImportError:
+    from docutils.utils import roman
 import inspect
 
 FIELD_LIST_INDENT = 7
--- a/mercurial/changelog.py	Fri May 11 13:42:37 2012 +0200
+++ b/mercurial/changelog.py	Fri May 11 15:09:06 2012 +0200
@@ -153,6 +153,7 @@
         r = revlog.revlog(self.opener, file)
         self.index = r.index
         self.nodemap = r.nodemap
+        self._nodecache = r._nodecache
         self._chunkcache = r._chunkcache
 
     def writepending(self):
--- a/mercurial/commands.py	Fri May 11 13:42:37 2012 +0200
+++ b/mercurial/commands.py	Fri May 11 15:09:06 2012 +0200
@@ -919,26 +919,26 @@
 
     for isactive, node, tag in branches:
         if (not active) or isactive:
+            hn = repo.lookup(node)
+            if isactive:
+                label = 'branches.active'
+                notice = ''
+            elif hn not in repo.branchheads(tag, closed=False):
+                if not closed:
+                    continue
+                label = 'branches.closed'
+                notice = _(' (closed)')
+            else:
+                label = 'branches.inactive'
+                notice = _(' (inactive)')
+            if tag == repo.dirstate.branch():
+                label = 'branches.current'
+            rev = str(node).rjust(31 - encoding.colwidth(tag))
+            rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
+            tag = ui.label(tag, label)
             if ui.quiet:
                 ui.write("%s\n" % tag)
             else:
-                hn = repo.lookup(node)
-                if isactive:
-                    label = 'branches.active'
-                    notice = ''
-                elif hn not in repo.branchheads(tag, closed=False):
-                    if not closed:
-                        continue
-                    label = 'branches.closed'
-                    notice = _(' (closed)')
-                else:
-                    label = 'branches.inactive'
-                    notice = _(' (inactive)')
-                if tag == repo.dirstate.branch():
-                    label = 'branches.current'
-                rev = str(node).rjust(31 - encoding.colwidth(tag))
-                rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
-                tag = ui.label(tag, label)
                 ui.write("%s %s%s\n" % (tag, rev, notice))
 
 @command('bundle',
--- a/mercurial/context.py	Fri May 11 13:42:37 2012 +0200
+++ b/mercurial/context.py	Fri May 11 15:09:06 2012 +0200
@@ -697,7 +697,7 @@
             yield c
 
     def copies(self, c2):
-        if not util.hasattr(self, "_copycache"):
+        if not util.safehasattr(self, "_copycache"):
             self._copycache = {}
         sc2 = str(c2)
         if sc2 not in self._copycache:
--- a/mercurial/dispatch.py	Fri May 11 13:42:37 2012 +0200
+++ b/mercurial/dispatch.py	Fri May 11 15:09:06 2012 +0200
@@ -243,6 +243,7 @@
         self.opts = []
         self.help = ''
         self.norepo = True
+        self.optionalrepo = False
         self.badalias = False
 
         try:
@@ -312,6 +313,8 @@
             self.args = aliasargs(self.fn, args)
             if cmd not in commands.norepo.split(' '):
                 self.norepo = False
+            if cmd in commands.optionalrepo.split(' '):
+                self.optionalrepo = True
             if self.help.startswith("hg " + cmd):
                 # drop prefix in old-style help lines so hg shows the alias
                 self.help = self.help[4 + len(cmd):]
@@ -370,6 +373,8 @@
         cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
         if aliasdef.norepo:
             commands.norepo += ' %s' % alias
+        if aliasdef.optionalrepo:
+            commands.optionalrepo += ' %s' % alias
 
 def _parse(ui, args):
     options = {}
@@ -495,7 +500,6 @@
     return path, lui
 
 def _checkshellalias(lui, ui, args):
-    norepo = commands.norepo
     options = {}
 
     try:
@@ -506,6 +510,12 @@
     if not args:
         return
 
+    norepo = commands.norepo
+    optionalrepo = commands.optionalrepo
+    def restorecommands():
+        commands.norepo = norepo
+        commands.optionalrepo = optionalrepo
+
     cmdtable = commands.table.copy()
     addaliases(lui, cmdtable)
 
@@ -514,7 +524,7 @@
         aliases, entry = cmdutil.findcmd(cmd, cmdtable,
                                          lui.configbool("ui", "strict"))
     except (error.AmbiguousCommand, error.UnknownCommand):
-        commands.norepo = norepo
+        restorecommands()
         return
 
     cmd = aliases[0]
@@ -524,7 +534,7 @@
         d = lambda: fn(ui, *args[1:])
         return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
 
-    commands.norepo = norepo
+    restorecommands()
 
 _loaded = set()
 def _dispatch(req):
--- a/mercurial/parsers.c	Fri May 11 13:42:37 2012 +0200
+++ b/mercurial/parsers.c	Fri May 11 15:09:06 2012 +0200
@@ -13,8 +13,10 @@
 
 #include "util.h"
 
-static int hexdigit(char c)
+static inline int hexdigit(const char *p, Py_ssize_t off)
 {
+	char c = p[off];
+
 	if (c >= '0' && c <= '9')
 		return c - '0';
 	if (c >= 'a' && c <= 'f')
@@ -32,8 +34,8 @@
 static PyObject *unhexlify(const char *str, int len)
 {
 	PyObject *ret;
-	const char *c;
 	char *d;
+	int i;
 
 	ret = PyBytes_FromStringAndSize(NULL, len / 2);
 
@@ -42,9 +44,9 @@
 
 	d = PyBytes_AsString(ret);
 
-	for (c = str; c < str + len;) {
-		int hi = hexdigit(*c++);
-		int lo = hexdigit(*c++);
+	for (i = 0; i < len;) {
+		int hi = hexdigit(str, i++);
+		int lo = hexdigit(str, i++);
 		*d++ = (hi << 4) | lo;
 	}
 
@@ -536,7 +538,7 @@
 	return NULL;
 }
 
-static inline int nt_level(const char *node, int level)
+static inline int nt_level(const char *node, Py_ssize_t level)
 {
 	int v = node[level>>1];
 	if (!(level & 1))
@@ -544,6 +546,13 @@
 	return v & 0xf;
 }
 
+/*
+ * Return values:
+ *
+ *   -4: match is ambiguous (multiple candidates)
+ *   -2: not found
+ * rest: valid rev
+ */
 static int nt_find(indexObject *self, const char *node, Py_ssize_t nodelen)
 {
 	int level, off;
@@ -572,7 +581,8 @@
 			return -2;
 		off = v;
 	}
-	return -2;
+	/* multiple matches against an ambiguous prefix */
+	return -4;
 }
 
 static int nt_new(indexObject *self)
@@ -636,6 +646,24 @@
 	return -1;
 }
 
+static int nt_init(indexObject *self)
+{
+	if (self->nt == NULL) {
+		self->ntcapacity = self->raw_length < 4
+			? 4 : self->raw_length / 2;
+		self->nt = calloc(self->ntcapacity, sizeof(nodetree));
+		if (self->nt == NULL) {
+			PyErr_NoMemory();
+			return -1;
+		}
+		self->ntlength = 1;
+		self->ntrev = (int)index_length(self) - 1;
+		self->ntlookups = 1;
+		self->ntmisses = 0;
+	}
+	return 0;
+}
+
 /*
  * Return values:
  *
@@ -653,19 +681,8 @@
 	if (rev >= -1)
 		return rev;
 
-	if (self->nt == NULL) {
-		self->ntcapacity = self->raw_length < 4
-			? 4 : self->raw_length / 2;
-		self->nt = calloc(self->ntcapacity, sizeof(nodetree));
-		if (self->nt == NULL) {
-			PyErr_SetString(PyExc_MemoryError, "out of memory");
-			return -3;
-		}
-		self->ntlength = 1;
-		self->ntrev = (int)index_length(self) - 1;
-		self->ntlookups = 1;
-		self->ntmisses = 0;
-	}
+	if (nt_init(self) == -1)
+		return -3;
 
 	/*
 	 * For the first handful of lookups, we scan the entire index,
@@ -690,10 +707,14 @@
 	} else {
 		for (rev = self->ntrev - 1; rev >= 0; rev--) {
 			const char *n = index_node(self, rev);
-			if (n == NULL)
+			if (n == NULL) {
+				self->ntrev = rev + 1;
 				return -2;
-			if (nt_insert(self, n, rev) == -1)
+			}
+			if (nt_insert(self, n, rev) == -1) {
+				self->ntrev = rev + 1;
 				return -3;
+			}
 			if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) {
 				break;
 			}
@@ -1092,7 +1113,6 @@
 	0,                         /* tp_dictoffset */
 	(initproc)index_init,      /* tp_init */
 	0,                         /* tp_alloc */
-	PyType_GenericNew,         /* tp_new */
 };
 
 /*
@@ -1150,6 +1170,7 @@
 
 static void module_init(PyObject *mod)
 {
+	indexType.tp_new = PyType_GenericNew;
 	if (PyType_Ready(&indexType) < 0)
 		return;
 	Py_INCREF(&indexType);
--- a/tests/run-tests.py	Fri May 11 13:42:37 2012 +0200
+++ b/tests/run-tests.py	Fri May 11 15:09:06 2012 +0200
@@ -1187,6 +1187,7 @@
     os.environ['http_proxy'] = ''
     os.environ['no_proxy'] = ''
     os.environ['NO_PROXY'] = ''
+    os.environ['TERM'] = 'xterm'
 
     # unset env related to hooks
     for k in os.environ.keys():
--- a/tests/test-alias.t	Fri May 11 13:42:37 2012 +0200
+++ b/tests/test-alias.t	Fri May 11 15:09:06 2012 +0200
@@ -9,6 +9,7 @@
   > # should clobber ci but not commit (issue2993)
   > ci = version
   > myinit = init
+  > optionalrepo = showconfig alias.myinit
   > cleanstatus = status -c
   > unknown = bargle
   > ambiguous = s
@@ -108,8 +109,17 @@
   $ hg help no--repository
   error in definition for alias 'no--repository': --repository may only be given on the command line
 
+optional repository
+
+  $ hg optionalrepo
+  init
   $ cd alias
-
+  $ cat > .hg/hgrc <<EOF
+  > [alias]
+  > myinit = init -q
+  > EOF
+  $ hg optionalrepo
+  init -q
 
 no usage
 
--- a/tests/test-branches.t	Fri May 11 13:42:37 2012 +0200
+++ b/tests/test-branches.t	Fri May 11 15:09:06 2012 +0200
@@ -241,6 +241,11 @@
   default                        0:19709c5a4e75 (inactive)
   $ hg branches -a
   a branch name much longer than the default justification used by branches 7:10ff5895aa57
+  $ hg branches -q
+  a branch name much longer than the default justification used by branches
+  c
+  a
+  default
   $ hg heads b
   no open branch heads found on branches b
   [1]
--- a/tests/test-casefolding.t	Fri May 11 13:42:37 2012 +0200
+++ b/tests/test-casefolding.t	Fri May 11 15:09:06 2012 +0200
@@ -57,14 +57,14 @@
   A D/c
   $ hg ci -m addc D/c
   $ hg mv d/b d/e
-  moving D/b to D/e
+  moving D/b to D/e (glob)
   $ hg st
   A D/e
   R D/b
   $ hg revert -aq
   $ rm d/e
   $ hg mv d/b D/B
-  moving D/b to D/B
+  moving D/b to D/B (glob)
   $ hg st
   A D/B
   R D/b
--- a/tests/test-hook.t	Fri May 11 13:42:37 2012 +0200
+++ b/tests/test-hook.t	Fri May 11 15:09:06 2012 +0200
@@ -579,3 +579,30 @@
   $ hg tag -f foo
   ['a', 'foo', 'tip']
 
+new commits must be visible in pretxnchangegroup (issue3428)
+
+  $ cd ..
+  $ hg init to
+  $ echo '[hooks]' >> to/.hg/hgrc
+  $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
+  $ echo a >> to/a
+  $ hg --cwd to ci -Ama
+  adding a
+  $ hg clone to from
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo aa >> from/a
+  $ hg --cwd from ci -mb
+  $ hg --cwd from push
+  pushing to $TESTTMP/to
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  changeset:   1:9836a07b9b9d
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     b
+  
--- a/tests/test-parseindex2.py	Fri May 11 13:42:37 2012 +0200
+++ b/tests/test-parseindex2.py	Fri May 11 15:09:06 2012 +0200
@@ -114,8 +114,12 @@
     for i, r in enumerate(ix):
         if r[7] == nullid:
             i = -1
-        if ix[r[7]] != i:
-            print 'Reverse lookup inconsistent for %r' % r[7].encode('hex')
+        try:
+            if ix[r[7]] != i:
+                print 'Reverse lookup inconsistent for %r' % r[7].encode('hex')
+        except TypeError:
+            # pure version doesn't support this
+            break
 
     print "done"
 
--- a/tests/test-ssh.t	Fri May 11 13:42:37 2012 +0200
+++ b/tests/test-ssh.t	Fri May 11 15:09:06 2012 +0200
@@ -278,19 +278,36 @@
   $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
   3fb238f49e8c
 
-Test hg-ssh:
+Test hg-ssh using a helper script that will restore PYTHONPATH (which might
+have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
+parameters:
 
-  $ SSH_ORIGINAL_COMMAND="'hg' -R 'a repo' serve --stdio" hg id --ssh "python \"$TESTDIR\"/../contrib/hg-ssh \"$TESTTMP/a repo\"" "ssh://user@dummy/a repo"
+  $ cat > ssh.sh << EOF
+  > userhost="\$1"
+  > SSH_ORIGINAL_COMMAND="\$2"
+  > export SSH_ORIGINAL_COMMAND
+  > PYTHONPATH="$PYTHONPATH"
+  > export PYTHONPATH
+  > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
+  > EOF
+
+  $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
   3fb238f49e8c
-  $ SSH_ORIGINAL_COMMAND="'hg' -R 'a repo' serve --stdio" hg id --ssh "python \"$TESTDIR\"/../contrib/hg-ssh \"$TESTTMP\"" "ssh://user@dummy/a repo"
-  remote: Illegal repository '$TESTTMP/a repo' (glob)
+
+  $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
+  remote: Illegal repository "$TESTTMP/a'repo" (glob)
   abort: no suitable response from remote hg!
   [255]
-  $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" hg id --ssh "python \"$TESTDIR\"/../contrib/hg-ssh \"$TESTTMP\"" "ssh://user@dummy/a repo"
-  remote: Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
+
+  $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
+  remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
   abort: no suitable response from remote hg!
   [255]
 
+  $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
+  Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
+  [255]
+
   $ cat dummylog
   Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
   Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio