Mercurial > hgsubversion
diff hg_delta_editor.py @ 304:ce676eff002b
First merge, totally untested.
author | Dan Villiom Podlaski Christiansen <danchr@gmail.com> |
---|---|
date | Fri, 01 May 2009 10:28:59 +0200 |
parents | 4aba7542f6a9 153266401676 |
children | e6853c7fa3af |
line wrap: on
line diff
--- a/hg_delta_editor.py +++ b/hg_delta_editor.py @@ -8,14 +8,14 @@ import traceback from mercurial import context from mercurial import hg from mercurial import ui -from mercurial import util +from mercurial import util as hgutil from mercurial import revlog from mercurial import node from svn import delta from svn import core import svnexternals -import util as our_util +import util def pickle_atomic(data, file_path, dir=None): """pickle some data to a path atomically. @@ -31,7 +31,7 @@ def pickle_atomic(data, file_path, dir=N except: #pragma: no cover raise else: - util.rename(path, file_path) + hgutil.rename(path, file_path) def stash_exception_on_self(fn): """Stash any exception raised in the method on self. @@ -60,12 +60,12 @@ class HgChangeReceiver(delta.Editor): self.revmap[revnum, branch] = node_hash def last_known_revision(self): - ''' Obtain the highest numbered -- i.e. latest -- revision known. + """Obtain the highest numbered -- i.e. latest -- revision known. Currently, this function just iterates over the entire revision map using the max() builtin. This may be slow for extremely large repositories, but for now, it's fast enough. - ''' + """ try: return max(k[0] for k in self.revmap.iterkeys()) except ValueError: @@ -81,6 +81,8 @@ class HgChangeReceiver(delta.Editor): subdir is the subdirectory of the edits *on the svn server*. It is needed for stripping paths off in certain cases. """ + if repo and repo.ui and not ui_: + ui_ = repo.ui if not ui_: ui_ = ui.ui() self.ui = ui_ @@ -98,7 +100,7 @@ class HgChangeReceiver(delta.Editor): self.subdir = self.subdir[1:] self.revmap = {} if os.path.exists(self.revmap_file): - self.revmap = our_util.parse_revmap(self.revmap_file) + self.revmap = util.parse_revmap(self.revmap_file) self.branches = {} if os.path.exists(self.branch_info_file): f = open(self.branch_info_file) @@ -130,11 +132,22 @@ class HgChangeReceiver(delta.Editor): self.readauthors(authors) if self.authors: self.writeauthors() + + self.lastdate = '1970-01-01 00:00:00 -0000' self.includepaths = {} self.excludepaths = {} if filemap and os.path.exists(filemap): self.readfilemap(filemap) + def fixdate(self, date): + if date is not None: + date = date.replace('T', ' ').replace('Z', '').split('.')[0] + date += ' -0000' + self.lastdate = date + else: + date = self.lastdate + return date + def __setup_repo(self, repo_path): """Verify the repo is going to work out for us. @@ -150,7 +163,7 @@ class HgChangeReceiver(delta.Editor): self.repo = hg.repository(self.ui, repo_path, create=True) os.makedirs(os.path.dirname(self.uuid_file)) f = open(self.revmap_file, 'w') - f.write('%s\n' % our_util.REVMAP_FILE_VERSION) + f.write('%s\n' % util.REVMAP_FILE_VERSION) f.flush() f.close() @@ -206,8 +219,6 @@ class HgChangeReceiver(delta.Editor): while paths_need_discovery: p = paths_need_discovery.pop(0) path_could_be_file = True - # TODO(augie) Figure out if you can use break here in a for loop, quick - # testing of that failed earlier. ind = 0 while ind < len(paths_need_discovery) and not paths_need_discovery: if op.startswith(p): @@ -233,10 +244,14 @@ class HgChangeReceiver(delta.Editor): parentdir = '/'.join(path[:-1]) filepaths = [p for p in filepaths if not '/'.join(p).startswith(parentdir)] branchpath = self._normalize_path(parentdir) + if branchpath.startswith('tags/'): + continue branchname = self._localname(branchpath) if branchpath.startswith('trunk/'): branches[self._localname('trunk')] = 'trunk' continue + if branchname and branchname.startswith('../'): + continue branches[branchname] = branchpath return branches @@ -250,6 +265,7 @@ class HgChangeReceiver(delta.Editor): def _localname(self, path): """Compute the local name for a branch located at path. """ + assert not path.startswith('tags/') if path == 'trunk': return None elif path.startswith('branches/'): @@ -274,6 +290,8 @@ class HgChangeReceiver(delta.Editor): known. """ path = self._normalize_path(path) + if path.startswith('tags/'): + return None, None, None test = '' path_comps = path.split('/') while self._localname(test) not in self.branches and len(path_comps): @@ -288,10 +306,17 @@ class HgChangeReceiver(delta.Editor): if path.startswith('trunk/'): path = test.split('/')[1:] test = 'trunk' + elif path.startswith('branches/'): + elts = path.split('/') + test = '/'.join(elts[:2]) + path = '/'.join(elts[2:]) else: path = test.split('/')[-1] test = '/'.join(test.split('/')[:-1]) - return path, self._localname(test), test + ln = self._localname(test) + if ln and ln.startswith('../'): + return None, None, None + return path, ln, test def set_current_rev(self, rev): """Set the revision we're currently converting. @@ -358,6 +383,8 @@ class HgChangeReceiver(delta.Editor): return True def _is_path_valid(self, path): + if path is None: + return False subpath = self._split_branch_path(path)[0] if subpath is None: return False @@ -504,7 +531,7 @@ class HgChangeReceiver(delta.Editor): # check for case 5 for known in self.branches: if self._svnpath(known).startswith(p): - self.branches_to_delete.add(br) # case 5 + self.branches_to_delete.add(known) # case 5 added_branches.update(self.__determine_parent_branch(p, paths[p].copyfrom_path, paths[p].copyfrom_rev, revision.revnum)) for t in tags_to_delete: @@ -565,8 +592,7 @@ class HgChangeReceiver(delta.Editor): files_to_commit.sort() branch_batches = {} rev = self.current_rev - date = rev.date.replace('T', ' ').replace('Z', '').split('.')[0] - date += ' -0000' + date = self.fixdate(rev.date) # build up the branches that have files on them for f in files_to_commit: @@ -615,10 +641,9 @@ class HgChangeReceiver(delta.Editor): revlog.nullid) if parents[0] in closed_revs and branch in self.branches_to_delete: continue - # TODO this needs to be fixed with the new revmap - extra = our_util.build_extra(rev.revnum, branch, - open(self.uuid_file).read(), - self.subdir) + extra = util.build_extra(rev.revnum, branch, + open(self.uuid_file).read(), + self.subdir) if branch is not None: if (branch not in self.branches and branch not in self.repo.branchtags()): @@ -658,7 +683,7 @@ class HgChangeReceiver(delta.Editor): date, extra) new_hash = self.repo.commitctx(current_ctx) - our_util.describe_commit(self.ui, new_hash, branch) + util.describe_commit(self.ui, new_hash, branch) if (rev.revnum, branch) not in self.revmap: self.add_to_revmap(rev.revnum, branch, new_hash) # now we handle branches that need to be committed without any files @@ -671,9 +696,9 @@ class HgChangeReceiver(delta.Editor): raise IOError # True here meant nuke all files, shouldn't happen with branch closing if self.commit_branches_empty[branch]: #pragma: no cover - raise util.Abort('Empty commit to an open branch attempted. ' - 'Please report this issue.') - extra = our_util.build_extra(rev.revnum, branch, + raise hgutil.Abort('Empty commit to an open branch attempted. ' + 'Please report this issue.') + extra = util.build_extra(rev.revnum, branch, open(self.uuid_file).read(), self.subdir) current_ctx = context.memctx(self.repo, @@ -685,23 +710,23 @@ class HgChangeReceiver(delta.Editor): date, extra) new_hash = self.repo.commitctx(current_ctx) - our_util.describe_commit(self.ui, new_hash, branch) + util.describe_commit(self.ui, new_hash, branch) if (rev.revnum, branch) not in self.revmap: self.add_to_revmap(rev.revnum, branch, new_hash) self._save_metadata() self.clear_current_info() def authorforsvnauthor(self, author): - if(author in self.authors): + if author in self.authors: return self.authors[author] - return '%s%s' %(author, self.author_host) + return '%s%s' % (author, self.author_host) def svnauthorforauthor(self, author): for svnauthor, hgauthor in self.authors.iteritems(): if author == hgauthor: return svnauthor else: - # Mercurial incorrectly splits at e.g. '.', so we roll our own. + # return the original svn-side author return author.rsplit('@', 1)[0] def readauthors(self, authorfile): @@ -837,8 +862,8 @@ class HgChangeReceiver(delta.Editor): # assuming it is a directory self.externals[path] = None map(self.delete_file, [pat for pat in self.current_files.iterkeys() - if pat.startswith(path)]) - for f in ctx.walk(our_util.PrefixMatch(br_path2)): + if pat.startswith(path+'/')]) + for f in ctx.walk(util.PrefixMatch(br_path2)): f_p = '%s/%s' % (path, f[len(br_path2):]) if f_p not in self.current_files: self.delete_file(f_p) @@ -846,7 +871,7 @@ class HgChangeReceiver(delta.Editor): delete_entry = stash_exception_on_self(delete_entry) def open_file(self, path, parent_baton, base_revision, p=None): - self.current_file = 'foobaz' + self.current_file = None fpath, branch = self._path_and_branch_for_path(path) if fpath: self.current_file = path @@ -891,7 +916,7 @@ class HgChangeReceiver(delta.Editor): def add_file(self, path, parent_baton=None, copyfrom_path=None, copyfrom_revision=None, file_pool=None): - self.current_file = 'foobaz' + self.current_file = None self.base_revision = None if path in self.deleted_files: del self.deleted_files[path] @@ -953,6 +978,7 @@ class HgChangeReceiver(delta.Editor): source_rev = copyfrom_revision cp_f, source_branch = self._path_and_branch_for_path(copyfrom_path) if cp_f == '' and br_path == '': + assert br_path is not None self.branches[branch] = source_branch, source_rev, self.current_rev.revnum new_hash = self.get_parent_revision(source_rev + 1, source_branch) @@ -1036,8 +1062,8 @@ class HgChangeReceiver(delta.Editor): handler, baton = delta.svn_txdelta_apply(source, target, None) if not callable(handler): #pragma: no cover - raise util.Abort('Error in Subversion bindings: ' - 'cannot call handler!') + raise hgutil.Abort('Error in Subversion bindings: ' + 'cannot call handler!') def txdelt_window(window): try: if not self._is_path_valid(self.current_file): @@ -1050,7 +1076,7 @@ class HgChangeReceiver(delta.Editor): if e.apr_err == core.SVN_ERR_INCOMPLETE_DATA: self.missing_plaintexts.add(self.current_file) else: #pragma: no cover - raise util.Abort(*e.args) + raise hgutil.Abort(*e.args) except: #pragma: no cover print len(base), self.current_file self._exception_info = sys.exc_info()