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