merge with mpm.
--- a/doc/hgrc.5.txt
+++ b/doc/hgrc.5.txt
@@ -306,7 +306,7 @@ http_proxy::
smtp::
Configuration for extensions that need to send email messages.
host;;
- Optional. Host name of mail server. Default: "mail".
+ Host name of mail server, e.g. "mail.example.com".
port;;
Optional. Port to connect to on mail server. Default: 25.
tls;;
--- a/hgext/fetch.py
+++ b/hgext/fetch.py
@@ -24,13 +24,13 @@ def fetch(ui, repo, source='default', **
if modheads == 0:
return 0
if modheads == 1:
- return hg.update(repo, repo.changelog.tip(), wlock=wlock)
+ return hg.clean(repo, repo.changelog.tip(), wlock=wlock)
newheads = repo.heads(parent)
newchildren = [n for n in repo.heads(parent) if n != parent]
newparent = parent
if newchildren:
newparent = newchildren[0]
- hg.update(repo, newparent, wlock=wlock)
+ hg.clean(repo, newparent, wlock=wlock)
newheads = [n for n in repo.heads() if n != newparent]
err = False
if newheads:
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -176,11 +176,11 @@ class queue:
if exactneg:
return False, exactneg[0]
pos = [g for g in patchguards if g[0] == '+']
- nonpos = [g for g in pos if g[1:] not in guards]
+ exactpos = [g for g in pos if g[1:] in guards]
if pos:
- if not nonpos:
- return True, ''
- return False, nonpos
+ if exactpos:
+ return True, exactpos[0]
+ return False, pos
return True, ''
def explain_pushable(self, idx, all_patches=False):
@@ -725,6 +725,8 @@ class queue:
# 2) a unique substring of the patch name was given
# 3) patchname[-+]num to indicate an offset in the series file
def lookup(self, patch, strict=False):
+ patch = patch and str(patch)
+
def partial_name(s):
if s in self.series:
return s
@@ -1739,7 +1741,7 @@ def select(ui, repo, *args, **opts):
this sets "stable" guard. mq will skip foo.patch (because it has
nagative match) but push bar.patch (because it has posative
- match). patch is pushed only if all posative guards match and no
+ match). patch is pushed if any posative guards match and no
nagative guards match.
with no arguments, default is to print current active guards.
@@ -1749,19 +1751,36 @@ def select(ui, repo, *args, **opts):
when no guards active, patches with posative guards are skipped,
patches with nagative guards are pushed.
+ qselect can change guards of applied patches. it does not pop
+ guarded patches by default. use --pop to pop back to last applied
+ patch that is not guarded. use --reapply (implies --pop) to push
+ back to current patch afterwards, but skip guarded patches.
+
use -s/--series to print list of all guards in series file (no
other arguments needed). use -v for more information.'''
q = repo.mq
guards = q.active()
if args or opts['none']:
+ old_unapplied = q.unapplied(repo)
+ old_guarded = [i for i in xrange(len(q.applied)) if
+ not q.pushable(i)[0]]
q.set_active(args)
q.save_dirty()
if not args:
ui.status(_('guards deactivated\n'))
- if q.series:
- ui.status(_('%d of %d unapplied patches active\n') %
- (len(q.unapplied(repo)), len(q.series)))
+ if not opts['pop'] and not opts['reapply']:
+ unapplied = q.unapplied(repo)
+ guarded = [i for i in xrange(len(q.applied))
+ if not q.pushable(i)[0]]
+ if len(unapplied) != len(old_unapplied):
+ ui.status(_('number of unguarded, unapplied patches has '
+ 'changed from %d to %d\n') %
+ (len(old_unapplied), len(unapplied)))
+ if len(guarded) != len(old_guarded):
+ ui.status(_('number of guarded, applied patches has changed '
+ 'from %d to %d\n') %
+ (len(old_guarded), len(guarded)))
elif opts['series']:
guards = {}
noguards = 0
@@ -1789,9 +1808,51 @@ def select(ui, repo, *args, **opts):
ui.write(g, '\n')
else:
ui.write(_('no active guards\n'))
+ reapply = opts['reapply'] and q.applied and q.appliedname(-1)
+ popped = False
+ if opts['pop'] or opts['reapply']:
+ for i in xrange(len(q.applied)):
+ pushable, reason = q.pushable(i)
+ if not pushable:
+ ui.status(_('popping guarded patches\n'))
+ popped = True
+ if i == 0:
+ q.pop(repo, all=True)
+ else:
+ q.pop(repo, i-1)
+ break
+ if popped:
+ try:
+ if reapply:
+ ui.status(_('reapplying unguarded patches\n'))
+ q.push(repo, reapply)
+ finally:
+ q.save_dirty()
def reposetup(ui, repo):
class mqrepo(repo.__class__):
+ def abort_if_wdir_patched(self, errmsg, force=False):
+ if self.mq.applied and not force:
+ parent = revlog.hex(self.dirstate.parents()[0])
+ if parent in [s.rev for s in self.mq.applied]:
+ raise util.Abort(errmsg)
+
+ def commit(self, *args, **opts):
+ if len(args) >= 6:
+ force = args[5]
+ else:
+ force = opts.get('force')
+ self.abort_if_wdir_patched(
+ _('cannot commit over an applied mq patch'),
+ force)
+
+ return super(mqrepo, self).commit(*args, **opts)
+
+ def push(self, remote, force=False, revs=None):
+ if self.mq.applied and not force:
+ raise util.Abort(_('source has mq patches applied'))
+ return super(mqrepo, self).push(remote, force, revs)
+
def tags(self):
if self.tagscache:
return self.tagscache
@@ -1813,8 +1874,9 @@ def reposetup(ui, repo):
return tagscache
- repo.__class__ = mqrepo
- repo.mq = queue(ui, repo.join(""))
+ if repo.local():
+ repo.__class__ = mqrepo
+ repo.mq = queue(ui, repo.join(""))
cmdtable = {
"qapplied": (applied, [], 'hg qapplied [PATCH]'),
@@ -1906,8 +1968,11 @@ cmdtable = {
'hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'),
"qselect": (select,
[('n', 'none', None, _('disable all guards')),
- ('s', 'series', None, _('list all guards in series file'))],
- 'hg qselect [GUARDS]'),
+ ('s', 'series', None, _('list all guards in series file')),
+ ('', 'pop', None,
+ _('pop to before first guarded applied patch')),
+ ('', 'reapply', None, _('pop, then reapply patches'))],
+ 'hg qselect [OPTION...] [GUARD...]'),
"qseries":
(series,
[('m', 'missing', None, 'print patches not in series'),
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3545,6 +3545,7 @@ def dispatch(args):
mod = sys.modules[name]
if hasattr(mod, 'reposetup'):
mod.reposetup(u, repo)
+ hg.repo_setup_hooks.append(mod.reposetup)
except hg.RepoError:
if cmd not in optionalrepo.split():
raise
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -48,9 +48,14 @@ def islocal(repo):
return False
return repo.local()
+repo_setup_hooks = []
+
def repository(ui, path=None, create=False):
"""return a repository object for the specified path"""
- return _lookup(path).instance(ui, path, create)
+ repo = _lookup(path).instance(ui, path, create)
+ for hook in repo_setup_hooks:
+ hook(ui, repo)
+ return repo
def defaultdest(source):
'''return default destination of clone if none is given'''
--- a/tests/test-abort-checkin
+++ b/tests/test-abort-checkin
@@ -3,6 +3,11 @@
HGRCPATH=$HGTMP/.hgrc; export HGRCPATH
echo "[extensions]" >> $HGTMP/.hgrc
echo "mq=" >> $HGTMP/.hgrc
+cat > $HGTMP/false <<EOF
+#!/bin/sh
+exit 1
+EOF
+chmod +x $HGTMP/false
hg init foo
cd foo
@@ -11,7 +16,7 @@ hg add foo
# mq may keep a reference to the repository so __del__ will not be called
# and .hg/journal.dirstate will not be deleted:
-HGEDITOR=false hg ci
-HGEDITOR=false hg ci
+HGEDITOR=$HGTMP/false hg ci
+HGEDITOR=$HGTMP/false hg ci
exit 0
--- a/tests/test-globalopts
+++ b/tests/test-globalopts
@@ -45,7 +45,7 @@ hg --cwd c head -v
hg --cwd b tip --verbose
echo %% --config
-hg --cwd c --config paths.quuxfoo=bar paths | grep -q quuxfoo && echo quuxfoo
+hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo
hg --cwd c --config '' tip -q
hg --cwd c --config a.b tip -q
hg --cwd c --config a tip -q
--- a/tests/test-import
+++ b/tests/test-import
@@ -72,7 +72,7 @@ rm -rf b
echo % plain diff in email, no subject, no message body, should fail
hg clone -r0 a b
-grep -v '^\(Subject\|email\)' msg.patch | hg --cwd b import -
+egrep -v '^(Subject|email)' msg.patch | hg --cwd b import -
rm -rf b
echo % hg export in email, should use patch header
@@ -89,9 +89,10 @@ hg --cwd a ci -u someoneelse -d '1 0' -m
echo % hg import in a subdirectory
hg clone -r0 a b
hg --cwd a export tip | sed -e 's/d1\/d2\///' > tip.patch
-pushd b/d1/d2 2>&1 > /dev/null
+dir=`pwd`
+cd b/d1/d2 2>&1 > /dev/null
hg import ../../../tip.patch
-popd 2>&1 > /dev/null
+cd $dir
echo "% message should be 'subdir change'"
hg --cwd b tip | grep 'subdir change'
echo "% committer should be 'someoneelse'"
--- a/tests/test-mq
+++ b/tests/test-mq
@@ -10,6 +10,10 @@ hg help mq
hg init a
cd a
echo a > a
+hg ci -Ama
+
+hg clone . ../k
+
mkdir b
echo z > b/z
hg ci -Ama
@@ -48,7 +52,7 @@ echo % qrefresh
echo a >> a
hg qrefresh
-sed -e "s/\(^diff -r \)\([a-f0-9]* \)/\1 x/" \
+sed -e "s/^\(diff -r \)\([a-f0-9]* \)/\1 x/" \
-e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
-e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/test.patch
@@ -103,9 +107,19 @@ hg qnext
hg qprev
hg qapplied
+echo % commit should fail
+hg commit
+
+echo % push should fail
+hg push ../../k
+
echo % qunapplied
hg qunapplied
+echo % push should succeed
+hg qpop -a
+hg push ../../k
+
echo % strip
cd ../../b
echo x>x
--- a/tests/test-mq-guards
+++ b/tests/test-mq-guards
@@ -63,22 +63,39 @@ echo % should push all
hg qpush -a
hg qpop -a
-hg qguard a.patch +1 +2
+hg qguard a.patch +1
+hg qguard b.patch +2
hg qselect 1
+echo % should push a.patch, not b.patch
+hg qpush
+hg qpush
+hg qpop -a
+
+hg qselect 2
echo % should push b.patch
hg qpush
hg qpop -a
-hg qselect 2
+hg qselect 1 2
+echo % should push a.patch, b.patch
hg qpush
-hg qpop -a
-
-hg qselect 1 2
-echo % should push a.patch
hg qpush
hg qpop -a
hg qguard a.patch +1 +2 -3
hg qselect 1 2 3
+echo % list patches and guards
+hg qguard -l
+echo % list series
+hg qseries -v
+echo % list guards
+hg qselect
echo % should push b.patch
hg qpush
+
+hg qpush -a
+hg qselect -n --reapply
+echo % guards in series file: +1 +2 -3
+hg qselect -s
+echo % should show c.patch
+hg qapplied
--- a/tests/test-mq-guards.out
+++ b/tests/test-mq-guards.out
@@ -13,7 +13,7 @@ a.patch: +a
applying b.patch
Now at: b.patch
Patch queue now empty
-3 of 3 unapplied patches active
+number of unguarded, unapplied patches has changed from 2 to 3
% should push a.patch
applying a.patch
Now at: a.patch
@@ -28,27 +28,57 @@ applying c.patch
Now at: c.patch
Patch queue now empty
guards deactivated
-2 of 3 unapplied patches active
+number of unguarded, unapplied patches has changed from 3 to 2
% should push all
applying b.patch
applying c.patch
Now at: c.patch
Patch queue now empty
-2 of 3 unapplied patches active
+number of unguarded, unapplied patches has changed from 1 to 2
+% should push a.patch, not b.patch
+applying a.patch
+Now at: a.patch
+applying c.patch
+Now at: c.patch
+Patch queue now empty
% should push b.patch
applying b.patch
Now at: b.patch
Patch queue now empty
-2 of 3 unapplied patches active
+number of unguarded, unapplied patches has changed from 2 to 3
+% should push a.patch, b.patch
+applying a.patch
+Now at: a.patch
applying b.patch
Now at: b.patch
Patch queue now empty
-3 of 3 unapplied patches active
-% should push a.patch
-applying a.patch
-Now at: a.patch
-Patch queue now empty
-2 of 3 unapplied patches active
+number of unguarded, unapplied patches has changed from 3 to 2
+% list patches and guards
+a.patch: +1 +2 -3
+b.patch: +2
+c.patch: unguarded
+% list series
+0 G a.patch
+1 U b.patch
+2 U c.patch
+% list guards
+1
+2
+3
% should push b.patch
applying b.patch
Now at: b.patch
+applying c.patch
+Now at: c.patch
+guards deactivated
+popping guarded patches
+Patch queue now empty
+reapplying unguarded patches
+applying c.patch
+Now at: c.patch
+% guards in series file: +1 +2 -3
++1
++2
+-3
+% should show c.patch
+c.patch
--- a/tests/test-mq-qrefresh-replace-log-message
+++ b/tests/test-mq-qrefresh-replace-log-message
@@ -33,7 +33,7 @@ echo " This is the 3rd log message" >> l
echo bbbb > file
hg qrefresh -l logfile
echo =======================
-echo "Should display 'Third commit message\n This is the 3rd log message'"
+printf "Should display 'Third commit message\\\n This is the 3rd log message'\n"
hg log -l1 -v | sed -n '/description/,$p'
echo
@@ -46,6 +46,6 @@ echo bbbb > file2
echo " This is the 5th log message" >> logfile) |\
hg qrefresh -l-
echo =======================
-echo "Should display 'Fifth commit message\n This is the 5th log message'"
+printf "Should display 'Fifth commit message\\\n This is the 5th log message'\n"
hg log -l1 -v | sed -n '/description/,$p'
echo
--- a/tests/test-mq.out
+++ b/tests/test-mq.out
@@ -49,6 +49,7 @@ list of commands (use "hg help -v mq" to
qunapplied print the patches not yet applied
strip strip a revision and all later revs on the same branch
adding a
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
adding b/z
% qinit
% -R qinit
@@ -102,8 +103,21 @@ Now at: test.patch
test2.patch
Only one patch applied
test.patch
+% commit should fail
+abort: cannot commit over an applied mq patch
+% push should fail
+pushing to ../../k
+abort: source has mq patches applied
% qunapplied
test2.patch
+% push should succeed
+Patch queue now empty
+pushing to ../../k
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
% strip
adding x
0 files updated, 0 files merged, 1 files removed, 0 files unresolved