Mercurial > hgsubversion
comparison hg_delta_editor.py @ 331:75f082b5897e
Switch to using url scheme wrappers instead of duplicating each command we wrap.
The 'hg svn url' command has been killed; the replacement is
'.hg/hgrc'. More stuff related to its disappearance has been stripped,
including two tests.
HgChangeReceiver now takes a UUID argument, which it uses to ensure
that remote repositories remain unchanged. This is a temporary
solution, and I'm not entirely satisfied with how it's done either.
Access to the UUID file has been isolated in a HgChangeReceiver
property.
Some more tests have been updated to use ui.pushbuffer()/popbuffer(),
and to pass through the Mercurial API.
Moved the arguments to wrappers.pull() to the UI configuration.
Also, remove HgChangeReceiver.opts in favour of a 'usebranchnames'
instance & configuration variable. The name is taken from the
ConvertExtension.
author | Dan Villiom Podlaski Christiansen <danchr@gmail.com> |
---|---|
date | Fri, 15 May 2009 19:18:43 +0200 |
parents | 5f8f2fd4fd54 |
children | 9ef720a611e0 |
comparison
equal
deleted
inserted
replaced
330:5f8f2fd4fd54 | 331:75f082b5897e |
---|---|
9 from mercurial import hg | 9 from mercurial import hg |
10 from mercurial import ui | 10 from mercurial import ui |
11 from mercurial import util as hgutil | 11 from mercurial import util as hgutil |
12 from mercurial import revlog | 12 from mercurial import revlog |
13 from mercurial import node | 13 from mercurial import node |
14 from mercurial import error | |
14 from svn import delta | 15 from svn import delta |
15 from svn import core | 16 from svn import core |
16 | 17 |
17 import svnexternals | 18 import svnexternals |
18 import util | 19 import util |
72 except ValueError: | 73 except ValueError: |
73 return 0 | 74 return 0 |
74 | 75 |
75 def __init__(self, path=None, repo=None, ui_=None, | 76 def __init__(self, path=None, repo=None, ui_=None, |
76 subdir='', author_host='', | 77 subdir='', author_host='', |
77 tag_locations=['tags'], | 78 tag_locations=[], |
78 authors=None, | 79 authors=None, filemap=None, uuid=None): |
79 filemap=None): | |
80 """path is the path to the target hg repo. | 80 """path is the path to the target hg repo. |
81 | 81 |
82 subdir is the subdirectory of the edits *on the svn server*. | 82 subdir is the subdirectory of the edits *on the svn server*. |
83 It is needed for stripping paths off in certain cases. | 83 It is needed for stripping paths off in certain cases. |
84 """ | 84 """ |
85 if repo and repo.ui and not ui_: | 85 if repo and repo.ui and not ui_: |
86 ui_ = repo.ui | 86 ui_ = repo.ui |
87 if not ui_: | 87 if not ui_: |
88 ui_ = ui.ui() | 88 ui_ = ui.ui() |
89 self.ui = ui_ | 89 self.ui = ui_ |
90 self.__setup_repo(repo or path) | 90 self.__setup_repo(repo or path, uuid) |
91 | |
92 if not author_host: | |
93 author_host = self.ui.config('hgsubversion', 'defaulthost', uuid) | |
94 if not authors: | |
95 authors = self.ui.config('hgsubversion', 'authormap') | |
96 if not filemap: | |
97 filemap = self.ui.config('hgsubversion', 'filemap') | |
98 if not tag_locations: | |
99 tag_locations = self.ui.config('hgsubversion', 'tagpaths', ['tags']) | |
100 self.usebranchnames = self.ui.configbool('hgsubversion', | |
101 'usebranchnames', True) | |
91 | 102 |
92 self.subdir = subdir | 103 self.subdir = subdir |
93 if self.subdir and self.subdir[0] == '/': | 104 if self.subdir and self.subdir[0] == '/': |
94 self.subdir = self.subdir[1:] | 105 self.subdir = self.subdir[1:] |
95 self.revmap = {} | |
96 if os.path.exists(self.revmap_file): | |
97 self.revmap = util.parse_revmap(self.revmap_file) | |
98 self.branches = {} | 106 self.branches = {} |
99 if os.path.exists(self.branch_info_file): | 107 if os.path.exists(self.branch_info_file): |
100 f = open(self.branch_info_file) | 108 f = open(self.branch_info_file) |
101 self.branches = pickle.load(f) | 109 self.branches = pickle.load(f) |
102 f.close() | 110 f.close() |
135 self.lastdate = date | 143 self.lastdate = date |
136 else: | 144 else: |
137 date = self.lastdate | 145 date = self.lastdate |
138 return date | 146 return date |
139 | 147 |
140 def __setup_repo(self, arg): | 148 def __setup_repo(self, arg, uuid): |
141 """Verify the repo is going to work out for us. | 149 """Verify the repo is going to work out for us. |
142 | 150 |
143 This method will fail an assertion if the repo exists but doesn't have | 151 This method will fail an assertion if the repo exists but doesn't have |
144 the Subversion metadata. | 152 the Subversion metadata. |
145 """ | 153 """ |
152 self.path = os.path.normpath(os.path.join(self.repo.path, '..')) | 160 self.path = os.path.normpath(os.path.join(self.repo.path, '..')) |
153 else: #pragma: no cover | 161 else: #pragma: no cover |
154 raise TypeError("editor requires either a path or a repository " | 162 raise TypeError("editor requires either a path or a repository " |
155 "specified") | 163 "specified") |
156 | 164 |
157 if os.path.isdir(self.meta_data_dir) and os.listdir(self.meta_data_dir): | 165 if not os.path.isdir(self.meta_data_dir): |
158 assert os.path.isfile(self.revmap_file) | 166 os.makedirs(self.meta_data_dir) |
159 assert os.path.isfile(self.svn_url_file) | 167 self._set_uuid(uuid) |
160 assert os.path.isfile(self.uuid_file) | 168 |
169 if os.path.isfile(self.revmap_file): | |
170 self.revmap = util.parse_revmap(self.revmap_file) | |
161 else: | 171 else: |
162 os.makedirs(os.path.dirname(self.uuid_file)) | 172 self.revmap = {} |
163 f = open(self.revmap_file, 'w') | 173 f = open(self.revmap_file, 'w') |
164 f.write('%s\n' % util.REVMAP_FILE_VERSION) | 174 f.write('%s\n' % util.REVMAP_FILE_VERSION) |
165 f.flush() | 175 f.flush() |
166 f.close() | 176 f.close() |
167 | 177 |
634 parents = (ha, closed) | 644 parents = (ha, closed) |
635 def del_all_files(*args): | 645 def del_all_files(*args): |
636 raise IOError | 646 raise IOError |
637 files = parentctx.manifest().keys() | 647 files = parentctx.manifest().keys() |
638 extra = {} | 648 extra = {} |
639 if not self.opts.get('svn_no_branchnames', False): | 649 if self.usebranchnames: |
640 extra['branch'] = 'closed-branches' | 650 extra['branch'] = 'closed-branches' |
641 current_ctx = context.memctx(self.repo, | 651 current_ctx = context.memctx(self.repo, |
642 parents, | 652 parents, |
643 rev.message or ' ', | 653 rev.message or ' ', |
644 files, | 654 files, |
656 | 666 |
657 parents = (self.get_parent_revision(rev.revnum, branch), | 667 parents = (self.get_parent_revision(rev.revnum, branch), |
658 revlog.nullid) | 668 revlog.nullid) |
659 if parents[0] in closed_revs and branch in self.branches_to_delete: | 669 if parents[0] in closed_revs and branch in self.branches_to_delete: |
660 continue | 670 continue |
661 extra = util.build_extra(rev.revnum, branch, | 671 extra = util.build_extra(rev.revnum, branch, self.uuid, self.subdir) |
662 open(self.uuid_file).read(), | |
663 self.subdir) | |
664 if branch is not None: | 672 if branch is not None: |
665 if (branch not in self.branches | 673 if (branch not in self.branches |
666 and branch not in self.repo.branchtags()): | 674 and branch not in self.repo.branchtags()): |
667 continue | 675 continue |
668 parent_ctx = self.repo.changectx(parents[0]) | 676 parent_ctx = self.repo.changectx(parents[0]) |
689 data = parent_ctx.filectx(path).data() | 697 data = parent_ctx.filectx(path).data() |
690 return context.memfilectx(path=path, | 698 return context.memfilectx(path=path, |
691 data=data, | 699 data=data, |
692 islink=is_link, isexec=is_exec, | 700 islink=is_link, isexec=is_exec, |
693 copied=copied) | 701 copied=copied) |
694 if self.opts.get('svn_no_branchnames', False): | 702 if not self.usebranchnames: |
695 extra.pop('branch', None) | 703 extra.pop('branch', None) |
696 current_ctx = context.memctx(self.repo, | 704 current_ctx = context.memctx(self.repo, |
697 parents, | 705 parents, |
698 rev.message or '...', | 706 rev.message or '...', |
699 files.keys(), | 707 files.keys(), |
715 raise IOError | 723 raise IOError |
716 # True here meant nuke all files, shouldn't happen with branch closing | 724 # True here meant nuke all files, shouldn't happen with branch closing |
717 if self.commit_branches_empty[branch]: #pragma: no cover | 725 if self.commit_branches_empty[branch]: #pragma: no cover |
718 raise hgutil.Abort('Empty commit to an open branch attempted. ' | 726 raise hgutil.Abort('Empty commit to an open branch attempted. ' |
719 'Please report this issue.') | 727 'Please report this issue.') |
720 extra = util.build_extra(rev.revnum, branch, | 728 extra = util.build_extra(rev.revnum, branch, self.uuid, self.subdir) |
721 open(self.uuid_file).read(), | 729 if not self.usebranchnames: |
722 self.subdir) | |
723 if self.opts.get('svn_no_branchnames', False): | |
724 extra.pop('branch', None) | 730 extra.pop('branch', None) |
725 current_ctx = context.memctx(self.repo, | 731 current_ctx = context.memctx(self.repo, |
726 (ha, node.nullid), | 732 (ha, node.nullid), |
727 rev.message or ' ', | 733 rev.message or ' ', |
728 [], | 734 [], |
781 | 787 |
782 def revmap_file(self): | 788 def revmap_file(self): |
783 return self.meta_file_named('rev_map') | 789 return self.meta_file_named('rev_map') |
784 revmap_file = property(revmap_file) | 790 revmap_file = property(revmap_file) |
785 | 791 |
786 def svn_url_file(self): | 792 def _get_uuid(self): |
787 return self.meta_file_named('url') | 793 return open(self.meta_file_named('uuid')).read() |
788 svn_url_file = property(svn_url_file) | 794 |
789 | 795 def _set_uuid(self, uuid): |
790 def uuid_file(self): | 796 if not uuid: |
791 return self.meta_file_named('uuid') | 797 return self._get_uuid() |
792 uuid_file = property(uuid_file) | 798 elif os.path.isfile(self.meta_file_named('uuid')): |
799 stored_uuid = self._get_uuid() | |
800 assert stored_uuid | |
801 if uuid != stored_uuid: | |
802 raise hgutil.Abort('unable to operate on unrelated repository') | |
803 else: | |
804 return stored_uuid | |
805 else: | |
806 if uuid: | |
807 f = open(self.meta_file_named('uuid'), 'w') | |
808 f.write(uuid) | |
809 f.flush() | |
810 f.close() | |
811 return self._get_uuid() | |
812 else: | |
813 raise hgutil.Abort('unable to operate on unrelated repository') | |
814 | |
815 uuid = property(_get_uuid, _set_uuid, None, | |
816 'Error-checked UUID of source Subversion repository.') | |
793 | 817 |
794 def branch_info_file(self): | 818 def branch_info_file(self): |
795 return self.meta_file_named('branch_info') | 819 return self.meta_file_named('branch_info') |
796 branch_info_file = property(branch_info_file) | 820 branch_info_file = property(branch_info_file) |
797 | 821 |
800 tag_info_file = property(tag_info_file) | 824 tag_info_file = property(tag_info_file) |
801 | 825 |
802 def tag_locations_file(self): | 826 def tag_locations_file(self): |
803 return self.meta_file_named('tag_locations') | 827 return self.meta_file_named('tag_locations') |
804 tag_locations_file = property(tag_locations_file) | 828 tag_locations_file = property(tag_locations_file) |
805 | |
806 def url(self): | |
807 return open(self.svn_url_file).read() | |
808 url = property(url) | |
809 | 829 |
810 def authors_file(self): | 830 def authors_file(self): |
811 return self.meta_file_named('authors') | 831 return self.meta_file_named('authors') |
812 authors_file = property(authors_file) | 832 authors_file = property(authors_file) |
813 | 833 |