--- 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 ../..