comparison hgext/convert/subversion.py @ 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 6e1a61b14bbf
children 4e400863c5ac
comparison
equal deleted inserted replaced
5697:98f45e141567 5698:b63ef7b1441c
723 723
724 def __init__(self, ui, path): 724 def __init__(self, ui, path):
725 converter_sink.__init__(self, ui, path) 725 converter_sink.__init__(self, ui, path)
726 commandline.__init__(self, ui, 'svn') 726 commandline.__init__(self, ui, 'svn')
727 self.delete = [] 727 self.delete = []
728 self.setexec = []
729 self.delexec = []
730 self.copies = []
728 self.wc = None 731 self.wc = None
729 self.cwd = os.getcwd() 732 self.cwd = os.getcwd()
730 733
731 path = os.path.realpath(path) 734 path = os.path.realpath(path)
732 735
790 was_exec = 'x' not in flags 793 was_exec = 'x' not in flags
791 794
792 util.set_exec(self.wjoin(filename), 'x' in flags) 795 util.set_exec(self.wjoin(filename), 'x' in flags)
793 if was_exec: 796 if was_exec:
794 if 'x' not in flags: 797 if 'x' not in flags:
795 self.run0('propdel', 'svn:executable', filename) 798 self.delexec.append(filename)
796 else: 799 else:
797 if 'x' in flags: 800 if 'x' in flags:
798 self.run0('propset', 'svn:executable', '*', filename) 801 self.setexec.append(filename)
799 802
800 def delfile(self, name): 803 def delfile(self, name):
801 self.delete.append(name) 804 self.delete.append(name)
802 805
803 def copyfile(self, source, dest): 806 def copyfile(self, source, dest):
807 self.copies.append([source, dest])
808
809 def _copyfile(self, source, dest):
804 # SVN's copy command pukes if the destination file exists, but 810 # SVN's copy command pukes if the destination file exists, but
805 # our copyfile method expects to record a copy that has 811 # our copyfile method expects to record a copy that has
806 # already occurred. Cross the semantic gap. 812 # already occurred. Cross the semantic gap.
807 wdest = self.wjoin(dest) 813 wdest = self.wjoin(dest)
808 exists = os.path.exists(wdest) 814 exists = os.path.exists(wdest)
829 dirs.add(f) 835 dirs.add(f)
830 for i in strutil.rfindall(f, '/'): 836 for i in strutil.rfindall(f, '/'):
831 dirs.add(f[:i]) 837 dirs.add(f[:i])
832 return dirs 838 return dirs
833 839
834 def add_files(self, files): 840 def add_dirs(self, files):
835 add_dirs = [d for d in self.dirs_of(files) 841 add_dirs = [d for d in self.dirs_of(files)
836 if not os.path.exists(self.wjoin(d, '.svn', 'entries'))] 842 if not os.path.exists(self.wjoin(d, '.svn', 'entries'))]
837 if add_dirs: 843 if add_dirs:
838 add_dirs.sort() 844 add_dirs.sort()
839 self.run('add', non_recursive=True, quiet=True, *add_dirs) 845 self.run('add', non_recursive=True, quiet=True, *add_dirs)
846 return add_dirs
847
848 def add_files(self, files):
840 if files: 849 if files:
841 self.run('add', quiet=True, *files) 850 self.run('add', quiet=True, *files)
842 return files.union(add_dirs) 851 return files
843 852
844 def tidy_dirs(self, names): 853 def tidy_dirs(self, names):
845 dirs = list(self.dirs_of(names)) 854 dirs = list(self.dirs_of(names))
846 dirs.sort(reverse=True) 855 dirs.sort(reverse=True)
847 deleted = [] 856 deleted = []
855 def addchild(self, parent, child): 864 def addchild(self, parent, child):
856 self.childmap[parent] = child 865 self.childmap[parent] = child
857 866
858 def revid(self, rev): 867 def revid(self, rev):
859 return u"svn:%s@%s" % (self.uuid, rev) 868 return u"svn:%s@%s" % (self.uuid, rev)
860 869
861 def putcommit(self, files, parents, commit): 870 def putcommit(self, files, parents, commit):
862 for parent in parents: 871 for parent in parents:
863 try: 872 try:
864 return self.revid(self.childmap[parent]) 873 return self.revid(self.childmap[parent])
865 except KeyError: 874 except KeyError:
866 pass 875 pass
867 entries = set(self.delete) 876 entries = set(self.delete)
877 files = util.frozenset(files)
878 entries.update(self.add_dirs(files.difference(entries)))
879 if self.copies:
880 for s, d in self.copies:
881 self._copyfile(s, d)
882 self.copies = []
868 if self.delete: 883 if self.delete:
869 self.run0('delete', *self.delete) 884 self.run0('delete', *self.delete)
870 self.delete = [] 885 self.delete = []
871 files = util.frozenset(files)
872 entries.update(self.add_files(files.difference(entries))) 886 entries.update(self.add_files(files.difference(entries)))
873 entries.update(self.tidy_dirs(entries)) 887 entries.update(self.tidy_dirs(entries))
888 if self.delexec:
889 self.run0('propdel', 'svn:executable', *self.delexec)
890 self.delexec = []
891 if self.setexec:
892 self.run0('propset', 'svn:executable', '*', *self.setexec)
893 self.setexec = []
894
874 fd, messagefile = tempfile.mkstemp(prefix='hg-convert-') 895 fd, messagefile = tempfile.mkstemp(prefix='hg-convert-')
875 fp = os.fdopen(fd, 'w') 896 fp = os.fdopen(fd, 'w')
876 fp.write(commit.desc) 897 fp.write(commit.desc)
877 fp.close() 898 fp.close()
878 try: 899 try: