merge with i18n stable
authorMatt Mackall <mpm@selenic.com>
Sat, 30 Oct 2010 02:47:24 -0500
branchstable
changeset 12885 b5eae8e24e80
parent 12879 da4a9ed369c8 (diff)
parent 12884 f2e2ef5c6a1b (current diff)
child 12886 c25945a148c1
merge with i18n
--- a/hgext/mq.py	Fri Oct 29 00:19:39 2010 +0900
+++ b/hgext/mq.py	Sat Oct 30 02:47:24 2010 -0500
@@ -821,7 +821,11 @@
         diffopts = self.diffopts({'git': opts.get('git')})
         self.check_reserved_name(patchfn)
         if os.path.exists(self.join(patchfn)):
-            raise util.Abort(_('patch "%s" already exists') % patchfn)
+            if os.path.isdir(self.join(patchfn)):
+                raise util.Abort(_('"%s" already exists as a directory')
+                                 % patchfn)
+            else:
+                raise util.Abort(_('patch "%s" already exists') % patchfn)
         if opts.get('include') or opts.get('exclude') or pats:
             match = cmdutil.match(repo, pats, opts)
             # detect missing files in pats
@@ -839,8 +843,12 @@
         insert = self.full_series_end()
         wlock = repo.wlock()
         try:
-            # if patch file write fails, abort early
-            p = self.opener(patchfn, "w")
+            try:
+                # if patch file write fails, abort early
+                p = self.opener(patchfn, "w")
+            except IOError, e:
+                raise util.Abort(_('cannot write patch "%s": %s')
+                                 % (patchfn, e.strerror))
             try:
                 if self.plainmode:
                     if user:
@@ -2400,7 +2408,7 @@
         os.makedirs(destdir)
     util.rename(q.join(patch), absdest)
     r = q.qrepo()
-    if r:
+    if r and patch in r.dirstate:
         wctx = r[None]
         wlock = r.wlock()
         try:
--- a/hgext/pager.py	Fri Oct 29 00:19:39 2010 +0900
+++ b/hgext/pager.py	Sat Oct 30 02:47:24 2010 -0500
@@ -22,12 +22,6 @@
 If no pager is set, the pager extensions uses the environment variable
 $PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.
 
-By default, the pager is only executed if a command has output. To
-force the pager to run even if a command prints nothing, set::
-
-  [pager]
-  force = True
-
 If you notice "BROKEN PIPE" error messages, you can disable them by
 setting::
 
@@ -63,7 +57,7 @@
 from mercurial import commands, dispatch, util, extensions
 from mercurial.i18n import _
 
-def _runpager(p, sigpipe=False):
+def _runpager(p):
     if not hasattr(os, 'fork'):
         sys.stderr = sys.stdout = util.popen(p, 'wb')
         return
@@ -74,8 +68,6 @@
         os.dup2(fdout, sys.stdout.fileno())
         os.dup2(fdout, sys.stderr.fileno())
         os.close(fdout)
-        if sigpipe:
-            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
         return
     os.dup2(fdin, sys.stdin.fileno())
     os.close(fdin)
@@ -94,23 +86,6 @@
     if ui.plain():
         return
 
-    class pagerui(ui.__class__):
-        _pager = None
-        _pagerstarted = False
-
-        def write(self, *args, **opts):
-            if self._pager and not self._pagerstarted:
-                self._pagerstarted = True
-                self._pager()
-            return super(pagerui, self).write(*args, **opts)
-
-        def write_err(self, *args, **opts):
-            if self._pager and not self._pagerstarted:
-                self._pagerstarted = True
-                self._pager()
-            return super(pagerui, self).write(*args, **opts)
-    ui.__class__ = pagerui
-
     def pagecmd(orig, ui, options, cmd, cmdfunc):
         p = ui.config("pager", "pager", os.environ.get("PAGER"))
         if p and sys.stdout.isatty() and '--debugger' not in sys.argv:
@@ -122,11 +97,9 @@
                  (cmd not in ui.configlist('pager', 'ignore') and not attend))):
                 ui.setconfig('ui', 'formatted', ui.formatted())
                 ui.setconfig('ui', 'interactive', False)
-                sigpipe = ui.configbool('pager', 'quiet')
-                if ui.configbool('pager', 'force'):
-                    _runpager(p, sigpipe)
-                else:
-                    ui._pager = lambda: _runpager(p, sigpipe)
+                _runpager(p)
+                if ui.configbool('pager', 'quiet'):
+                    signal.signal(signal.SIGPIPE, signal.SIG_DFL)
         return orig(ui, options, cmd, cmdfunc)
 
     extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
--- a/mercurial/cmdutil.py	Fri Oct 29 00:19:39 2010 +0900
+++ b/mercurial/cmdutil.py	Sat Oct 30 02:47:24 2010 -0500
@@ -348,7 +348,7 @@
 
     wctx = repo[None]
     for src, dst in copies:
-        wctx.copy(src, dst)
+        dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
     if (not similarity) and removes:
         wctx.remove(sorted(removes), True)
 
@@ -367,6 +367,25 @@
     files.extend([r for r in removes if r not in files])
     return sorted(files)
 
+def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
+    """Update the dirstate to reflect the intent of copying src to dst. For
+    different reasons it might not end with dst being marked as copied from src.
+    """
+    origsrc = repo.dirstate.copied(src) or src
+    if dst == origsrc: # copying back a copy?
+        if repo.dirstate[dst] not in 'mn' and not dryrun:
+            repo.dirstate.normallookup(dst)
+    else:
+        if repo.dirstate[origsrc] == 'a' and origsrc == src:
+            if not ui.quiet:
+                ui.warn(_("%s has not been committed yet, so no copy "
+                          "data will be stored for %s.\n")
+                        % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
+            if repo.dirstate[dst] in '?r' and not dryrun:
+                wctx.add([dst])
+        elif not dryrun:
+            wctx.copy(origsrc, dst)
+
 def copy(ui, repo, pats, opts, rename=False):
     # called with the repo lock held
     #
@@ -458,21 +477,7 @@
         targets[abstarget] = abssrc
 
         # fix up dirstate
-        origsrc = repo.dirstate.copied(abssrc) or abssrc
-        if abstarget == origsrc: # copying back a copy?
-            if state not in 'mn' and not dryrun:
-                repo.dirstate.normallookup(abstarget)
-        else:
-            if repo.dirstate[origsrc] == 'a' and origsrc == abssrc:
-                if not ui.quiet:
-                    ui.warn(_("%s has not been committed yet, so no copy "
-                              "data will be stored for %s.\n")
-                            % (repo.pathto(origsrc, cwd), reltarget))
-                if repo.dirstate[abstarget] in '?r' and not dryrun:
-                    wctx.add([abstarget])
-            elif not dryrun:
-                wctx.copy(origsrc, abstarget)
-
+        dirstatecopy(ui, repo, wctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd)
         if rename and not dryrun:
             wctx.remove([abssrc], not after)
 
--- a/mercurial/util.py	Fri Oct 29 00:19:39 2010 +0900
+++ b/mercurial/util.py	Sat Oct 30 02:47:24 2010 -0500
@@ -863,9 +863,11 @@
                 nlink = nlinks(f)
             except OSError:
                 nlink = 0
-                d = os.path.dirname(f)
-                if not os.path.isdir(d):
-                    makedirs(d, self.createmode)
+                dirname, basename = os.path.split(f)
+                # Avoid calling makedirs when the path points to a
+                # directory -- the open will raise IOError below.
+                if basename and not os.path.isdir(dirname):
+                    makedirs(dirname, self.createmode)
             if atomictemp:
                 return atomictempfile(f, mode, self.createmode)
             if nlink > 1:
--- a/tests/test-git-import.t	Fri Oct 29 00:19:39 2010 +0900
+++ b/tests/test-git-import.t	Sat Oct 30 02:47:24 2010 -0500
@@ -361,4 +361,25 @@
   A binary2
     text2
   R text2
+  $ cd ..
 
+Consecutive import with renames (issue2459)
+
+  $ hg init issue2459
+  $ cd issue2459
+  $ hg import --no-commit --force - <<EOF
+  > diff --git a/a b/a
+  > new file mode 100644
+  > EOF
+  applying patch from stdin
+  $ hg import --no-commit --force - <<EOF
+  > diff --git a/a b/b
+  > rename from a
+  > rename to b
+  > EOF
+  applying patch from stdin
+  a has not been committed yet, so no copy data will be stored for b.
+  $ hg debugstate
+  a   0         -1 unset               b
+  $ hg ci -m done
+  $ cd ..
--- a/tests/test-mq-qnew.t	Fri Oct 29 00:19:39 2010 +0900
+++ b/tests/test-mq-qnew.t	Sat Oct 30 02:47:24 2010 -0500
@@ -23,7 +23,9 @@
   >     hg qinit -c
   > 
   >     echo '% qnew with name containing slash'
+  >     hg qnew foo/
   >     hg qnew foo/bar.patch
+  >     hg qnew foo
   >     hg qseries
   >     hg qpop
   >     hg qdelete foo/bar.patch
@@ -105,6 +107,8 @@
   abort: "foo#bar" cannot be used as the name of a patch
   abort: "foo:bar" cannot be used as the name of a patch
   % qnew with name containing slash
+  abort: cannot write patch "foo/": Is a directory
+  abort: "foo" already exists as a directory
   foo/bar.patch
   popping foo/bar.patch
   patch queue now empty
@@ -168,6 +172,8 @@
   abort: "foo#bar" cannot be used as the name of a patch
   abort: "foo:bar" cannot be used as the name of a patch
   % qnew with name containing slash
+  abort: cannot write patch "foo/": Is a directory
+  abort: "foo" already exists as a directory
   foo/bar.patch
   popping foo/bar.patch
   patch queue now empty
--- a/tests/test-mq-qrename.t	Fri Oct 29 00:19:39 2010 +0900
+++ b/tests/test-mq-qrename.t	Sat Oct 30 02:47:24 2010 -0500
@@ -81,3 +81,16 @@
   A patchc
   R patcha
   $ cd ..
+
+Test renames with mq repo (issue2097)
+
+  $ hg init issue2097
+  $ cd issue2097
+  $ hg qnew p0
+  $ (cd .hg/patches && hg init)
+  $ hg qren p0 p1
+  $ hg debugstate --mq
+  $ hg ci --mq -mq0
+  nothing changed
+  [1]
+  $ cd ..