changeset 4582:7de7a80e7422

merge with main
author Thomas Arendsen Hein <thomas@intevation.de>
date Thu, 14 Jun 2007 11:33:32 +0200
parents 4500fbe3a432 (diff) 3daed3680554 (current diff)
children 11cf78983961 0d26e3d0eeeb
files mercurial/extensions.py mercurial/localrepo.py
diffstat 14 files changed, 191 insertions(+), 155 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -438,11 +438,14 @@ class queue:
     def apply(self, repo, series, list=False, update_status=True,
               strict=False, patchdir=None, merge=None, wlock=None,
               all_files={}):
+        if not wlock:
+            wlock = repo.wlock()
+        lock = repo.lock()
         tr = repo.transaction()
         try:
             ret = self._apply(tr, repo, series, list, update_status,
                               strict, patchdir, merge, wlock,
-                              all_files=all_files)
+                              lock=lock, all_files=all_files)
             tr.close()
             self.save_dirty()
             return ret
@@ -456,14 +459,11 @@ class queue:
 
     def _apply(self, tr, repo, series, list=False, update_status=True,
                strict=False, patchdir=None, merge=None, wlock=None,
-               all_files={}):
+               lock=None, all_files={}):
         # TODO unify with commands.py
         if not patchdir:
             patchdir = self.path
         err = 0
-        if not wlock:
-            wlock = repo.wlock()
-        lock = repo.lock()
         n = None
         for patchname in series:
             pushable, reason = self.pushable(patchname)
@@ -1057,9 +1057,11 @@ class queue:
             aaa = aa[:]
             if opts.get('short'):
                 filelist = mm + aa + dd
+                match = dict.fromkeys(filelist).__contains__
             else:
                 filelist = None
-            m, a, r, d, u = repo.status(files=filelist)[:5]
+                match = util.always
+            m, a, r, d, u = repo.status(files=filelist, match=match)[:5]
 
             # we might end up with files that were added between tip and
             # the dirstate parent, but then changed in the local dirstate.
--- a/hgext/patchbomb.py
+++ b/hgext/patchbomb.py
@@ -223,13 +223,15 @@ def patchbomb(ui, repo, *revs, **opts):
                 pass
             os.rmdir(tmpdir)
 
-    if not opts['test']:
+    really_sending = not (opts['test'] or opts['mbox'])
+
+    if really_sending:
         mail.validateconfig(ui)
 
     if not (revs or opts.get('rev') or opts.get('outgoing')):
         raise util.Abort(_('specify at least one changeset with -r or -o'))
 
-    commands.setremoteconfig(ui, opts)
+    cmdutil.setremoteconfig(ui, opts)
     if opts.get('outgoing') and opts.get('bundle'):
         raise util.Abort(_("--outgoing mode always on with --bundle; do not re-specify --outgoing"))
 
@@ -250,7 +252,10 @@ def patchbomb(ui, repo, *revs, **opts):
         opts['revs'] = revs
 
     # start
-    start_time = util.makedate()
+    if opts.get('date'):
+        start_time = util.parsedate(opts['date'])
+    else:
+        start_time = util.makedate()
 
     def genmsgid(id):
         return '<%s.%s@%s>' % (id[:20], int(start_time[0]), socket.getfqdn())
@@ -351,7 +356,7 @@ def patchbomb(ui, repo, *revs, **opts):
 
     ui.write('\n')
 
-    if not opts['test'] and not opts['mbox']:
+    if really_sending:
         mailer = mail.connect(ui)
     parent = None
 
@@ -405,6 +410,7 @@ cmdtable = {
       ('', 'bcc', [], 'email addresses of blind copy recipients'),
       ('c', 'cc', [], 'email addresses of copy recipients'),
       ('d', 'diffstat', None, 'add diffstat output to messages'),
+      ('', 'date', '', _('use the given date as the sending date')),
       ('g', 'git', None, _('use git extended diff format')),
       ('f', 'from', '', 'email address of sender'),
       ('', 'plain', None, 'omit hg patch header'),
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -7,9 +7,9 @@
 
 from node import *
 from i18n import _
-import os, sys, mdiff, bdiff, util, templater, patch, commands
-import atexit, signal, pdb, hg, lock, fancyopts, traceback
-import socket, revlog, version, extensions, errno
+import os, sys, atexit, signal, pdb, traceback, socket, errno, shlex
+import mdiff, bdiff, util, templater, patch, commands, hg, lock
+import fancyopts, revlog, version, extensions
 
 revrangesep = ':'
 
@@ -574,9 +574,7 @@ def addremove(repo, pats=[], opts={}, wl
             mapping[abs] = rel, exact
             if repo.ui.verbose or not exact:
                 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
-        islink = os.path.islink(target)
-        if (repo.dirstate.state(abs) != 'r' and not islink
-            and not os.path.exists(target)):
+        if repo.dirstate.state(abs) != 'r' and not util.lexists(target):
             remove.append(abs)
             mapping[abs] = rel, exact
             if repo.ui.verbose or not exact:
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -404,8 +404,6 @@ def commit(ui, repo, *pats, **opts):
                 continue
             if f not in files:
                 rf = repo.wjoin(f)
-                if f in unknown:
-                    raise util.Abort(_("file %s not tracked!") % rf)
                 try:
                     mode = os.lstat(rf)[stat.ST_MODE]
                 except OSError:
@@ -419,9 +417,11 @@ def commit(ui, repo, *pats, **opts):
                     if i >= len(slist) or not slist[i].startswith(name):
                         raise util.Abort(_("no match under directory %s!")
                                          % rf)
-                elif not stat.S_ISREG(mode):
+                elif not (stat.S_ISREG(mode) or stat.S_ISLNK(mode)):
                     raise util.Abort(_("can't commit %s: "
                                        "unsupported file type!") % rf)
+                elif repo.dirstate.state(f) == '?':
+                    raise util.Abort(_("file %s not tracked!") % rf)
     else:
         files = []
     try:
@@ -2099,7 +2099,7 @@ def remove(ui, repo, *pats, **opts):
                 forget.append(abs)
                 continue
             reason = _('has been marked for add (use -f to force removal)')
-        elif abs in unknown:
+        elif repo.dirstate.state(abs) == '?':
             reason = _('is not managed')
         elif opts['after'] and not exact and abs not in deleted:
             continue
@@ -2261,8 +2261,7 @@ def revert(ui, repo, *pats, **opts):
         def handle(xlist, dobackup):
             xlist[0].append(abs)
             update[abs] = 1
-            if (dobackup and not opts['no_backup'] and
-                (os.path.islink(target) or os.path.exists(target))):
+            if dobackup and not opts['no_backup'] and util.lexists(target):
                 bakname = "%s.orig" % rel
                 ui.note(_('saving current version of %s as %s\n') %
                         (rel, bakname))
@@ -2997,11 +2996,13 @@ norepo = ("clone init version help debug
           " debugindex debugindexdot debugdate debuginstall")
 optionalrepo = ("paths serve showconfig")
 
-def run():
+def dispatch(args):
     try:
-        u = ui.ui(traceback='--traceback' in sys.argv[1:])
+        u = ui.ui(traceback='--traceback' in args)
     except util.Abort, inst:
         sys.stderr.write(_("abort: %s\n") % inst)
         return -1
-    sys.exit(cmdutil.runcatch(u, sys.argv[1:]))
-
+    return cmdutil.runcatch(u, args)
+
+def run():
+    sys.exit(dispatch(sys.argv[1:]))
--- a/mercurial/extensions.py
+++ b/mercurial/extensions.py
@@ -5,7 +5,8 @@
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.
 
-import imp, commands, hg, util, sys
+import imp, os
+import commands, hg, util, sys
 from i18n import _
 
 _extensions = {}
@@ -28,7 +29,13 @@ def load(ui, name, path):
         # choose an unique name so that it doesn't
         # conflicts with other modules
         module_name = "hgext_%s" % name.replace('.', '_')
-        mod = imp.load_source(module_name, path)
+        if os.path.isdir(path):
+            # module/__init__.py style
+            d, f = os.path.split(path)
+            fd, fpath, desc = imp.find_module(f, [d])
+            mod = imp.load_module(module_name, fd, fpath, desc)
+        else:
+            mod = imp.load_source(module_name, path)
     else:
         def importh(name):
             mod = __import__(name)
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -960,7 +960,8 @@ class localrepository(repo.repository):
                         if fcmp(f, getnode):
                             modified.append(f)
                         else:
-                            clean.append(f)
+                            if list_clean:
+                                clean.append(f)
                             if not wlock and not mywlock:
                                 mywlock = True
                                 try:
@@ -1022,16 +1023,17 @@ class localrepository(repo.repository):
             wlock = self.wlock()
         for f in list:
             p = self.wjoin(f)
-            islink = os.path.islink(p)
-            size = os.lstat(p).st_size
-            if size > 10000000:
+            try:
+                st = os.lstat(p)
+            except:
+                self.ui.warn(_("%s does not exist!\n") % f)
+                continue
+            if st.st_size > 10000000:
                 self.ui.warn(_("%s: files over 10MB may cause memory and"
                                " performance problems\n"
                                "(use 'hg revert %s' to unadd the file)\n")
                                % (f, f))
-            if not islink and not os.path.exists(p):
-                self.ui.warn(_("%s does not exist!\n") % f)
-            elif not islink and not os.path.isfile(p):
+            if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
                 self.ui.warn(_("%s not added: only files and symlinks "
                                "supported currently\n") % f)
             elif self.dirstate.state(f) in 'an':
new file mode 100755
--- /dev/null
+++ b/tests/test-dispatch
@@ -0,0 +1,15 @@
+#!/bin/sh
+# test command parsing and dispatch
+
+hg init a
+cd a
+echo a > a
+hg ci -Ama -d '0 0'
+
+echo '% [defaults]'
+hg cat a
+cat > $HGRCPATH <<EOF
+[defaults]
+cat = -v
+EOF
+hg cat a
new file mode 100644
--- /dev/null
+++ b/tests/test-dispatch.out
@@ -0,0 +1,4 @@
+adding a
+% [defaults]
+a
+a
--- a/tests/test-extension
+++ b/tests/test-extension
@@ -29,6 +29,10 @@ commands.norepo += ' bar'
 EOF
 abspath=`pwd`/foobar.py
 
+mkdir barfoo
+cp foobar.py barfoo/__init__.py
+barfoopath=`pwd`/barfoo
+
 hg init a
 cd a
 echo foo > file
@@ -43,3 +47,9 @@ cd ..
 hg clone a b
 
 hg bar
+
+echo '% module/__init__.py-style'
+echo '[extensions]' > $HGRCPATH
+echo "barfoo = $barfoopath" >> $HGRCPATH
+cd a
+hg foo
--- a/tests/test-extension.out
+++ b/tests/test-extension.out
@@ -13,3 +13,9 @@ 1 files updated, 0 files merged, 0 files
 uisetup called
 ui.parentui is None
 Bar
+% module/__init__.py-style
+uisetup called
+ui.parentui is None
+reposetup called for a
+ui == repo.ui
+Foo
--- a/tests/test-patchbomb
+++ b/tests/test-patchbomb
@@ -14,4 +14,7 @@ echo b > b
 hg commit -Amb -d '2 0'
 
 hg email --date '1970-1-1 0:2' -n -f quux -t foo -c bar -s test 0:tip | \
-  sed -e 's/\(Message-Id:.*@\|In-Reply-To:.*@\).*/\1/'
+  sed -e 's/\(Message-Id:.*@\).*/\1/' | \
+  sed -e 's/\(In-Reply-To:.*@\).*/\1/'
+
+hg email -m test.mbox -f quux -t foo -c bar -s test 0:tip
--- a/tests/test-patchbomb.out
+++ b/tests/test-patchbomb.out
@@ -1,134 +1,109 @@
 adding a
-hg email: option --date not recognized
-hg email [OPTION]... [DEST]...
-
-send changesets by email
-
-    By default, diffs are sent in the format generated by hg export,
-    one per message.  The series starts with a "[PATCH 0 of N]"
-    introduction, which describes the series as a whole.
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [PATCH] a
+X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
+Message-Id: <8580ff50825a50c8f716.60@
+Date: Thu, 01 Jan 1970 00:01:00 +0000
+From: quux
+To: foo
+Cc: bar
 
-    Each patch email has a Subject line of "[PATCH M of N] ...", using
-    the first line of the changeset description as the subject text.
-    The message contains two or three body parts.  First, the rest of
-    the changeset description.  Next, (optionally) if the diffstat
-    program is installed, the result of running diffstat on the patch.
-    Finally, the patch itself, as generated by "hg export".
-
-    With --outgoing, emails will be generated for patches not
-    found in the destination repository (or only those which are
-    ancestors of the specified revisions if any are provided)
+# HG changeset patch
+# User test
+# Date 1 0
+# Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
+# Parent  0000000000000000000000000000000000000000
+a
 
-    With --bundle, changesets are selected as for --outgoing,
-    but a single email containing a binary Mercurial bundle as an
-    attachment will be sent.
-
-    Examples:
-
-    hg email -r 3000          # send patch 3000 only
-    hg email -r 3000 -r 3001  # send patches 3000 and 3001
-    hg email -r 3000:3005     # send patches 3000 through 3005
-    hg email 3000             # send patch 3000 (deprecated)
+diff -r 000000000000 -r 8580ff50825a a
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/a	Thu Jan 01 00:00:01 1970 +0000
+@@ -0,0 +1,1 @@
++a
 
-    hg email -o               # send all patches not in default
-    hg email -o DEST          # send all patches not in DEST
-    hg email -o -r 3000       # send all ancestors of 3000 not in default
-    hg email -o -r 3000 DEST  # send all ancestors of 3000 not in DEST
+This patch series consists of 1 patches.
 
-    hg email -b               # send bundle of all patches not in default
-    hg email -b DEST          # send bundle of all patches not in DEST
-    hg email -b -r 3000       # bundle of all ancestors of 3000 not in default
-    hg email -b -r 3000 DEST  # bundle of all ancestors of 3000 not in DEST
-
-    Before using this command, you will need to enable email in your hgrc.
-    See the [email] section in hgrc(5) for details.
-
-options:
 
- -a --attach     send patches as inline attachments
-    --bcc        email addresses of blind copy recipients
- -c --cc         email addresses of copy recipients
- -d --diffstat   add diffstat output to messages
- -g --git        use git extended diff format
- -f --from       email address of sender
-    --plain      omit hg patch header
- -n --test       print messages that would be sent
- -m --mbox       write messages to mbox file instead of sending them
- -o --outgoing   send changes not found in the target repository
- -b --bundle     send changes not in target as a binary bundle
- -r --rev        a revision to send
- -s --subject    subject of first message (intro or single patch)
- -t --to         email addresses of recipients
-    --force      run even when remote repository is unrelated (with -b)
-    --base       a base changeset to specify instead of a destination (with -b)
- -e --ssh        specify ssh command to use
-    --remotecmd  specify hg command to run on the remote side
+Displaying [PATCH] a ...
+adding b
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [PATCH 0 of 2] test
+Message-Id: <patchbomb.120@
+Date: Thu, 01 Jan 1970 00:02:00 +0000
+From: quux
+To: foo
+Cc: bar
+
+
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [PATCH 1 of 2] a
+X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
+Message-Id: <8580ff50825a50c8f716.121@
+In-Reply-To: <patchbomb.120@
+Date: Thu, 01 Jan 1970 00:02:01 +0000
+From: quux
+To: foo
+Cc: bar
 
-use "hg -v help email" to show global options
-adding b
-hg email: option --date not recognized
-hg email [OPTION]... [DEST]...
-
-send changesets by email
-
-    By default, diffs are sent in the format generated by hg export,
-    one per message.  The series starts with a "[PATCH 0 of N]"
-    introduction, which describes the series as a whole.
+# HG changeset patch
+# User test
+# Date 1 0
+# Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
+# Parent  0000000000000000000000000000000000000000
+a
 
-    Each patch email has a Subject line of "[PATCH M of N] ...", using
-    the first line of the changeset description as the subject text.
-    The message contains two or three body parts.  First, the rest of
-    the changeset description.  Next, (optionally) if the diffstat
-    program is installed, the result of running diffstat on the patch.
-    Finally, the patch itself, as generated by "hg export".
-
-    With --outgoing, emails will be generated for patches not
-    found in the destination repository (or only those which are
-    ancestors of the specified revisions if any are provided)
+diff -r 000000000000 -r 8580ff50825a a
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/a	Thu Jan 01 00:00:01 1970 +0000
+@@ -0,0 +1,1 @@
++a
 
-    With --bundle, changesets are selected as for --outgoing,
-    but a single email containing a binary Mercurial bundle as an
-    attachment will be sent.
-
-    Examples:
-
-    hg email -r 3000          # send patch 3000 only
-    hg email -r 3000 -r 3001  # send patches 3000 and 3001
-    hg email -r 3000:3005     # send patches 3000 through 3005
-    hg email 3000             # send patch 3000 (deprecated)
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [PATCH 2 of 2] b
+X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
+Message-Id: <97d72e5f12c7e84f8506.122@
+In-Reply-To: <patchbomb.120@
+Date: Thu, 01 Jan 1970 00:02:02 +0000
+From: quux
+To: foo
+Cc: bar
 
-    hg email -o               # send all patches not in default
-    hg email -o DEST          # send all patches not in DEST
-    hg email -o -r 3000       # send all ancestors of 3000 not in default
-    hg email -o -r 3000 DEST  # send all ancestors of 3000 not in DEST
+# HG changeset patch
+# User test
+# Date 2 0
+# Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
+# Parent  8580ff50825a50c8f716709acdf8de0deddcd6ab
+b
 
-    hg email -b               # send bundle of all patches not in default
-    hg email -b DEST          # send bundle of all patches not in DEST
-    hg email -b -r 3000       # bundle of all ancestors of 3000 not in default
-    hg email -b -r 3000 DEST  # bundle of all ancestors of 3000 not in DEST
+diff -r 8580ff50825a -r 97d72e5f12c7 b
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/b	Thu Jan 01 00:00:02 1970 +0000
+@@ -0,0 +1,1 @@
++b
 
-    Before using this command, you will need to enable email in your hgrc.
-    See the [email] section in hgrc(5) for details.
+This patch series consists of 2 patches.
 
-options:
 
- -a --attach     send patches as inline attachments
-    --bcc        email addresses of blind copy recipients
- -c --cc         email addresses of copy recipients
- -d --diffstat   add diffstat output to messages
- -g --git        use git extended diff format
- -f --from       email address of sender
-    --plain      omit hg patch header
- -n --test       print messages that would be sent
- -m --mbox       write messages to mbox file instead of sending them
- -o --outgoing   send changes not found in the target repository
- -b --bundle     send changes not in target as a binary bundle
- -r --rev        a revision to send
- -s --subject    subject of first message (intro or single patch)
- -t --to         email addresses of recipients
-    --force      run even when remote repository is unrelated (with -b)
-    --base       a base changeset to specify instead of a destination (with -b)
- -e --ssh        specify ssh command to use
-    --remotecmd  specify hg command to run on the remote side
+Write the introductory message for the patch series.
+
+
+Displaying [PATCH 0 of 2] test ...
+Displaying [PATCH 1 of 2] a ...
+Displaying [PATCH 2 of 2] b ...
+This patch series consists of 2 patches.
 
-use "hg -v help email" to show global options
+
+Write the introductory message for the patch series.
+
+
+Writing [PATCH 0 of 2] test ...
+Writing [PATCH 1 of 2] a ...
+Writing [PATCH 2 of 2] b ...
--- a/tests/test-symlink-basic
+++ b/tests/test-symlink-basic
@@ -1,5 +1,10 @@
 #!/bin/sh
 
+cleanpath()
+{
+    sed -e "s:/.*\(/test-symlink-basic/.*\):...\1:"
+}
+
 cat >> readlink.py <<EOF
 import os
 import sys
@@ -11,6 +16,7 @@ EOF
 hg init a
 cd a
 ln -s nothing dangling
+hg commit -m 'commit symlink without adding' -d '0 0' dangling 2>&1 | cleanpath
 hg add dangling
 hg commit -m 'add symlink' -d '0 0'
 
--- a/tests/test-symlink-basic.out
+++ b/tests/test-symlink-basic.out
@@ -1,3 +1,4 @@
+abort: file .../test-symlink-basic/a/dangling not tracked!
 changeset:   0:cabd88b706fc
 tag:         tip
 user:        test