changeset 21585:652e07debf10

merge with stable
author Matt Mackall <mpm@selenic.com>
date Tue, 27 May 2014 17:41:20 -0700
parents 32601b0b74c0 (current diff) 4dca1a06e7ee (diff)
children 8a2637cf1130
files mercurial/commands.py mercurial/subrepo.py tests/test-bundle2.t tests/test-encoding-align.t tests/test-subrepo-git.t tests/test-subrepo-svn.t
diffstat 9 files changed, 240 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py	Sat Mar 08 19:02:39 2014 +1100
+++ b/mercurial/commands.py	Tue May 27 17:41:20 2014 -0700
@@ -950,8 +950,9 @@
                 if ui.quiet:
                     ui.write("%s\n" % bmark, label=label)
                 else:
-                    ui.write(" %s %-25s %d:%s\n" % (
-                        prefix, bmark, repo.changelog.rev(n), hexfn(n)),
+                    pad = " " * (25 - encoding.colwidth(bmark))
+                    ui.write(" %s %s%s %d:%s\n" % (
+                        prefix, bmark, pad, repo.changelog.rev(n), hexfn(n)),
                         label=label)
 
 @command('branch',
--- a/mercurial/dispatch.py	Sat Mar 08 19:02:39 2014 +1100
+++ b/mercurial/dispatch.py	Tue May 27 17:41:20 2014 -0700
@@ -355,7 +355,7 @@
         if not self.definition:
             def fn(ui, *args):
                 ui.warn(_("no definition for alias '%s'\n") % self.name)
-                return 1
+                return -1
             self.fn = fn
             self.badalias = True
             return
@@ -383,7 +383,16 @@
             self.fn = fn
             return
 
-        args = shlex.split(self.definition)
+        try:
+            args = shlex.split(self.definition)
+        except ValueError, inst:
+            def fn(ui, *args):
+                ui.warn(_("error in definition for alias '%s': %s\n")
+                        % (self.name, inst))
+                return -1
+            self.fn = fn
+            self.badalias = True
+            return
         self.cmdname = cmd = args.pop(0)
         args = map(util.expandpath, args)
 
@@ -393,7 +402,7 @@
                     ui.warn(_("error in definition for alias '%s': %s may only "
                               "be given on the command line\n")
                             % (self.name, invalidarg))
-                    return 1
+                    return -1
 
                 self.fn = fn
                 self.badalias = True
@@ -425,14 +434,14 @@
                     commands.help_(ui, cmd, unknowncmd=True)
                 except error.UnknownCommand:
                     pass
-                return 1
+                return -1
             self.fn = fn
             self.badalias = True
         except error.AmbiguousCommand:
             def fn(ui, *args):
                 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
                             % (self.name, cmd))
-                return 1
+                return -1
             self.fn = fn
             self.badalias = True
 
--- a/mercurial/pathutil.py	Sat Mar 08 19:02:39 2014 +1100
+++ b/mercurial/pathutil.py	Tue May 27 17:41:20 2014 -0700
@@ -142,3 +142,25 @@
             name = dirname
 
         raise util.Abort(_("%s not under root '%s'") % (myname, root))
+
+def normasprefix(path):
+    '''normalize the specified path as path prefix
+
+    Returned vaule can be used safely for "p.startswith(prefix)",
+    "p[len(prefix):]", and so on.
+
+    For efficiency, this expects "path" argument to be already
+    normalized by "os.path.normpath", "os.path.realpath", and so on.
+
+    See also issue3033 for detail about need of this function.
+
+    >>> normasprefix('/foo/bar').replace(os.sep, '/')
+    '/foo/bar/'
+    >>> normasprefix('/').replace(os.sep, '/')
+    '/'
+    '''
+    d, p = os.path.splitdrive(path)
+    if len(p) != len(os.sep):
+        return path + os.sep
+    else:
+        return path
--- a/mercurial/subrepo.py	Sat Mar 08 19:02:39 2014 +1100
+++ b/mercurial/subrepo.py	Tue May 27 17:41:20 2014 -0700
@@ -277,8 +277,7 @@
     parent = repo
     while util.safehasattr(parent, '_subparent'):
         parent = parent._subparent
-    p = parent.root.rstrip(os.sep)
-    return repo.root[len(p) + 1:]
+    return repo.root[len(pathutil.normasprefix(parent.root)):]
 
 def subrelpath(sub):
     """return path to this subrepo as seen from outermost repo"""
@@ -315,17 +314,19 @@
     if abort:
         raise util.Abort(_("default path for subrepository not found"))
 
-def _sanitize(ui, path):
-    def v(arg, dirname, names):
+def _sanitize(ui, path, ignore):
+    for dirname, dirs, names in os.walk(path):
+        for i, d in enumerate(dirs):
+            if d.lower() == ignore:
+                del dirs[i]
+                break
         if os.path.basename(dirname).lower() != '.hg':
-            return
+            continue
         for f in names:
             if f.lower() == 'hgrc':
-                ui.warn(
-                    _("warning: removing potentially hostile .hg/hgrc in '%s'")
-                      % path)
+                ui.warn(_("warning: removing potentially hostile 'hgrc' "
+                          "in '%s'\n") % dirname)
                 os.unlink(os.path.join(dirname, f))
-    os.walk(path, v, None)
 
 def subrepo(ctx, path):
     """return instance of the right subrepo class for subrepo in path"""
@@ -1059,7 +1060,7 @@
         # update to a directory which has since been deleted and recreated.
         args.append('%s@%s' % (state[0], state[1]))
         status, err = self._svncommand(args, failok=True)
-        _sanitize(self._ui, self._path)
+        _sanitize(self._ui, self._ctx._repo.wjoin(self._path), '.svn')
         if not re.search('Checked out revision [0-9]+.', status):
             if ('is already a working copy for a different URL' in err
                 and (self._wcchanged()[:2] == (False, False))):
@@ -1352,7 +1353,7 @@
                 self._gitcommand(['reset', 'HEAD'])
                 cmd.append('-f')
             self._gitcommand(cmd + args)
-            _sanitize(self._ui, self._path)
+            _sanitize(self._ui, self._abspath, '.git')
 
         def rawcheckout():
             # no branch to checkout, check it out with no branch
@@ -1401,6 +1402,7 @@
             if tracking[remote] != self._gitcurrentbranch():
                 checkout([tracking[remote]])
             self._gitcommand(['merge', '--ff', remote])
+            _sanitize(self._ui, self._abspath, '.git')
         else:
             # a real merge would be required, just checkout the revision
             rawcheckout()
@@ -1436,7 +1438,7 @@
                 self.get(state) # fast forward merge
             elif base != self._state[1]:
                 self._gitcommand(['merge', '--no-commit', revision])
-            _sanitize(self._ui, self._path)
+            _sanitize(self._ui, self._abspath, '.git')
 
         if self.dirty():
             if self._gitstate() != revision:
--- a/tests/test-alias.t	Sat Mar 08 19:02:39 2014 +1100
+++ b/tests/test-alias.t	Tue May 27 17:41:20 2014 -0700
@@ -11,6 +11,7 @@
   > ambiguous = s
   > recursive = recursive
   > nodefinition =
+  > noclosingquotation = '
   > no--cwd = status --cwd elsewhere
   > no-R = status -R elsewhere
   > no--repo = status --repo elsewhere
@@ -60,7 +61,7 @@
 
   $ hg unknown
   alias 'unknown' resolves to unknown command 'bargle'
-  [1]
+  [255]
   $ hg help unknown
   alias 'unknown' resolves to unknown command 'bargle'
 
@@ -69,7 +70,7 @@
 
   $ hg ambiguous
   alias 'ambiguous' resolves to ambiguous command 's'
-  [1]
+  [255]
   $ hg help ambiguous
   alias 'ambiguous' resolves to ambiguous command 's'
 
@@ -78,7 +79,7 @@
 
   $ hg recursive
   alias 'recursive' resolves to unknown command 'recursive'
-  [1]
+  [255]
   $ hg help recursive
   alias 'recursive' resolves to unknown command 'recursive'
 
@@ -87,36 +88,45 @@
 
   $ hg nodef
   no definition for alias 'nodefinition'
-  [1]
+  [255]
   $ hg help nodef
   no definition for alias 'nodefinition'
 
 
+no closing quotation
+
+  $ hg noclosing
+  error in definition for alias 'noclosingquotation': No closing quotation
+  [255]
+  $ hg help noclosing
+  error in definition for alias 'noclosingquotation': No closing quotation
+
+
 invalid options
 
   $ hg no--cwd
   error in definition for alias 'no--cwd': --cwd may only be given on the command line
-  [1]
+  [255]
   $ hg help no--cwd
   error in definition for alias 'no--cwd': --cwd may only be given on the command line
   $ hg no-R
   error in definition for alias 'no-R': -R may only be given on the command line
-  [1]
+  [255]
   $ hg help no-R
   error in definition for alias 'no-R': -R may only be given on the command line
   $ hg no--repo
   error in definition for alias 'no--repo': --repo may only be given on the command line
-  [1]
+  [255]
   $ hg help no--repo
   error in definition for alias 'no--repo': --repo may only be given on the command line
   $ hg no--repository
   error in definition for alias 'no--repository': --repository may only be given on the command line
-  [1]
+  [255]
   $ hg help no--repository
   error in definition for alias 'no--repository': --repository may only be given on the command line
   $ hg no--config
   error in definition for alias 'no--config': --config may only be given on the command line
-  [1]
+  [255]
 
 optional repository
 
--- a/tests/test-doctest.py	Sat Mar 08 19:02:39 2014 +1100
+++ b/tests/test-doctest.py	Tue May 27 17:41:20 2014 -0700
@@ -19,6 +19,7 @@
 testmod('mercurial.hgweb.hgwebdir_mod')
 testmod('mercurial.match')
 testmod('mercurial.minirst')
+testmod('mercurial.pathutil')
 testmod('mercurial.revset')
 testmod('mercurial.store')
 testmod('mercurial.subrepo')
--- a/tests/test-encoding-align.t	Sat Mar 08 19:02:39 2014 +1100
+++ b/tests/test-encoding-align.t	Tue May 27 17:41:20 2014 -0700
@@ -116,22 +116,25 @@
   marked working directory as branch \xe7\x9f\xad\xe5\x90\x8d (esc)
   (branches are permanent and global, did you want a bookmark?)
   $ hg tag $S
+  $ hg book -f $S
   $ hg branch $M
   marked working directory as branch MIDDLE_
   (branches are permanent and global, did you want a bookmark?)
   $ hg tag $M
+  $ hg book -f $M
   $ hg branch $L
   marked working directory as branch \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
   (branches are permanent and global, did you want a bookmark?)
   $ hg tag $L
+  $ hg book -f $L
 
 check alignment of branches
 
-  $ hg tags
-  tip                                5:d745ff46155b
-  \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d                       4:9259be597f19 (esc)
-  MIDDLE_                            3:b06c5b6def9e
-  \xe7\x9f\xad\xe5\x90\x8d                               2:64a70663cee8 (esc)
+  $ hg branches
+  \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d                   5:d745ff46155b (esc)
+  MIDDLE_                        4:9259be597f19 (inactive)
+  \xe7\x9f\xad\xe5\x90\x8d                           3:b06c5b6def9e (inactive) (esc)
+  default                        2:64a70663cee8 (inactive)
 
 check alignment of tags
 
@@ -141,4 +144,9 @@
   MIDDLE_                            3:b06c5b6def9e
   \xe7\x9f\xad\xe5\x90\x8d                               2:64a70663cee8 (esc)
 
-  $ cd ..
+check alignment of bookmarks
+
+  $ hg book
+     MIDDLE_                   5:d745ff46155b
+     \xe7\x9f\xad\xe5\x90\x8d                      4:9259be597f19 (esc)
+   * \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d              5:d745ff46155b (esc)
--- a/tests/test-subrepo-git.t	Sat Mar 08 19:02:39 2014 +1100
+++ b/tests/test-subrepo-git.t	Tue May 27 17:41:20 2014 -0700
@@ -566,3 +566,105 @@
 #endif
 
   $ cd ..
+
+Test sanitizing ".hg/hgrc" in subrepo
+
+  $ cd t
+  $ hg tip -q
+  7:af6d2edbb0d3
+  $ hg update -q -C af6d2edbb0d3
+  $ cd s
+  $ git checkout -q -b sanitize-test
+  $ mkdir .hg
+  $ echo '.hg/hgrc in git repo' > .hg/hgrc
+  $ mkdir -p sub/.hg
+  $ echo 'sub/.hg/hgrc in git repo' > sub/.hg/hgrc
+  $ git add .hg sub
+  $ git commit -qm 'add .hg/hgrc to be sanitized at hg update'
+  $ git push -q origin sanitize-test
+  $ cd ..
+  $ grep ' s$' .hgsubstate
+  32a343883b74769118bb1d3b4b1fbf9156f4dddc s
+  $ hg commit -qm 'commit with git revision including .hg/hgrc'
+  $ hg parents -q
+  8:3473d20bddcf
+  $ grep ' s$' .hgsubstate
+  c4069473b459cf27fd4d7c2f50c4346b4e936599 s
+  $ cd ..
+
+  $ hg -R tc pull -q
+  $ hg -R tc update -q -C 3473d20bddcf 2>&1 | sort
+  warning: removing potentially hostile 'hgrc' in '$TESTTMP/tc/s/.hg' (glob)
+  warning: removing potentially hostile 'hgrc' in '$TESTTMP/tc/s/sub/.hg' (glob)
+  $ cd tc
+  $ hg parents -q
+  8:3473d20bddcf
+  $ grep ' s$' .hgsubstate
+  c4069473b459cf27fd4d7c2f50c4346b4e936599 s
+  $ cat s/.hg/hgrc
+  cat: s/.hg/hgrc: No such file or directory
+  [1]
+  $ cat s/sub/.hg/hgrc
+  cat: s/sub/.hg/hgrc: No such file or directory
+  [1]
+  $ cd ..
+
+additional test for "git merge --ff" route:
+
+  $ cd t
+  $ hg tip -q
+  8:3473d20bddcf
+  $ hg update -q -C af6d2edbb0d3
+  $ cd s
+  $ git checkout -q testing
+  $ mkdir .hg
+  $ echo '.hg/hgrc in git repo' > .hg/hgrc
+  $ mkdir -p sub/.hg
+  $ echo 'sub/.hg/hgrc in git repo' > sub/.hg/hgrc
+  $ git add .hg sub
+  $ git commit -qm 'add .hg/hgrc to be sanitized at hg update (git merge --ff)'
+  $ git push -q origin testing
+  $ cd ..
+  $ grep ' s$' .hgsubstate
+  32a343883b74769118bb1d3b4b1fbf9156f4dddc s
+  $ hg commit -qm 'commit with git revision including .hg/hgrc'
+  $ hg parents -q
+  9:ed23f7fe024e
+  $ grep ' s$' .hgsubstate
+  f262643c1077219fbd3858d54e78ef050ef84fbf s
+  $ cd ..
+
+  $ cd tc
+  $ hg update -q -C af6d2edbb0d3
+  $ cat s/.hg/hgrc
+  cat: s/.hg/hgrc: No such file or directory
+  [1]
+  $ cat s/sub/.hg/hgrc
+  cat: s/sub/.hg/hgrc: No such file or directory
+  [1]
+  $ cd ..
+  $ hg -R tc pull -q
+  $ hg -R tc update -q -C ed23f7fe024e 2>&1 | sort
+  warning: removing potentially hostile 'hgrc' in '$TESTTMP/tc/s/.hg' (glob)
+  warning: removing potentially hostile 'hgrc' in '$TESTTMP/tc/s/sub/.hg' (glob)
+  $ cd tc
+  $ hg parents -q
+  9:ed23f7fe024e
+  $ grep ' s$' .hgsubstate
+  f262643c1077219fbd3858d54e78ef050ef84fbf s
+  $ cat s/.hg/hgrc
+  cat: s/.hg/hgrc: No such file or directory
+  [1]
+  $ cat s/sub/.hg/hgrc
+  cat: s/sub/.hg/hgrc: No such file or directory
+  [1]
+
+Test that sanitizing is omitted in meta data area:
+
+  $ mkdir s/.git/.hg
+  $ echo '.hg/hgrc in git metadata area' > s/.git/.hg/hgrc
+  $ hg update -q -C af6d2edbb0d3
+  checking out detached HEAD in subrepo s
+  check out a git branch if you intend to make changes
+
+  $ cd ..
--- a/tests/test-subrepo-svn.t	Sat Mar 08 19:02:39 2014 +1100
+++ b/tests/test-subrepo-svn.t	Tue May 27 17:41:20 2014 -0700
@@ -635,3 +635,54 @@
   Checked out revision 15.
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd ..
+
+Test sanitizing ".hg/hgrc" in subrepo
+
+  $ cd sub/t
+  $ hg update -q -C tip
+  $ cd s
+  $ mkdir .hg
+  $ echo '.hg/hgrc in svn repo' > .hg/hgrc
+  $ mkdir -p sub/.hg
+  $ echo 'sub/.hg/hgrc in svn repo' > sub/.hg/hgrc
+  $ svn add .hg sub
+  A         .hg
+  A         .hg/hgrc (glob)
+  A         sub
+  A         sub/.hg (glob)
+  A         sub/.hg/hgrc (glob)
+  $ svn ci -m 'add .hg/hgrc to be sanitized at hg update'
+  Adding         .hg
+  Adding         .hg/hgrc (glob)
+  Adding         sub
+  Adding         sub/.hg (glob)
+  Adding         sub/.hg/hgrc (glob)
+  Transmitting file data ..
+  Committed revision 16.
+  $ svn up -q
+  $ cd ..
+  $ hg commit -S -m 'commit with svn revision including .hg/hgrc'
+  $ grep ' s$' .hgsubstate
+  16 s
+  $ cd ..
+
+  $ hg -R tc pull -u -q 2>&1 | sort
+  warning: removing potentially hostile 'hgrc' in '$TESTTMP/sub/tc/s/.hg' (glob)
+  warning: removing potentially hostile 'hgrc' in '$TESTTMP/sub/tc/s/sub/.hg' (glob)
+  $ cd tc
+  $ grep ' s$' .hgsubstate
+  16 s
+  $ cat s/.hg/hgrc
+  cat: s/.hg/hgrc: No such file or directory
+  [1]
+  $ cat s/sub/.hg/hgrc
+  cat: s/sub/.hg/hgrc: No such file or directory
+  [1]
+
+Test that sanitizing is omitted in meta data area:
+
+  $ mkdir s/.svn/.hg
+  $ echo '.hg/hgrc in svn metadata area' > s/.svn/.hg/hgrc
+  $ hg update -q -C '.^1'
+
+  $ cd ../..