fix rename --after

This commit is contained in:
Robin Farine 2005-12-01 10:48:35 -06:00
parent c6b2943998
commit 1ad6c4c7e4
3 changed files with 203 additions and 27 deletions

View File

@ -821,16 +821,18 @@ def docopy(ui, repo, pats, opts):
ui.warn(_('%s: not overwriting - %s collides with %s\n') %
(reltarget, abssrc, prevsrc))
return
elif os.path.exists(reltarget):
if opts['force']:
os.unlink(reltarget)
else:
if (not opts['after'] and os.path.exists(reltarget) or
opts['after'] and repo.dirstate.state(abstarget) not in '?r'):
if not opts['force']:
ui.warn(_('%s: not overwriting - file exists\n') %
reltarget)
return
if ui.verbose or not exact:
ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
if not opts['after']:
if not opts['after']:
os.unlink(reltarget)
if opts['after']:
if not os.path.exists(reltarget):
return
else:
targetdir = os.path.dirname(reltarget) or '.'
if not os.path.isdir(targetdir):
os.makedirs(targetdir)
@ -847,10 +849,64 @@ def docopy(ui, repo, pats, opts):
(relsrc, inst.strerror))
errors += 1
return
if ui.verbose or not exact:
ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
targets[abstarget] = abssrc
repo.copy(abssrc, abstarget)
copied.append((abssrc, relsrc, exact))
def targetpathfn(pat, dest, srcs):
if os.path.isdir(pat):
if pat.endswith(os.sep):
pat = pat[:-len(os.sep)]
if destdirexists:
striplen = len(os.path.split(pat)[0])
else:
striplen = len(pat)
if striplen:
striplen += len(os.sep)
res = lambda p: os.path.join(dest, p[striplen:])
elif destdirexists:
res = lambda p: os.path.join(dest, os.path.basename(p))
else:
res = lambda p: dest
return res
def targetpathafterfn(pat, dest, srcs):
if util.patkind(pat, None)[0]:
# a mercurial pattern
res = lambda p: os.path.join(dest, os.path.basename(p))
elif len(util.canonpath(repo.root, cwd, pat)) < len(srcs[0][0]):
# A directory. Either the target path contains the last
# component of the source path or it does not.
def evalpath(striplen):
score = 0
for s in srcs:
t = os.path.join(dest, s[1][striplen:])
if os.path.exists(t):
score += 1
return score
if pat.endswith(os.sep):
pat = pat[:-len(os.sep)]
striplen = len(pat) + len(os.sep)
if os.path.isdir(os.path.join(dest, os.path.split(pat)[1])):
score = evalpath(striplen)
striplen1 = len(os.path.split(pat)[0])
if striplen1:
striplen1 += len(os.sep)
if evalpath(striplen1) > score:
striplen = striplen1
res = lambda p: os.path.join(dest, p[striplen:])
else:
# a file
if destdirexists:
res = lambda p: os.path.join(dest, os.path.basename(p))
else:
res = lambda p: dest
return res
pats = list(pats)
if not pats:
raise util.Abort(_('no source or destination specified'))
@ -858,31 +914,31 @@ def docopy(ui, repo, pats, opts):
raise util.Abort(_('no destination specified'))
dest = pats.pop()
destdirexists = os.path.isdir(dest)
if (len(pats) > 1 or not os.path.exists(pats[0])) and not destdirexists:
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 opts['after']:
tfn = targetpathafterfn
else:
tfn = targetpathfn
copylist = []
for pat in pats:
if os.path.isdir(pat):
if destdirexists:
striplen = len(os.path.split(pat)[0])
else:
striplen = len(pat)
if striplen:
striplen += len(os.sep)
targetpath = lambda p: os.path.join(dest, p[striplen:])
elif destdirexists:
targetpath = lambda p: os.path.join(dest, os.path.basename(p))
else:
targetpath = lambda p: dest
srcs = []
for tag, abssrc, relsrc, exact in walk(repo, [pat], opts):
if okaytocopy(abssrc, relsrc, exact):
copy(abssrc, relsrc, targetpath(abssrc), exact)
srcs.append((abssrc, relsrc, exact))
if not srcs:
continue
copylist.append((tfn(pat, dest, srcs), srcs))
if not copylist:
raise util.Abort(_('no files to copy'))
for targetpath, srcs in copylist:
for abssrc, relsrc, exact in srcs:
copy(abssrc, relsrc, targetpath(relsrc), exact)
if errors:
ui.warn(_('(consider using --after)\n'))
if len(copied) == 0:
raise util.Abort(_('no files to copy'))
return errors, copied
def copy(ui, repo, *pats, **opts):

View File

@ -15,18 +15,56 @@ hg rename d1/d11/a1 d2/c
hg status
hg update -C
echo "# rename --after a single file"
mv d1/d11/a1 d2/c
hg rename --after d1/d11/a1 d2/c
hg status
hg update -C
echo "# move a single file to an existing directory"
hg rename d1/d11/a1 d2
hg status
hg update -C
echo "# move --after a single file to an existing directory"
mv d1/d11/a1 d2
hg rename --after d1/d11/a1 d2
hg status
hg update -C
echo "# rename a file using a relative path"
(cd d1/d11; hg rename ../../d2/b e)
hg status
hg update -C
echo "# rename --after a file using a relative path"
(cd d1/d11; mv ../../d2/b e; hg rename --after ../../d2/b e)
hg status
hg update -C
echo "# rename directory d1 as d3"
hg rename d1 d3
hg rename d1/ d3
hg status
hg update -C
echo "# rename --after directory d1 as d3"
mv d1 d3
hg rename --after d1 d3
hg status
hg update -C
echo "# move a directory using a relative path"
(cd d2; mkdir d3; hg rename ../d1/d11 d3)
hg status
hg update -C
echo "# move --after a directory using a relative path"
(cd d2; mkdir d3; mv ../d1/d11 d3; hg rename --after ../d1/d11 d3)
hg status
hg update -C
echo "# move directory d1/d11 to an existing directory d2 (removes empty d1)"
hg rename d1/d11 d2
hg rename d1/d11/ d2
hg status
hg update -C
@ -36,6 +74,13 @@ hg rename d1 d2 d3
hg status
hg update -C
echo "# move --after directories d1 and d2 to a new directory d3"
mkdir d3
mv d1 d2 d3
hg rename --after d1 d2 d3
hg status
hg update -C
echo "# move everything under directory d1 to existing directory d2, do not"
echo "# overwrite existing files (d2/b)"
hg rename d1/* d2
@ -53,6 +98,13 @@ hg rename 'glob:d1/**' d2/d21
hg status
hg update -C
echo "# move --after some files under d1 to d2/d21 (glob)"
mkdir d2/d21
mv d1/a d1/d11/a1 d2/d21
hg rename --after 'glob:d1/**' d2/d21
hg status
hg update -C
echo "# move every file under d1 starting with an 'a' to d2/d21 (regexp)"
mkdir d2/d21
hg rename 're:d1/([^a][^/]*/)*a.*' d2/d21

View File

@ -1,9 +1,21 @@
# rename a single file
A d2/c
R d1/d11/a1
# rename --after a single file
A d2/c
R d1/d11/a1
# move a single file to an existing directory
A d2/a1
R d1/d11/a1
# move --after a single file to an existing directory
A d2/a1
R d1/d11/a1
# rename a file using a relative path
A d1/d11/e
R d2/b
# rename --after a file using a relative path
A d1/d11/e
R d2/b
# rename directory d1 as d3
copying d1/a to d3/a
copying d1/b to d3/b
@ -21,6 +33,33 @@ R d1/a
R d1/b
R d1/ba
R d1/d11/a1
# rename --after directory d1 as d3
copying d1/a to d3/a
copying d1/b to d3/b
copying d1/ba to d3/ba
copying d1/d11/a1 to d3/d11/a1
removing d1/a
removing d1/b
removing d1/ba
removing d1/d11/a1
A d3/a
A d3/b
A d3/ba
A d3/d11/a1
R d1/a
R d1/b
R d1/ba
R d1/d11/a1
# move a directory using a relative path
copying ../d1/d11/a1 to d3/d11/a1
removing ../d1/d11/a1
A d2/d3/d11/a1
R d1/d11/a1
# move --after a directory using a relative path
copying ../d1/d11/a1 to d3/d11/a1
removing ../d1/d11/a1
A d2/d3/d11/a1
R d1/d11/a1
# move directory d1/d11 to an existing directory d2 (removes empty d1)
copying d1/d11/a1 to d2/d11/a1
removing d1/d11/a1
@ -47,6 +86,27 @@ R d1/b
R d1/ba
R d1/d11/a1
R d2/b
# move --after directories d1 and d2 to a new directory d3
copying d1/a to d3/d1/a
copying d1/b to d3/d1/b
copying d1/ba to d3/d1/ba
copying d1/d11/a1 to d3/d1/d11/a1
copying d2/b to d3/d2/b
removing d1/a
removing d1/b
removing d1/ba
removing d1/d11/a1
removing d2/b
A d3/d1/a
A d3/d1/b
A d3/d1/ba
A d3/d1/d11/a1
A d3/d2/b
R d1/a
R d1/b
R d1/ba
R d1/d11/a1
R d2/b
# move everything under directory d1 to existing directory d2, do not
# overwrite existing files (d2/b)
d2/b: not overwriting - file exists
@ -82,6 +142,15 @@ R d1/a
R d1/b
R d1/ba
R d1/d11/a1
# move --after some files under d1 to d2/d21 (glob)
copying d1/a to d2/d21/a
copying d1/d11/a1 to d2/d21/a1
removing d1/a
removing d1/d11/a1
A d2/d21/a
A d2/d21/a1
R d1/a
R d1/d11/a1
# move every file under d1 starting with an 'a' to d2/d21 (regexp)
copying d1/a to d2/d21/a
copying d1/d11/a1 to d2/d21/a1
@ -93,7 +162,6 @@ R d1/a
R d1/d11/a1
# attempt to overwrite an existing file
d1/ca: not overwriting - file exists
abort: no files to copy
? d1/ca
# forced overwrite of an existing file
A d1/ca