changeset 16642:5cf18921bb7b

merge with stable
author Matt Mackall <mpm@selenic.com>
date Sat, 12 May 2012 00:06:11 +0200
parents 1435866c1937 (diff) e6dfbc5df76f (current diff)
children 24dbef11f477
files hgext/largefiles/overrides.py mercurial/cmdutil.py mercurial/commands.py mercurial/parsers.c
diffstat 23 files changed, 287 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/check-code.py	Tue May 08 14:46:04 2012 -0700
+++ b/contrib/check-code.py	Sat May 12 00:06:11 2012 +0200
@@ -199,6 +199,7 @@
      "always assign an opened file to a variable, and close it afterwards"),
     (r'(?i)descendent', "the proper spelling is descendAnt"),
     (r'\.debug\(\_', "don't mark debug messages for translation"),
+    (r'\.strip\(\)\.split\(\)', "no need to strip before splitting"),
   ],
   # warnings
   [
--- a/hgext/largefiles/overrides.py	Tue May 08 14:46:04 2012 -0700
+++ b/hgext/largefiles/overrides.py	Sat May 12 00:06:11 2012 +0200
@@ -782,6 +782,47 @@
 
     archiver.done()
 
+def hgsubrepoarchive(orig, repo, ui, archiver, prefix):
+    rev = repo._state[1]
+    ctx = repo._repo[rev]
+
+    lfcommands.cachelfiles(ui, repo._repo, ctx.node())
+
+    def write(name, mode, islink, getdata):
+        if lfutil.isstandin(name):
+            return
+        data = getdata()
+
+        archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
+
+    for f in ctx:
+        ff = ctx.flags(f)
+        getdata = ctx[f].data
+        if lfutil.isstandin(f):
+            path = lfutil.findfile(repo._repo, getdata().strip())
+            if path is None:
+                raise util.Abort(
+                    _('largefile %s not found in repo store or system cache')
+                    % lfutil.splitstandin(f))
+            f = lfutil.splitstandin(f)
+
+            def getdatafn():
+                fd = None
+                try:
+                    fd = open(os.path.join(prefix, path), 'rb')
+                    return fd.read()
+                finally:
+                    if fd:
+                        fd.close()
+
+            getdata = getdatafn
+
+        write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
+
+    for subpath in ctx.substate:
+        sub = ctx.sub(subpath)
+        sub.archive(repo.ui, archiver, prefix)
+
 # If a largefile is modified, the change is not reflected in its
 # standin until a commit. cmdutil.bailifchanged() raises an exception
 # if the repo has uncommitted changes. Wrap it to also check if
--- a/hgext/largefiles/uisetup.py	Tue May 08 14:46:04 2012 -0700
+++ b/hgext/largefiles/uisetup.py	Sat May 12 00:06:11 2012 +0200
@@ -100,6 +100,7 @@
     extensions.wrapfunction(hg, 'merge', overrides.hgmerge)
 
     extensions.wrapfunction(archival, 'archive', overrides.overridearchive)
+    extensions.wrapfunction(hgsubrepo, 'archive', overrides.hgsubrepoarchive)
     extensions.wrapfunction(cmdutil, 'bailifchanged',
                             overrides.overridebailifchanged)
 
--- a/hgext/rebase.py	Tue May 08 14:46:04 2012 -0700
+++ b/hgext/rebase.py	Sat May 12 00:06:11 2012 +0200
@@ -182,7 +182,7 @@
                 branch = repo[None].branch()
                 dest = repo[branch]
             else:
-                dest = repo[destf]
+                dest = scmutil.revsingle(repo, destf)
 
             if revf:
                 rebaseset = repo.revs('%lr', revf)
@@ -201,7 +201,7 @@
                 root = None
 
             if not rebaseset:
-                repo.ui.debug('base is ancestor of destination')
+                repo.ui.debug('base is ancestor of destination\n')
                 result = None
             elif not keepf and list(repo.revs('first(children(%ld) - %ld)',
                                               rebaseset, rebaseset)):
@@ -618,7 +618,7 @@
     if commonbase == dest:
         samebranch = root.branch() == dest.branch()
         if samebranch and root in dest.children():
-           repo.ui.debug('source is a child of destination')
+           repo.ui.debug('source is a child of destination\n')
            return None
         # rebase on ancestor, force detach
         detach = True
--- a/hgext/transplant.py	Tue May 08 14:46:04 2012 -0700
+++ b/hgext/transplant.py	Sat May 12 00:06:11 2012 +0200
@@ -124,7 +124,7 @@
                     continue
 
                 parents = source.changelog.parents(node)
-                if not opts.get('filter'):
+                if not (opts.get('filter') or opts.get('log')):
                     # If the changeset parent is the same as the
                     # wdir's parent, just pull it.
                     if parents[0] == p1:
--- a/mercurial/cmdutil.py	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/cmdutil.py	Sat May 12 00:06:11 2012 +0200
@@ -1486,7 +1486,7 @@
         def badfn(path, msg):
             if path in names:
                 return
-            if path in repo[node].substate:
+            if path in ctx.substate:
                 return
             path_ = path + '/'
             for f in names:
@@ -1494,14 +1494,14 @@
                     return
             ui.warn("%s: %s\n" % (m.rel(path), msg))
 
-        m = scmutil.match(repo[node], pats, opts)
+        m = scmutil.match(ctx, pats, opts)
         m.bad = badfn
-        for abs in repo[node].walk(m):
+        for abs in ctx.walk(m):
             if abs not in names:
                 names[abs] = m.rel(abs), m.exact(abs)
 
         # get the list of subrepos that must be reverted
-        targetsubs = [s for s in repo[node].substate if m(s)]
+        targetsubs = [s for s in ctx.substate if m(s)]
         m = scmutil.matchfiles(repo, names)
         changes = repo.status(match=m)[:4]
         modified, added, removed, deleted = map(set, changes)
--- a/mercurial/commands.py	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/commands.py	Sat May 12 00:06:11 2012 +0200
@@ -921,26 +921,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',
@@ -2722,8 +2722,10 @@
             date = ctx.date()
             if opts.get('date'):
                 date = opts['date']
-            repo.commit(text=ctx.description(), user=user,
+            node = repo.commit(text=ctx.description(), user=user,
                         date=date, extra=extra, editor=editor)
+            if node is None:
+                ui.status(_('graft for revision %s is empty\n') % ctx.rev())
     finally:
         wlock.release()
 
--- a/mercurial/context.py	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/context.py	Sat May 12 00:06:11 2012 +0200
@@ -8,6 +8,7 @@
 from node import nullid, nullrev, short, hex, bin
 from i18n import _
 import ancestor, mdiff, error, util, scmutil, subrepo, patch, encoding, phases
+import copies
 import match as matchmod
 import os, errno, stat
 
@@ -634,27 +635,27 @@
 
         return zip(hist[base][0], hist[base][1].splitlines(True))
 
-    def ancestor(self, fc2, actx=None):
+    def ancestor(self, fc2, actx):
         """
         find the common ancestor file context, if any, of self, and fc2
 
-        If actx is given, it must be the changectx of the common ancestor
+        actx must be the changectx of the common ancestor
         of self's and fc2's respective changesets.
         """
 
-        if actx is None:
-            actx = self.changectx().ancestor(fc2.changectx())
-
-        # the trivial case: changesets are unrelated, files must be too
-        if not actx:
-            return None
-
         # the easy case: no (relevant) renames
         if fc2.path() == self.path() and self.path() in actx:
             return actx[self.path()]
-        acache = {}
+
+        # the next easiest cases: unambiguous predecessor (name trumps
+        # history)
+        if self.path() in actx and fc2.path() not in actx:
+            return actx[self.path()]
+        if fc2.path() in actx and self.path() not in actx:
+            return actx[fc2.path()]
 
         # prime the ancestor cache for the working directory
+        acache = {}
         for c in (self, fc2):
             if c._filerev is None:
                 pl = [(n.path(), n.filenode()) for n in c.parents()]
@@ -695,6 +696,14 @@
             c = visit.pop(max(visit))
             yield c
 
+    def copies(self, c2):
+        if not util.safehasattr(self, "_copycache"):
+            self._copycache = {}
+        sc2 = str(c2)
+        if sc2 not in self._copycache:
+            self._copycache[sc2] = copies.pathcopies(c2)
+        return self._copycache[sc2]
+
 class workingctx(changectx):
     """A workingctx object makes access to data related to
     the current working directory convenient.
--- a/mercurial/localrepo.py	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/localrepo.py	Sat May 12 00:06:11 2012 +0200
@@ -183,9 +183,8 @@
 
     @storecache('phaseroots')
     def _phaseroots(self):
-        self._dirtyphases = False
-        phaseroots = phases.readroots(self)
-        phases.filterunknown(self, phaseroots)
+        phaseroots, self._dirtyphases = phases.readroots(
+            self, self._phasedefaults)
         return phaseroots
 
     @propertycache
@@ -505,7 +504,7 @@
             partial = self._branchcache
 
         self._branchtags(partial, lrev)
-        # this private cache holds all heads (not just tips)
+        # this private cache holds all heads (not just the branch tips)
         self._branchcache = partial
 
     def branchmap(self):
@@ -585,8 +584,8 @@
                 latest = newnodes.pop()
                 if latest not in bheads:
                     continue
-                minbhrev = self[bheads[0]].node()
-                reachable = self.changelog.reachable(latest, minbhrev)
+                minbhnode = self[bheads[0]].node()
+                reachable = self.changelog.reachable(latest, minbhnode)
                 reachable.remove(latest)
                 if reachable:
                     bheads = [b for b in bheads if b not in reachable]
@@ -933,7 +932,7 @@
         def unlock():
             self.store.write()
             if self._dirtyphases:
-                phases.writeroots(self)
+                phases.writeroots(self, self._phaseroots)
                 self._dirtyphases = False
             for k, ce in self._filecache.items():
                 if k == 'dirstate':
@@ -1694,7 +1693,7 @@
                     # * missingheads part of comon (::commonheads)
                     common = set(outgoing.common)
                     cheads = [node for node in revs if node in common]
-                    # and 
+                    # and
                     # * commonheads parents on missing
                     revset = self.set('%ln and parents(roots(%ln))',
                                      outgoing.commonheads,
--- a/mercurial/parsers.c	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/parsers.c	Sat May 12 00:06:11 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;
 	}
 
@@ -506,13 +508,13 @@
 		return NULL;
 
 #define istat(__n, __d) \
-	if (PyDict_SetItemString(obj, __d, PyInt_FromLong(self->__n)) == -1) \
+	if (PyDict_SetItemString(obj, __d, PyInt_FromSsize_t(self->__n)) == -1) \
 		goto bail;
 
 	if (self->added) {
 		Py_ssize_t len = PyList_GET_SIZE(self->added);
 		if (PyDict_SetItemString(obj, "index entries added",
-					 PyInt_FromLong(len)) == -1)
+					 PyInt_FromSsize_t(len)) == -1)
 			goto bail;
 	}
 
@@ -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, maxlevel, off;
@@ -574,7 +583,8 @@
 			return -2;
 		off = v;
 	}
-	return -2;
+	/* multiple matches against an ambiguous prefix */
+	return -4;
 }
 
 static int nt_new(indexObject *self)
@@ -638,6 +648,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:
  *
@@ -655,19 +683,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,
@@ -692,10 +709,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;
 			}
--- a/mercurial/patch.py	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/patch.py	Sat May 12 00:06:11 2012 +0200
@@ -1040,12 +1040,13 @@
             hunk.append(l)
             return l.rstrip('\r\n')
 
-        line = getline(lr, self.hunk)
-        while line and not line.startswith('literal '):
+        while True:
             line = getline(lr, self.hunk)
-        if not line:
-            raise PatchError(_('could not extract "%s" binary data')
-                             % self._fname)
+            if not line:
+                raise PatchError(_('could not extract "%s" binary data')
+                                 % self._fname)
+            if line.startswith('literal '):
+                break
         size = int(line[8:].rstrip())
         dec = []
         line = getline(lr, self.hunk)
--- a/mercurial/phases.py	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/phases.py	Sat May 12 00:06:11 2012 +0200
@@ -106,54 +106,66 @@
 trackedphases = allphases[1:]
 phasenames = ['public', 'draft', 'secret']
 
-def readroots(repo):
-    """Read phase roots from disk"""
+def _filterunknown(ui, changelog, phaseroots):
+    """remove unknown nodes from the phase boundary
+
+    Nothing is lost as unknown nodes only hold data for their descendants
+    """
+    updated = False
+    nodemap = changelog.nodemap # to filter unknown nodes
+    for phase, nodes in enumerate(phaseroots):
+        missing = [node for node in nodes if node not in nodemap]
+        if missing:
+            for mnode in missing:
+                ui.debug(
+                    'removing unknown node %s from %i-phase boundary\n'
+                    % (short(mnode), phase))
+            nodes.symmetric_difference_update(missing)
+            updated = True
+    return updated
+
+def readroots(repo, phasedefaults=None):
+    """Read phase roots from disk
+
+    phasedefaults is a list of fn(repo, roots) callable, which are
+    executed if the phase roots file does not exist. When phases are
+    being initialized on an existing repository, this could be used to
+    set selected changesets phase to something else than public.
+
+    Return (roots, dirty) where dirty is true if roots differ from
+    what is being stored.
+    """
+    dirty = False
     roots = [set() for i in allphases]
     try:
         f = repo.sopener('phaseroots')
         try:
             for line in f:
-                phase, nh = line.strip().split()
+                phase, nh = line.split()
                 roots[int(phase)].add(bin(nh))
         finally:
             f.close()
     except IOError, inst:
         if inst.errno != errno.ENOENT:
             raise
-        for f in repo._phasedefaults:
-            roots = f(repo, roots)
-        repo._dirtyphases = True
-    return roots
+        if phasedefaults:
+            for f in phasedefaults:
+                roots = f(repo, roots)
+        dirty = True
+    if _filterunknown(repo.ui, repo.changelog, roots):
+        dirty = True
+    return roots, dirty
 
-def writeroots(repo):
+def writeroots(repo, phaseroots):
     """Write phase roots from disk"""
     f = repo.sopener('phaseroots', 'w', atomictemp=True)
     try:
-        for phase, roots in enumerate(repo._phaseroots):
+        for phase, roots in enumerate(phaseroots):
             for h in roots:
                 f.write('%i %s\n' % (phase, hex(h)))
-        repo._dirtyphases = False
     finally:
         f.close()
 
-def filterunknown(repo, phaseroots=None):
-    """remove unknown nodes from the phase boundary
-
-    no data is lost as unknown node only old data for their descentants
-    """
-    if phaseroots is None:
-        phaseroots = repo._phaseroots
-    nodemap = repo.changelog.nodemap # to filter unknown nodes
-    for phase, nodes in enumerate(phaseroots):
-        missing = [node for node in nodes if node not in nodemap]
-        if missing:
-            for mnode in missing:
-                repo.ui.debug(
-                    'removing unknown node %s from %i-phase boundary\n'
-                    % (short(mnode), phase))
-            nodes.symmetric_difference_update(missing)
-            repo._dirtyphases = True
-
 def advanceboundary(repo, targetphase, nodes):
     """Add nodes to a phase changing other nodes phases if necessary.
 
--- a/mercurial/repair.py	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/repair.py	Sat May 12 00:06:11 2012 +0200
@@ -6,7 +6,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-from mercurial import changegroup, bookmarks, phases
+from mercurial import changegroup, bookmarks
 from mercurial.node import short
 from mercurial.i18n import _
 import os
@@ -38,14 +38,14 @@
     """return the changesets which will be broken by the truncation"""
     s = set()
     def collectone(revlog):
-        links = (revlog.linkrev(i) for i in revlog)
+        linkgen = (revlog.linkrev(i) for i in revlog)
         # find the truncation point of the revlog
-        for lrev in links:
+        for lrev in linkgen:
             if lrev >= striprev:
                 break
         # see if any revision after this point has a linkrev
         # less than striprev (those will be broken by strip)
-        for lrev in links:
+        for lrev in linkgen:
             if lrev < striprev:
                 s.add(lrev)
 
@@ -170,7 +170,3 @@
         raise
 
     repo.destroyed()
-
-    # remove potential unknown phase
-    # XXX using to_strip data would be faster
-    phases.filterunknown(repo)
--- a/mercurial/tags.py	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/tags.py	Sat May 12 00:06:11 2012 +0200
@@ -181,7 +181,7 @@
             for line in cachelines:
                 if line == "\n":
                     break
-                line = line.rstrip().split()
+                line = line.split()
                 cacherevs.append(int(line[0]))
                 headnode = bin(line[1])
                 cacheheads.append(headnode)
--- a/mercurial/util.h	Tue May 08 14:46:04 2012 -0700
+++ b/mercurial/util.h	Sat May 12 00:06:11 2012 +0200
@@ -109,6 +109,7 @@
 typedef int Py_ssize_t;
 typedef Py_ssize_t (*lenfunc)(PyObject *);
 typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
+#define PyInt_FromSsize_t PyInt_FromLong
 
 #if !defined(PY_SSIZE_T_MIN)
 #define PY_SSIZE_T_MAX INT_MAX
--- a/tests/run-tests.py	Tue May 08 14:46:04 2012 -0700
+++ b/tests/run-tests.py	Sat May 12 00:06:11 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-branches.t	Tue May 08 14:46:04 2012 -0700
+++ b/tests/test-branches.t	Sat May 12 00:06:11 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-graft.t	Tue May 08 14:46:04 2012 -0700
+++ b/tests/test-graft.t	Sat May 12 00:06:11 2012 +0200
@@ -72,28 +72,23 @@
   # HG changeset patch
   # User foo
   # Date 0 0
-  # Node ID d2e44c99fd3f31c176ea4efb9eca9f6306c81756
+  # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
   # Parent  68795b066622ca79a25816a662041d8f78f3cd9e
   2
   
   diff --git a/a b/b
   rename from a
   rename to b
-  --- a/a
-  +++ b/b
-  @@ -1,1 +1,1 @@
-  -a
-  +b
 
 Look for extra:source
 
   $ hg log --debug -r tip
-  changeset:   7:d2e44c99fd3f31c176ea4efb9eca9f6306c81756
+  changeset:   7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
   tag:         tip
   phase:       draft
   parent:      0:68795b066622ca79a25816a662041d8f78f3cd9e
   parent:      -1:0000000000000000000000000000000000000000
-  manifest:    7:5d59766436fd8fbcd38e7bebef0f6eaf3eebe637
+  manifest:    7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
   user:        foo
   date:        Thu Jan 01 00:00:00 1970 +0000
   files+:      b
@@ -128,15 +123,20 @@
     checking for directory renames
   resolving manifests
    overwrite: False, partial: False
-   ancestor: 68795b066622, local: d2e44c99fd3f+, remote: 5d205f8b35b6
+   ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
    b: local copied/moved to a -> m
   preserving b for resolve of b
   updating: b 1/1 files (100.00%)
+  picked tool 'internal:merge' for b (binary False symlink False)
+  merging b and a to b
+  my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
+   premerge successful
+  b
   grafting revision 5
     searching for copies back to rev 1
   resolving manifests
    overwrite: False, partial: False
-   ancestor: 4c60f11aa304, local: d2e44c99fd3f+, remote: 97f8bfe72746
+   ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
    e: remote is newer -> g
   updating: e 1/1 files (100.00%)
   getting e
@@ -145,7 +145,7 @@
     searching for copies back to rev 1
   resolving manifests
    overwrite: False, partial: False
-   ancestor: 4c60f11aa304, local: 839a7e8fcf80+, remote: 9c233e8e184d
+   ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
    e: versions differ -> m
    d: remote is newer -> g
   preserving e for resolve of e
@@ -154,7 +154,7 @@
   updating: e 2/2 files (100.00%)
   picked tool 'internal:merge' for e (binary False symlink False)
   merging e
-  my e@839a7e8fcf80+ other e@9c233e8e184d ancestor e@68795b066622
+  my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
   warning: conflicts during merge.
   merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts, can't continue
@@ -200,11 +200,13 @@
 View graph:
 
   $ hg --config extensions.graphlog= log -G --template '{author}@{rev}.{phase}: {desc}\n'
-  @  test@10.draft: 3
+  @  test@11.draft: 3
+  |
+  o  test@10.draft: 4
   |
-  o  test@9.draft: 4
+  o  test@9.draft: 5
   |
-  o  test@8.draft: 5
+  o  bar@8.draft: 1
   |
   o  foo@7.draft: 2
   |
@@ -232,17 +234,17 @@
   grafting revision 7
 
   $ hg log -r 7 --template '{rev}:{node}\n'
-  7:d2e44c99fd3f31c176ea4efb9eca9f6306c81756
+  7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
   $ hg log -r 2 --template '{rev}:{node}\n'
   2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
 
   $ hg log --debug -r tip
-  changeset:   12:95adbe5de6b10f376b699ece9ed5a57cd7b4b0f6
+  changeset:   13:9db0f28fd3747e92c57d015f53b5593aeec53c2d
   tag:         tip
   phase:       draft
-  parent:      11:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
+  parent:      12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
   parent:      -1:0000000000000000000000000000000000000000
-  manifest:    12:9944044f82a462bbaccc9bdf7e0ac5b811db7d1b
+  manifest:    13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
   user:        foo
   date:        Thu Jan 01 00:00:00 1970 +0000
   files+:      b
@@ -260,7 +262,7 @@
   [255]
 
 Disallow grafting already grafted csets with the same origin onto each other
-  $ hg up -q 12
+  $ hg up -q 13
   $ hg graft 2
   skipping already grafted revision 2
   [255]
@@ -273,5 +275,5 @@
   skipping already grafted revision 2
   [255]
   $ hg graft tip
-  skipping already grafted revision 12 (same origin 2)
+  skipping already grafted revision 13 (same origin 2)
   [255]
--- a/tests/test-keyword.t	Tue May 08 14:46:04 2012 -0700
+++ b/tests/test-keyword.t	Sat May 12 00:06:11 2012 +0200
@@ -558,6 +558,7 @@
   $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
   c
    c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
+  removing unknown node 40a904bbbe4c from 1-phase boundary
   overwriting c expanding keywords
   committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
   $ cat a c
@@ -722,6 +723,7 @@
 
   $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
   a
+  removing unknown node 40a904bbbe4c from 1-phase boundary
   overwriting a expanding keywords
   committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
   $ rm log
--- a/tests/test-largefiles.t	Tue May 08 14:46:04 2012 -0700
+++ b/tests/test-largefiles.t	Sat May 12 00:06:11 2012 +0200
@@ -1136,4 +1136,37 @@
   abort: uncommitted changes in subrepo subrepo
   (use --subrepos for recursive commit)
   [255]
+
+Add a normal file to the subrepo, then test archiving
+
+  $ echo 'normal file' > subrepo/normal.txt
+  $ hg -R subrepo add subrepo/normal.txt
+
+Lock in subrepo, otherwise the change isn't archived
+
+  $ hg ci -S -m "add normal file to top level"
+  committing subrepository subrepo
+  Invoking status precommit hook
+  M large.txt
+  A normal.txt
+  Invoking status precommit hook
+  M .hgsubstate
+  $ hg archive -S lf_subrepo_archive
+  $ find lf_subrepo_archive | sort
+  lf_subrepo_archive
+  lf_subrepo_archive/.hg_archival.txt
+  lf_subrepo_archive/.hgsub
+  lf_subrepo_archive/.hgsubstate
+  lf_subrepo_archive/a
+  lf_subrepo_archive/a/b
+  lf_subrepo_archive/a/b/c
+  lf_subrepo_archive/a/b/c/d
+  lf_subrepo_archive/a/b/c/d/e.large.txt
+  lf_subrepo_archive/a/b/c/d/e.normal.txt
+  lf_subrepo_archive/a/b/c/x
+  lf_subrepo_archive/a/b/c/x/y.normal.txt
+  lf_subrepo_archive/subrepo
+  lf_subrepo_archive/subrepo/large.txt
+  lf_subrepo_archive/subrepo/normal.txt
+
   $ cd ..
--- a/tests/test-phases.t	Tue May 08 14:46:04 2012 -0700
+++ b/tests/test-phases.t	Sat May 12 00:06:11 2012 +0200
@@ -9,6 +9,15 @@
 
   $ hg init initialrepo
   $ cd initialrepo
+
+Cannot change null revision phase
+
+  $ hg phase --force --secret null
+  abort: unknown revision '-1'!
+  [255]
+  $ hg phase null
+  -1: public
+
   $ mkcommit A
 
 New commit are draft by default
--- a/tests/test-rebase-parameters.t	Tue May 08 14:46:04 2012 -0700
+++ b/tests/test-rebase-parameters.t	Sat May 12 00:06:11 2012 +0200
@@ -158,12 +158,12 @@
   $ cd ..
 
 
-Rebase with dest == `hg branch` => same as no arguments (from 3 onto 8):
+Rebase with dest == branch(.) => same as no arguments (from 3 onto 8):
 
   $ hg clone -q -u 3 a a3
   $ cd a3
 
-  $ hg rebase --dest `hg branch`
+  $ hg rebase --dest 'branch(.)'
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
--- a/tests/test-transplant.t	Tue May 08 14:46:04 2012 -0700
+++ b/tests/test-transplant.t	Sat May 12 00:06:11 2012 +0200
@@ -120,7 +120,25 @@
   1  r2
   0  r1
 
+test same-parent transplant with --log
 
+  $ hg clone -r 1 ../t ../sameparent
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd ../sameparent
+  $ hg transplant --log -s ../prune 5
+  searching for changes
+  applying e234d668f844
+  e234d668f844 transplanted to e07aea8ecf9c
+  $ hg log --template '{rev} {parents} {desc}\n'
+  2  b1
+  (transplanted from e234d668f844e1b1a765f01db83a32c0c7bfa170)
+  1  r2
+  0  r1
 remote transplant
 
   $ hg clone -r 1 ../t ../remote