# HG changeset patch # User Augie Fackler # Date 1225076773 18000 # Node ID b3c7b844b7828fb92308688d2ef632657c747cd0 # Parent 9ee7ce0505ebb32e34f559479fe37325dd155b5f Some more fixes of cases discovered in the melange repo. If anyone knows how I can reproduce a "replaced" state in Subversion, I'd love to be able to make a real test case for this code. diff --git a/fetch_command.py b/fetch_command.py --- a/fetch_command.py +++ b/fetch_command.py @@ -394,7 +394,16 @@ def stupid_svn_server_pull_rev(ui, svn, used_diff = False shutil.rmtree(our_tempdir) os.makedirs(our_tempdir) - svn.fetch_all_files_to_dir(diff_path, r.revnum, our_tempdir) + try: + svn.fetch_all_files_to_dir(diff_path, r.revnum, our_tempdir) + except core.SubversionException, e: + # apr_err 21 means that we couldn't rename a file to be a dir. + # This happens only in the case (at least right now) of a file + # located in brances or tags, which we don't support anyway. + if e.apr_err == 21: + continue + else: + raise except core.SubversionException, e: if e.apr_err == 170000 or (e.message.startswith("URL '") and e.message.endswith("' doesn't exist")): diff --git a/hg_delta_editor.py b/hg_delta_editor.py --- a/hg_delta_editor.py +++ b/hg_delta_editor.py @@ -468,9 +468,13 @@ class HgChangeReceiver(delta.Editor): if br_path != '': br_path2 = br_path + '/' # assuming it is a directory - for f in ctx: - if f.startswith(br_path2): - f_p = '%s/%s' % (path, f[len(br_path2):]) + def delete_x(x): + self.deleted_files[x] = True + map(delete_x, [pat for pat in self.current_files.iterkeys() + if pat.startswith(path)]) + for f in ctx.walk(our_util.PrefixMatch(br_path2)): + f_p = '%s/%s' % (path, f[len(br_path2):]) + if f_p not in self.current_files: self.deleted_files[f_p] = True self.current_files[f_p] = '' self.ui.status('D %s\n' % f_p) @@ -550,6 +554,8 @@ class HgChangeReceiver(delta.Editor): self.current_files[fp_c] = fctx.data() self.current_files_exec[fp_c] = 'x' in fctx.flags() self.current_files_symlink[fp_c] = 'l' in fctx.flags() + if fp_c in self.deleted_files: + del self.deleted_files[fp_c] # TODO(augie) tag copies from files @stash_exception_on_self diff --git a/push_cmd.py b/push_cmd.py --- a/push_cmd.py +++ b/push_cmd.py @@ -65,15 +65,6 @@ def push_revisions_to_subversion(ui, rep svn_commit_hashes) return 0 -class PrefixMatch(object): - def __init__(self, prefix): - self.p = prefix - - def files(self): - return [] - - def __call__(self, fn): - return fn.startswith(self.p) def commit_from_rev(ui, repo, rev_ctx, hg_editor, svn_url, base_revision): """Build and send a commit from Mercurial to Subversion. @@ -106,7 +97,7 @@ def commit_from_rev(ui, repo, rev_ctx, h action = 'add' dirname = '/'.join(file.split('/')[:-1] + ['']) # check for new directories - if not list(parent.walk(PrefixMatch(dirname))): + if not list(parent.walk(util.PrefixMatch(dirname))): # check and see if the dir exists svn-side. try: assert svn.list_dir('%s/%s' % (branch_path, dirname)) diff --git a/util.py b/util.py --- a/util.py +++ b/util.py @@ -55,3 +55,13 @@ def parse_revmap(revmap_filename): raise NotImplementedError return revmap + +class PrefixMatch(object): + def __init__(self, prefix): + self.p = prefix + + def files(self): + return [] + + def __call__(self, fn): + return fn.startswith(self.p)