# HG changeset patch # User Maxim Dounin # Date 1198714486 -10800 # Node ID b63ef7b1441c11cc89ddb7156a878ae0ee067438 # Parent 98f45e141567b5f4b0bc82178fd8713f64991095 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(). diff -r 98f45e141567 -r b63ef7b1441c hgext/convert/subversion.py --- a/hgext/convert/subversion.py Thu Dec 27 19:59:44 2007 +0300 +++ b/hgext/convert/subversion.py Thu Dec 27 03:14:46 2007 +0300 @@ -725,6 +725,9 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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) diff -r 98f45e141567 -r b63ef7b1441c tests/test-convert-svn-sink --- a/tests/test-convert-svn-sink Thu Dec 27 19:59:44 2007 +0300 +++ b/tests/test-convert-svn-sink Thu Dec 27 03:14:46 2007 +0300 @@ -59,6 +59,29 @@ (cd a-hg-wc; svn up; svn st -v; svn log --xml -v --limit=1 | sed 's,.*,,') 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,.*,,') +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,.*,,') + echo % branchy history hg init b diff -r 98f45e141567 -r b63ef7b1441c tests/test-convert-svn-sink.out --- a/tests/test-convert-svn-sink.out Thu Dec 27 19:59:44 2007 +0300 +++ b/tests/test-convert-svn-sink.out Thu Dec 27 03:14:46 2007 +0300 @@ -195,6 +195,65 @@ 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 + + + +test + + +/d1 +/d1/a + +add executable file in new directory + + +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 + + + +test + + +/d2 +/d2/a + +copy file to new directory + + % branchy history adding b adding left-1