copy: if destination ends with "/", make sure it's a directory
Fixes issue724.
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -623,9 +623,12 @@ def docopy(ui, repo, pats, opts, wlock):
raise util.Abort(_('no destination specified'))
dest = pats.pop()
destdirexists = os.path.isdir(dest)
- if (len(pats) > 1 or util.patkind(pats[0], None)[0]) and not destdirexists:
- raise util.Abort(_('with multiple sources, destination must be an '
- 'existing directory'))
+ if not destdirexists:
+ if len(pats) > 1 or util.patkind(pats[0], None)[0]:
+ raise util.Abort(_('with multiple sources, destination must be an '
+ 'existing directory'))
+ if dest.endswith(os.sep) or os.altsep and dest.endswith(os.altsep):
+ raise util.Abort(_('destination %s is not a directory') % dest)
if opts['after']:
tfn = targetpathafterfn
else:
--- a/tests/test-rename
+++ b/tests/test-rename
@@ -88,6 +88,11 @@ hg status -C
diff d1/b d2/b
hg update -C
+echo "# attempt to move one file into a non-existent directory"
+hg rename d1/a dx/
+hg status -C
+hg update -C
+
echo "# attempt to move potentially more than one file into a non-existent"
echo "# directory"
hg rename 'glob:d1/**' dx
--- a/tests/test-rename.out
+++ b/tests/test-rename.out
@@ -166,6 +166,9 @@ 1c1
---
> d2/b
3 files updated, 0 files merged, 3 files removed, 0 files unresolved
+# attempt to move one file into a non-existent directory
+abort: destination dx/ is not a directory
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
# attempt to move potentially more than one file into a non-existent
# directory
abort: with multiple sources, destination must be an existing directory