mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 23:38:50 +03:00
fix rename --after
This commit is contained in:
parent
c6b2943998
commit
1ad6c4c7e4
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user