changeset 5698:b63ef7b1441c

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().
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 27 Dec 2007 03:14:46 +0300
parents 98f45e141567
children 4cf5a4950fc9
files hgext/convert/subversion.py tests/test-convert-svn-sink tests/test-convert-svn-sink.out
diffstat 3 files changed, 110 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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,<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
--- 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 @@
 </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