# HG changeset patch # User Matt Mackall # Date 1401237680 25200 # Node ID 652e07debf10193f4973a48ead96a95e81d0a55b # Parent 32601b0b74c0bb0ad294c100f0675745c048453d# Parent 4dca1a06e7ee6c7569d9c3f0b5885a4f068e52bc merge with stable diff -r 32601b0b74c0 -r 652e07debf10 mercurial/commands.py --- 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', diff -r 32601b0b74c0 -r 652e07debf10 mercurial/dispatch.py --- 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 diff -r 32601b0b74c0 -r 652e07debf10 mercurial/pathutil.py --- 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 diff -r 32601b0b74c0 -r 652e07debf10 mercurial/subrepo.py --- 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: diff -r 32601b0b74c0 -r 652e07debf10 tests/test-alias.t --- 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 diff -r 32601b0b74c0 -r 652e07debf10 tests/test-bundle2.t diff -r 32601b0b74c0 -r 652e07debf10 tests/test-doctest.py --- 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') diff -r 32601b0b74c0 -r 652e07debf10 tests/test-encoding-align.t --- 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) diff -r 32601b0b74c0 -r 652e07debf10 tests/test-subrepo-git.t --- 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 .. diff -r 32601b0b74c0 -r 652e07debf10 tests/test-subrepo-svn.t --- 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 ../..