changeset 19135:1c2dd751c12d

merge with stable
author Matt Mackall <mpm@selenic.com>
date Sat, 04 May 2013 14:52:51 -0500
parents 75031762aff2 (diff) af3b651505e2 (current diff)
children e073ac988b51
files
diffstat 21 files changed, 240 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/check-code.py	Sat May 04 14:51:21 2013 -0500
+++ b/contrib/check-code.py	Sat May 04 14:52:51 2013 -0500
@@ -109,6 +109,14 @@
     (r'^  changeset .* references (corrupted|missing) \$TESTTMP/.*[^)]$',
      winglobmsg),
     (r'^  pulling from \$TESTTMP/.*[^)]$', winglobmsg, '\$TESTTMP/unix-repo$'),
+    (r'^  reverting .*/.*[^)]$', winglobmsg, '\$TESTTMP/unix-repo$'),
+    (r'^  cloning subrepo \S+/.*[^)]$', winglobmsg, '\$TESTTMP/unix-repo$'),
+    (r'^  pushing to \$TESTTMP/.*[^)]$', winglobmsg, '\$TESTTMP/unix-repo$'),
+    (r'^  moving \S+/.*[^)]$', winglobmsg),
+    (r'^  no changes made to subrepo since.*/.*[^)]$',
+     winglobmsg, '\$TESTTMP/unix-repo$'),
+    (r'^  .*: largefile \S+ not available from file:.*/.*[^)]$',
+     winglobmsg, '\$TESTTMP/unix-repo$'),
   ],
   # warnings
   [
--- a/hgext/convert/common.py	Sat May 04 14:51:21 2013 -0500
+++ b/hgext/convert/common.py	Sat May 04 14:52:51 2013 -0500
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import base64, errno, subprocess, os, datetime
+import base64, errno, subprocess, os, datetime, re
 import cPickle as pickle
 from mercurial import util
 from mercurial.i18n import _
@@ -63,6 +63,14 @@
 
         self.encoding = 'utf-8'
 
+    def checkhexformat(self, revstr):
+        """ fails if revstr is not a 40 byte hex. mercurial and git both uses
+            such format for their revision numbering
+        """
+        if not re.match(r'[0-9a-fA-F]{40,40}$', revstr):
+            raise util.Abort(_('splicemap entry %s is not a valid revision'
+                               ' identifier') % revstr)
+
     def before(self):
         pass
 
@@ -164,6 +172,13 @@
         """
         return {}
 
+    def checkrevformat(self, revstr):
+        """revstr is a string that describes a revision in the given
+           source control system.  Return true if revstr has correct
+           format.
+        """
+        return True
+
 class converter_sink(object):
     """Conversion sink (target) interface"""
 
@@ -424,34 +439,6 @@
             self.fp.close()
             self.fp = None
 
-def parsesplicemap(path):
-    """Parse a splicemap, return a child/parents dictionary."""
-    if not path:
-        return {}
-    m = {}
-    try:
-        fp = open(path, 'r')
-        for i, line in enumerate(fp):
-            line = line.splitlines()[0].rstrip()
-            if not line:
-                # Ignore blank lines
-                continue
-            try:
-                child, parents = line.split(' ', 1)
-                parents = parents.replace(',', ' ').split()
-            except ValueError:
-                raise util.Abort(_('syntax error in %s(%d): child parent1'
-                                   '[,parent2] expected') % (path, i + 1))
-            pp = []
-            for p in parents:
-                if p not in pp:
-                    pp.append(p)
-            m[child] = pp
-    except IOError, e:
-        if e.errno != errno.ENOENT:
-            raise
-    return m
-
 def makedatetimestamp(t):
     """Like util.makedate() but for time t instead of current time"""
     delta = (datetime.datetime.utcfromtimestamp(t) -
--- a/hgext/convert/convcmd.py	Sat May 04 14:51:21 2013 -0500
+++ b/hgext/convert/convcmd.py	Sat May 04 14:52:51 2013 -0500
@@ -15,7 +15,7 @@
 from gnuarch import gnuarch_source
 from bzr import bzr_source
 from p4 import p4_source
-import filemap, common
+import filemap
 
 import os, shutil
 from mercurial import hg, util, encoding
@@ -118,9 +118,57 @@
             self.readauthormap(opts.get('authormap'))
             self.authorfile = self.dest.authorfile()
 
-        self.splicemap = common.parsesplicemap(opts.get('splicemap'))
+        self.splicemap = self.parsesplicemap(opts.get('splicemap'))
         self.branchmap = mapfile(ui, opts.get('branchmap'))
 
+    def parsesplicemap(self, path):
+        """ check and validate the splicemap format and
+            return a child/parents dictionary.
+            Format checking has two parts.
+            1. generic format which is same across all source types
+            2. specific format checking which may be different for
+               different source type.  This logic is implemented in
+               checkrevformat function in source files like
+               hg.py, subversion.py etc.
+        """
+
+        if not path:
+            return {}
+        m = {}
+        try:
+            fp = open(path, 'r')
+            for i, line in enumerate(fp):
+                line = line.splitlines()[0].rstrip()
+                if not line:
+                    # Ignore blank lines
+                    continue
+                try:
+                    child, parents = line.split(' ', 1)
+                    self.source.checkrevformat(child)
+                    parents = parents.replace(',', ' ').split()
+                    # check if number of parents are upto 2 max
+                    if (len(parents) > 2):
+                        raise util.Abort(_('syntax error in %s(%d): child '\
+                                            'parent1[,parent2] expected') \
+                                            % (path, i + 1))
+                    for parent in parents:
+                        self.source.checkrevformat(parent)
+                except ValueError:
+                    raise util.Abort(_('syntax error in %s(%d): child '\
+                                        'parent1[,parent2] expected') \
+                                        % (path, i + 1))
+                pp = []
+                for p in parents:
+                    if p not in pp:
+                        pp.append(p)
+                m[child] = pp
+         # if file does not exist or error reading, exit
+        except IOError:
+            raise util.Abort(_('splicemap file not found or error reading %s:')
+                               % path)
+        return m
+
+
     def walktree(self, heads):
         '''Return a mapping that identifies the uncommitted parents of every
         uncommitted changeset.'''
--- a/hgext/convert/git.py	Sat May 04 14:51:21 2013 -0500
+++ b/hgext/convert/git.py	Sat May 04 14:52:51 2013 -0500
@@ -296,3 +296,8 @@
                 pass
 
         return bookmarks
+
+    def checkrevformat(self, revstr):
+        """ git revision string is a 40 byte hex """
+        self.checkhexformat(revstr)
+
--- a/hgext/convert/hg.py	Sat May 04 14:51:21 2013 -0500
+++ b/hgext/convert/hg.py	Sat May 04 14:52:51 2013 -0500
@@ -397,3 +397,7 @@
 
     def getbookmarks(self):
         return bookmarks.listbookmarks(self.repo)
+
+    def checkrevformat(self, revstr):
+        """ Mercurial, revision string is a 40 byte hex """
+        self.checkhexformat(revstr)
--- a/hgext/convert/subversion.py	Sat May 04 14:51:21 2013 -0500
+++ b/hgext/convert/subversion.py	Sat May 04 14:52:51 2013 -0500
@@ -452,6 +452,14 @@
         del self.commits[rev]
         return commit
 
+    def checkrevformat(self, revstr):
+        """ fails if revision format does not match the correct format"""
+        if not re.match(r'svn:[0-9a-f]{8,8}-[0-9a-f]{4,4}-'
+                              '[0-9a-f]{4,4}-[0-9a-f]{4,4}-[0-9a-f]'
+                              '{12,12}(.*)\@[0-9]+$',revstr):
+            raise util.Abort(_('splicemap entry %s is not a valid revision'
+                               ' identifier') % revstr)
+
     def gettags(self):
         tags = {}
         if self.tags is None:
--- a/mercurial/help/templates.txt	Sat May 04 14:51:21 2013 -0500
+++ b/mercurial/help/templates.txt	Sat May 04 14:52:51 2013 -0500
@@ -6,8 +6,8 @@
 You can customize output for any "log-like" command: log,
 outgoing, incoming, tip, parents, heads and glog.
 
-Four styles are packaged with Mercurial: default (the style used
-when no explicit preference is passed), compact, changelog,
+Five styles are packaged with Mercurial: default (the style used
+when no explicit preference is passed), compact, changelog, phases
 and xml.
 Usage::
 
--- a/mercurial/templater.py	Sat May 04 14:51:21 2013 -0500
+++ b/mercurial/templater.py	Sat May 04 14:52:51 2013 -0500
@@ -394,6 +394,16 @@
 
 engines = {'default': engine}
 
+def stylelist():
+    path = templatepath()[0]
+    dirlist =  os.listdir(path)
+    stylelist = []
+    for file in dirlist:
+        split = file.split(".")
+        if split[0] == "map-cmdline":
+            stylelist.append(split[1])
+    return ", ".join(sorted(stylelist))
+
 class templater(object):
 
     def __init__(self, mapfile, filters={}, defaults={}, cache={},
@@ -415,7 +425,8 @@
         if not mapfile:
             return
         if not os.path.exists(mapfile):
-            raise util.Abort(_('style not found: %s') % mapfile)
+            raise util.Abort(_("style '%s' not found") % mapfile,
+                             hint=_("available styles: %s") % stylelist())
 
         conf = config.config()
         conf.read(mapfile)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/templates/map-cmdline.phases	Sat May 04 14:52:51 2013 -0500
@@ -0,0 +1,25 @@
+changeset = 'changeset:   {rev}:{node|short}\n{branches}{bookmarks}{tags}phase:       {phase}\n{parents}user:        {author}\ndate:        {date|date}\nsummary:     {desc|firstline}\n\n'
+changeset_quiet = '{rev}:{node|short}\n'
+changeset_verbose = 'changeset:   {rev}:{node|short}\n{branches}{bookmarks}{tags}{parents}user:        {author}\ndate:        {date|date}\n{files}{file_copies_switch}description:\n{desc|strip}\n\n\n'
+changeset_debug = 'changeset:   {rev}:{node}\n{branches}{bookmarks}{tags}phase:       {phase}\n{parents}{manifest}user:        {author}\ndate:        {date|date}\n{file_mods}{file_adds}{file_dels}{file_copies_switch}{extras}description:\n{desc|strip}\n\n\n'
+start_files = 'files:      '
+file = ' {file}'
+end_files = '\n'
+start_file_mods = 'files:      '
+file_mod = ' {file_mod}'
+end_file_mods = '\n'
+start_file_adds = 'files+:     '
+file_add = ' {file_add}'
+end_file_adds = '\n'
+start_file_dels = 'files-:     '
+file_del = ' {file_del}'
+end_file_dels = '\n'
+start_file_copies = 'copies:     '
+file_copy = ' {name} ({source})'
+end_file_copies = '\n'
+parent = 'parent:      {rev}:{node|formatnode}\n'
+manifest = 'manifest:    {rev}:{node}\n'
+branch = 'branch:      {branch}\n'
+tag = 'tag:         {tag}\n'
+bookmark = 'bookmark:    {bookmark}\n'
+extra = 'extra:       {key}={value|stringescape}\n'
--- a/tests/run-tests.py	Sat May 04 14:51:21 2013 -0500
+++ b/tests/run-tests.py	Sat May 04 14:52:51 2013 -0500
@@ -1120,6 +1120,8 @@
         childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
         childtmp = os.path.join(HGTMP, 'child%d' % j)
         childopts += ['--tmpdir', childtmp]
+        if options.keep_tmpdir:
+            childopts.append('--keep-tmpdir')
         cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
         vlog(' '.join(cmdline))
         proc = subprocess.Popen(cmdline, executable=cmdline[0])
@@ -1288,7 +1290,8 @@
     global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
     TESTDIR = os.environ["TESTDIR"] = os.getcwd()
     if options.tmpdir:
-        options.keep_tmpdir = True
+        if not options.child:
+            options.keep_tmpdir = True
         tmpdir = options.tmpdir
         if os.path.exists(tmpdir):
             # Meaning of tmpdir has changed since 1.3: we used to create
--- a/tests/test-command-template.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-command-template.t	Sat May 04 14:52:51 2013 -0500
@@ -458,7 +458,8 @@
 Error if no style:
 
   $ hg log --style notexist
-  abort: style not found: notexist
+  abort: style 'notexist' not found
+  (available styles: bisect, changelog, compact, default, phases, xml)
   [255]
 
 Error if style missing key:
--- a/tests/test-commandserver.py	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-commandserver.py	Sat May 04 14:52:51 2013 -0500
@@ -25,7 +25,11 @@
     else:
         return channel, server.stdout.read(length)
 
-def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None):
+def sep(text):
+    return text.replace('\\', '/')
+
+def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None,
+               outfilter=lambda x: x):
     print ' runcommand', ' '.join(args)
     sys.stdout.flush()
     server.stdin.write('runcommand\n')
@@ -37,7 +41,7 @@
     while True:
         ch, data = readchannel(server)
         if ch == 'o':
-            output.write(data)
+            output.write(outfilter(data))
             output.flush()
         elif ch == 'e':
             error.write(data)
@@ -249,7 +253,8 @@
 
     # make it public; draft marker moves to 4:7966c8e3734d
     runcommand(server, ['phase', '-p', '.'])
-    runcommand(server, ['phase', '.'])  # load _phasecache.phaseroots
+    # load _phasecache.phaseroots
+    runcommand(server, ['phase', '.'], outfilter=sep)
 
     # strip 1::4 outside server
     os.system('hg --config extensions.mq= strip 1')
--- a/tests/test-convert-git.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-convert-git.t	Sat May 04 14:52:51 2013 -0500
@@ -13,6 +13,10 @@
   $ GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
   $ GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
   $ GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+  $ INVALIDID1=afd12345af
+  $ INVALIDID2=28173x36ddd1e67bf7098d541130558ef5534a86
+  $ VALIDID1=39b3d83f9a69a9ba4ebb111461071a0af0027357
+  $ VALIDID2=8dd6476bd09d9c7776355dc454dafe38efaec5da
   $ count=10
   $ commit()
   > {
@@ -298,6 +302,36 @@
   $ commit -a -m 'addsubmodule' >/dev/null 2>/dev/null
   $ cd ..
 
+test invalid splicemap1
+
+  $ cat > splicemap <<EOF
+  > $VALIDID1
+  > EOF
+  $ hg convert --splicemap splicemap git-repo2 git-repo2-splicemap1-hg
+  initializing destination git-repo2-splicemap1-hg repository
+  abort: syntax error in splicemap(1): child parent1[,parent2] expected
+  [255]
+
+test invalid splicemap2
+
+  $ cat > splicemap <<EOF
+  > $VALIDID1 $VALIDID2, $VALIDID2, $VALIDID2
+  > EOF
+  $ hg convert --splicemap splicemap git-repo2 git-repo2-splicemap2-hg
+  initializing destination git-repo2-splicemap2-hg repository
+  abort: syntax error in splicemap(1): child parent1[,parent2] expected
+  [255]
+
+test invalid splicemap3
+
+  $ cat > splicemap <<EOF
+  > $INVALIDID1 $INVALIDID2
+  > EOF
+  $ hg convert --splicemap splicemap git-repo2 git-repo2-splicemap3-hg
+  initializing destination git-repo2-splicemap3-hg repository
+  abort: splicemap entry afd12345af is not a valid revision identifier
+  [255]
+
 convert sub modules
   $ hg convert git-repo6 git-repo6-hg
   initializing destination git-repo6-hg repository
--- a/tests/test-convert-splicemap.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-convert-splicemap.t	Sat May 04 14:52:51 2013 -0500
@@ -37,6 +37,8 @@
   $ hg ci -Am addaandd
   adding a
   adding d
+  $ INVALIDID1=afd12345af
+  $ INVALIDID2=28173x36ddd1e67bf7098d541130558ef5534a86
   $ CHILDID1=`hg id --debug -i`
   $ echo d >> d
   $ hg ci -Am changed
@@ -53,7 +55,7 @@
   o  0:527cdedf31fb "addaandd" files: a d
   
 
-test invalid splicemap
+test invalid splicemap1
 
   $ cat > splicemap <<EOF
   > $CHILDID2
@@ -62,6 +64,24 @@
   abort: syntax error in splicemap(1): child parent1[,parent2] expected
   [255]
 
+test invalid splicemap2
+
+  $ cat > splicemap <<EOF
+  > $CHILDID2 $PARENTID1, $PARENTID2, $PARENTID2
+  > EOF
+  $ hg convert --splicemap splicemap repo2 repo1
+  abort: syntax error in splicemap(1): child parent1[,parent2] expected
+  [255]
+
+test invalid splicemap3
+
+  $ cat > splicemap <<EOF
+  > $INVALIDID1 $INVALIDID2
+  > EOF
+  $ hg convert --splicemap splicemap repo2 repo1
+  abort: splicemap entry afd12345af is not a valid revision identifier
+  [255]
+
 splice repo2 on repo1
 
   $ cat > splicemap <<EOF
--- a/tests/test-convert-svn-source.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-convert-svn-source.t	Sat May 04 14:52:51 2013 -0500
@@ -16,6 +16,8 @@
 #else
   $ SVNREPOURL=file://`python -c "import urllib, sys; sys.stdout.write(urllib.quote(sys.argv[1]))" "$SVNREPOPATH"`
 #endif
+  $ INVALIDREVISIONID=svn:x2147622-4a9f-4db4-a8d3-13562ff547b2/proj%20B/mytrunk@1
+  $ VALIDREVISIONID=svn:a2147622-4a9f-4db4-a8d3-13562ff547b2/proj%20B/mytrunk/mytrunk@1
 
 Now test that it works with trunk/tags layout, but no branches yet.
 
@@ -168,6 +170,15 @@
   |
   o  0 second letter files: letter2.txt
   
+test invalid splicemap1
+
+  $ cat > splicemap <<EOF
+  > $INVALIDREVISIONID $VALIDREVISIONID
+  > EOF
+  $ hg convert --splicemap splicemap "$SVNREPOURL/proj%20B/mytrunk" smap
+  initializing destination smap repository
+  abort: splicemap entry svn:x2147622-4a9f-4db4-a8d3-13562ff547b2/proj%20B/mytrunk@1 is not a valid revision identifier
+  [255]
 
 Test stop revision
   $ hg convert --rev 1 "$SVNREPOURL/proj%20B/mytrunk" stoprev
--- a/tests/test-log.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-log.t	Sat May 04 14:52:51 2013 -0500
@@ -84,6 +84,25 @@
   abort: cannot follow file not in parent revision: "dir"
   [255]
 
+-f, a wrong style
+
+  $ hg log -f -l1 --style something
+  abort: style 'something' not found
+  (available styles: bisect, changelog, compact, default, phases, xml)
+  [255]
+
+-f, phases style
+
+
+  $ hg log -f -l1 --style phases
+  changeset:   4:7e4639b4691b
+  tag:         tip
+  phase:       draft
+  user:        test
+  date:        Thu Jan 01 00:00:05 1970 +0000
+  summary:     e
+  
+
 -f, but no args
 
   $ hg log -f
--- a/tests/test-nested-repo.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-nested-repo.t	Sat May 04 14:52:51 2013 -0500
@@ -8,6 +8,9 @@
   $ hg add b
   $ hg st
 
+  $ echo y > b/y
+  $ hg st
+
 Should fail:
 
   $ hg st b/x
--- a/tests/test-rebase-rename.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-rebase-rename.t	Sat May 04 14:52:51 2013 -0500
@@ -22,7 +22,7 @@
   adding d/b
 
   $ hg mv d d-renamed
-  moving d/b to d-renamed/b
+  moving d/b to d-renamed/b (glob)
   $ hg ci -m 'rename B'
 
   $ hg up -q -C 1
--- a/tests/test-rename-dir-merge.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-rename-dir-merge.t	Sat May 04 14:52:51 2013 -0500
@@ -51,7 +51,7 @@
   getting b/b
   updating: b/b 4/5 files (80.00%)
   updating: a/c 5/5 files (100.00%)
-  moving a/c to b/c
+  moving a/c to b/c (glob)
   3 files updated, 0 files merged, 2 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
 
--- a/tests/test-subrepo.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-subrepo.t	Sat May 04 14:52:51 2013 -0500
@@ -391,7 +391,7 @@
   $ hg -R s update '.^'
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg push
-  pushing to $TESTTMP/t
+  pushing to $TESTTMP/t (glob)
   no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
   no changes made to subrepo s since last push to $TESTTMP/t/s
   no changes made to subrepo t since last push to $TESTTMP/t/t
@@ -400,7 +400,7 @@
   [1]
   $ echo foo >> s/a
   $ hg push
-  pushing to $TESTTMP/t
+  pushing to $TESTTMP/t (glob)
   no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
   no changes made to subrepo s since last push to $TESTTMP/t/s
   no changes made to subrepo t since last push to $TESTTMP/t/t
@@ -415,7 +415,7 @@
   $ echo foo >> s/ss/a
   $ hg -R s/ss commit -m 'test dirty store detection'
   $ hg push
-  pushing to $TESTTMP/t
+  pushing to $TESTTMP/t (glob)
   pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
   searching for changes
   adding changesets
@@ -431,7 +431,7 @@
 a subrepo store may be clean versus one repo but not versus another
 
   $ hg push
-  pushing to $TESTTMP/t
+  pushing to $TESTTMP/t (glob)
   no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss (glob)
   no changes made to subrepo s since last push to $TESTTMP/t/s
   no changes made to subrepo t since last push to $TESTTMP/t/t
@@ -798,7 +798,7 @@
 Try to push from the other side
 
   $ hg -R issue1852a push `pwd`/issue1852c
-  pushing to $TESTTMP/issue1852c
+  pushing to $TESTTMP/issue1852c (glob)
   pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
   searching for changes
   no changes found
--- a/tests/test-tag.t	Sat May 04 14:51:21 2013 -0500
+++ b/tests/test-tag.t	Sat May 04 14:52:51 2013 -0500
@@ -316,7 +316,7 @@
   adding test
   $ hg init repo-tag-target
   $ hg -R repo-tag --config hooks.commit="\"hg\" push \"`pwd`/repo-tag-target\"" tag tag
-  pushing to $TESTTMP/repo-tag-target
+  pushing to $TESTTMP/repo-tag-target (glob)
   searching for changes
   adding changesets
   adding manifests