convert: svn-sink: copy and set properties after adding dirs/files

We can't store properties for files we haven't added to repo. Similarly,
we can't copy file to directory we haven't added to svn yet. Remember
needed changes and apply them in putcommit().
This commit is contained in:
Maxim Dounin 2007-12-27 03:14:46 +03:00
parent a8a4715876
commit 54de122616
3 changed files with 110 additions and 7 deletions

View File

@ -725,6 +725,9 @@ class svn_sink(converter_sink, commandline):
converter_sink.__init__(self, ui, path)
commandline.__init__(self, ui, 'svn')
self.delete = []
self.setexec = []
self.delexec = []
self.copies = []
self.wc = None
self.cwd = os.getcwd()
@ -792,15 +795,18 @@ class svn_sink(converter_sink, commandline):
util.set_exec(self.wjoin(filename), 'x' in flags)
if was_exec:
if 'x' not in flags:
self.run0('propdel', 'svn:executable', filename)
self.delexec.append(filename)
else:
if 'x' in flags:
self.run0('propset', 'svn:executable', '*', filename)
self.setexec.append(filename)
def delfile(self, name):
self.delete.append(name)
def copyfile(self, source, dest):
self.copies.append([source, dest])
def _copyfile(self, source, dest):
# SVN's copy command pukes if the destination file exists, but
# our copyfile method expects to record a copy that has
# already occurred. Cross the semantic gap.
@ -831,15 +837,18 @@ class svn_sink(converter_sink, commandline):
dirs.add(f[:i])
return dirs
def add_files(self, files):
def add_dirs(self, files):
add_dirs = [d for d in self.dirs_of(files)
if not os.path.exists(self.wjoin(d, '.svn', 'entries'))]
if add_dirs:
add_dirs.sort()
self.run('add', non_recursive=True, quiet=True, *add_dirs)
return add_dirs
def add_files(self, files):
if files:
self.run('add', quiet=True, *files)
return files.union(add_dirs)
return files
def tidy_dirs(self, names):
dirs = list(self.dirs_of(names))
@ -857,7 +866,7 @@ class svn_sink(converter_sink, commandline):
def revid(self, rev):
return u"svn:%s@%s" % (self.uuid, rev)
def putcommit(self, files, parents, commit):
for parent in parents:
try:
@ -865,12 +874,24 @@ class svn_sink(converter_sink, commandline):
except KeyError:
pass
entries = set(self.delete)
files = util.frozenset(files)
entries.update(self.add_dirs(files.difference(entries)))
if self.copies:
for s, d in self.copies:
self._copyfile(s, d)
self.copies = []
if self.delete:
self.run0('delete', *self.delete)
self.delete = []
files = util.frozenset(files)
entries.update(self.add_files(files.difference(entries)))
entries.update(self.tidy_dirs(entries))
if self.delexec:
self.run0('propdel', 'svn:executable', *self.delexec)
self.delexec = []
if self.setexec:
self.run0('propset', 'svn:executable', '*', *self.setexec)
self.setexec = []
fd, messagefile = tempfile.mkstemp(prefix='hg-convert-')
fp = os.fdopen(fd, 'w')
fp.write(commit.desc)

View File

@ -59,6 +59,29 @@ hg convert -d svn a
(cd a-hg-wc; svn up; svn st -v; svn log --xml -v --limit=1 | sed 's,<date>.*,<date/>,')
test -x a-hg-wc/c && echo executable || echo not executable
echo % executable in new directory
rm -rf a a-hg a-hg-wc
hg init a
mkdir a/d1
echo a > a/d1/a
chmod +x a/d1/a
hg --cwd a ci -d '0 0' -A -m 'add executable file in new directory'
hg convert -d svn a
(cd a-hg-wc; svn up; svn st -v; svn log --xml -v --limit=1 | sed 's,<date>.*,<date/>,')
test -x a-hg-wc/d1/a && echo executable || echo not executable
echo % copy to new directory
mkdir a/d2
hg --cwd a cp d1/a d2/a
hg --cwd a ci -d '1 0' -A -m 'copy file to new directory'
hg convert -d svn a
(cd a-hg-wc; svn up; svn st -v; svn log --xml -v --limit=1 | sed 's,<date>.*,<date/>,')
echo % branchy history
hg init b

View File

@ -195,6 +195,65 @@ At revision 5.
</logentry>
</log>
executable
% executable in new directory
adding d1/a
assuming destination a-hg
initializing svn repo 'a-hg'
initializing svn wc 'a-hg-wc'
scanning source...
sorting...
converting...
0 add executable file in new directory
At revision 1.
1 1 test .
1 1 test d1
1 1 test d1/a
<?xml version="1.0"?>
<log>
<logentry
revision="1">
<author>test</author>
<date/>
<paths>
<path
action="A">/d1</path>
<path
action="A">/d1/a</path>
</paths>
<msg>add executable file in new directory</msg>
</logentry>
</log>
executable
% copy to new directory
assuming destination a-hg
initializing svn wc 'a-hg-wc'
scanning source...
sorting...
converting...
0 copy file to new directory
At revision 2.
2 2 test .
2 1 test d1
2 1 test d1/a
2 2 test d2
2 2 test d2/a
<?xml version="1.0"?>
<log>
<logentry
revision="2">
<author>test</author>
<date/>
<paths>
<path
action="A">/d2</path>
<path
copyfrom-path="/d1/a"
copyfrom-rev="1"
action="A">/d2/a</path>
</paths>
<msg>copy file to new directory</msg>
</logentry>
</log>
% branchy history
adding b
adding left-1