convert/svn: handle files/links replaced by dirs (issue2166)

This commit is contained in:
Patrick Mezard 2010-05-09 19:11:02 +02:00
parent c25c428f66
commit 3cefb24597
5 changed files with 365 additions and 16 deletions

View File

@ -645,14 +645,7 @@ class svn_source(converter_source):
self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
pmodule, prevnum = self.revsplit(parents[0])[1:]
parentpath = pmodule + "/" + entrypath
self.ui.debug("entry %s\n" % parentpath)
# We can avoid the reparent calls if the module has
# not changed but it probably does not worth the pain.
prevmodule = self.reparent('')
fromkind = svn.ra.check_path(self.ra, parentpath.strip('/'),
prevnum)
self.reparent(prevmodule)
fromkind = self._checkpath(entrypath, prevnum, pmodule)
if fromkind == svn.core.svn_node_file:
removed.add(self.recode(entrypath))
@ -668,11 +661,18 @@ class svn_source(converter_source):
else:
self.ui.debug('unknown path in revision %d: %s\n' % \
(revnum, path))
elif kind == svn.core.svn_node_dir:
# If the directory just had a prop change,
# then we shouldn't need to look for its children.
elif kind == svn.core.svn_node_dir:
if ent.action == 'M':
# If the directory just had a prop change,
# then we shouldn't need to look for its children.
continue
elif ent.action == 'R' and parents:
# If a directory is replacing a file, mark the previous
# file as deleted
pmodule, prevnum = self.revsplit(parents[0])[1:]
pkind = self._checkpath(entrypath, prevnum, pmodule)
if pkind == svn.core.svn_node_file:
removed.add(self.recode(entrypath))
children = sorted(self._find_children(path, revnum))
for child in children:
@ -898,11 +898,18 @@ class svn_source(converter_source):
self.ui.debug('%r is not under %r, ignoring\n' % (path, module))
return None
def _checkpath(self, path, revnum):
# ra.check_path does not like leading slashes very much, it leads
# to PROPFIND subversion errors
return svn.ra.check_path(self.ra, path.strip('/'), revnum)
def _checkpath(self, path, revnum, module=None):
if module is not None:
prevmodule = self.reparent('')
path = module + '/' + path
try:
# ra.check_path does not like leading slashes very much, it leads
# to PROPFIND subversion errors
return svn.ra.check_path(self.ra, path.strip('/'), revnum)
finally:
if module is not None:
self.reparent(prevmodule)
def _getlog(self, paths, start, end, limit=0, discover_changed_paths=True,
strict_node_history=False):
# Normalize path names, svn >= 1.5 only wants paths relative to

241
tests/svn/replace.svndump Normal file
View File

@ -0,0 +1,241 @@
SVN-fs-dump-format-version: 2
UUID: 4a895937-439c-4e56-b7b0-fa1c8acc0c20
Revision-number: 0
Prop-content-length: 56
Content-length: 56
K 8
svn:date
V 27
2010-05-09T14:57:31.007802Z
PROPS-END
Revision-number: 1
Prop-content-length: 108
Content-length: 108
K 7
svn:log
V 7
initial
K 10
svn:author
V 7
pmezard
K 8
svn:date
V 27
2010-05-09T14:57:32.094732Z
PROPS-END
Node-path: branches
Node-kind: dir
Node-action: add
Prop-content-length: 10
Content-length: 10
PROPS-END
Node-path: trunk
Node-kind: dir
Node-action: add
Prop-content-length: 10
Content-length: 10
PROPS-END
Node-path: trunk/a
Node-kind: file
Node-action: add
Prop-content-length: 10
Text-content-length: 2
Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3
Text-content-sha1: 3f786850e387550fdab836ed7e6dc881de23001b
Content-length: 12
PROPS-END
a
Node-path: trunk/d
Node-kind: dir
Node-action: add
Prop-content-length: 10
Content-length: 10
PROPS-END
Node-path: trunk/d/b
Node-kind: file
Node-action: add
Prop-content-length: 10
Text-content-length: 2
Text-content-md5: 3b5d5c3712955042212316173ccf37be
Text-content-sha1: 89e6c98d92887913cadf06b2adb97f26cde4849b
Content-length: 12
PROPS-END
b
Node-path: trunk/dlink
Node-kind: file
Node-action: add
Prop-content-length: 33
Text-content-length: 6
Text-content-md5: cca56829f18345718a4980bb02b6d8c3
Text-content-sha1: 7c54cc5d472b78c94a04382df34b0f4f0f4f2d49
Content-length: 39
K 11
svn:special
V 1
*
PROPS-END
link d
Node-path: trunk/dlink2
Node-kind: file
Node-action: add
Prop-content-length: 33
Text-content-length: 6
Text-content-md5: cca56829f18345718a4980bb02b6d8c3
Text-content-sha1: 7c54cc5d472b78c94a04382df34b0f4f0f4f2d49
Content-length: 39
K 11
svn:special
V 1
*
PROPS-END
link d
Node-path: trunk/dlink3
Node-kind: file
Node-action: add
Prop-content-length: 33
Text-content-length: 6
Text-content-md5: cca56829f18345718a4980bb02b6d8c3
Text-content-sha1: 7c54cc5d472b78c94a04382df34b0f4f0f4f2d49
Content-length: 39
K 11
svn:special
V 1
*
PROPS-END
link d
Revision-number: 2
Prop-content-length: 117
Content-length: 117
K 7
svn:log
V 15
clobber symlink
K 10
svn:author
V 7
pmezard
K 8
svn:date
V 27
2010-05-09T14:57:33.071117Z
PROPS-END
Node-path: trunk/dlink3
Node-kind: file
Node-action: change
Prop-content-length: 10
Text-content-length: 2
Text-content-md5: e29311f6f1bf1af907f9ef9f44b8328b
Text-content-sha1: e983f374794de9c64e3d1c1de1d490c0756eeeff
Content-length: 12
PROPS-END
d
Revision-number: 3
Prop-content-length: 106
Content-length: 106
K 7
svn:log
V 8
clobber1
K 10
svn:author
V 4
evil
K 8
svn:date
V 27
2010-05-09T14:57:35.268057Z
PROPS-END
Node-path: trunk/a
Node-kind: dir
Node-action: delete
Node-path: trunk/a
Node-kind: dir
Node-action: add
Node-copyfrom-rev: 2
Node-copyfrom-path: trunk/d
Node-path: trunk/dlink
Node-kind: dir
Node-action: delete
Node-path: trunk/dlink
Node-kind: dir
Node-action: add
Node-copyfrom-rev: 2
Node-copyfrom-path: trunk/d
Revision-number: 4
Prop-content-length: 106
Content-length: 106
K 7
svn:log
V 8
clobber2
K 10
svn:author
V 4
evil
K 8
svn:date
V 27
2010-05-09T14:57:35.521816Z
PROPS-END
Node-path: trunk/dlink3
Node-kind: file
Node-action: delete
Node-path: trunk/dlink3
Node-kind: file
Node-action: add
Node-copyfrom-rev: 3
Node-copyfrom-path: trunk/dlink2
Text-copy-source-md5: cca56829f18345718a4980bb02b6d8c3
Text-copy-source-sha1: 7c54cc5d472b78c94a04382df34b0f4f0f4f2d49

55
tests/svn/svndump-replace.sh Executable file
View File

@ -0,0 +1,55 @@
#!/bin/sh
RSVN="`pwd`/rsvn.py"
export PATH=/bin:/usr/bin
mkdir temp
cd temp
svnadmin create repo
svn co file://`pwd`/repo wc
cd wc
mkdir trunk branches
cd trunk
echo a > a
mkdir d
echo b > d/b
ln -s d dlink
ln -s d dlink2
ln -s d dlink3
cd ..
svn add *
svn ci -m 'initial'
# Clobber symlink with file with similar content
cd trunk
ls -Alh
readlink dlink3 > dlink3tmp
rm dlink3
mv dlink3tmp dlink3
svn propdel svn:special dlink3
svn ci -m 'clobber symlink'
cd ..
svn up
# Clobber files and symlink with directories
cd ..
cat > clobber.rsvn <<EOF
rdelete trunk/a
rdelete trunk/dlink
rcopy trunk/d trunk/a
rcopy trunk/d trunk/dlink
EOF
python $RSVN --message=clobber1 --username=evil `pwd`/repo < clobber.rsvn
# Clobber non-symlink with symlink with same content (kudos openwrt)
cat > clobber.rsvn <<EOF
rdelete trunk/dlink3
rcopy trunk/dlink2 trunk/dlink3
EOF
python $RSVN --message=clobber2 --username=evil `pwd`/repo < clobber.rsvn
svn log -v file://`pwd`/repo
svnadmin dump repo > ../replace.svndump

View File

@ -33,3 +33,21 @@ hg st --rev 12:13 --copies
echo '% check branches'
hg branches | sed 's/:.*/:/'
cd ..
mkdir test-replace
cd test-replace
svnadmin create svn-repo
cat "$TESTDIR/svn/replace.svndump" | svnadmin load svn-repo > /dev/null
echo '% convert files being replaced by directories'
hg convert svn-repo hg-repo
cd hg-repo
echo '% manifest before'
hg -v manifest -r 1
echo '% manifest after clobber1'
hg -v manifest -r 2
echo '% manifest after clobber2'
hg -v manifest -r 3
echo '% try updating'
hg up -qC default
cd ..

View File

@ -52,3 +52,31 @@ R d4old/g
% check branches
default 13:
d1 6:
% convert files being replaced by directories
initializing destination hg-repo repository
scanning source...
sorting...
converting...
3 initial
2 clobber symlink
1 clobber1
0 clobber2
% manifest before
644 a
644 d/b
644 @ dlink
644 @ dlink2
644 dlink3
% manifest after clobber1
644 a/b
644 d/b
644 dlink/b
644 @ dlink2
644 dlink3
% manifest after clobber2
644 a/b
644 d/b
644 dlink/b
644 @ dlink2
644 @ dlink3
% try updating