# HG changeset patch # User Augie Fackler # Date 1230002531 21600 # Node ID 1fde85a10f9e32af2bc1848c221d54734afa1ca6 # Parent 2decec74ad0c0a1028a7248d1fffe54138f2a065 push: Fix the bad implementation that required modifying the dirstate to push. diff --git a/diff_cmd.py b/diff_cmd.py --- a/diff_cmd.py +++ b/diff_cmd.py @@ -32,8 +32,8 @@ def diff_command(ui, repo, hg_repo_path, ui_=ui) svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys())) - o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes) parent = repo.parents()[0] + o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes, parent.node()) if o_r: parent = repo[o_r[-1]].parents()[0] base_rev, _junk = svn_commit_hashes[parent.node()] diff --git a/push_cmd.py b/push_cmd.py --- a/push_cmd.py +++ b/push_cmd.py @@ -24,13 +24,14 @@ def push_revisions_to_subversion(ui, rep hge.revmap.iterkeys())) # Strategy: # 1. Find all outgoing commits from this head - outgoing = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes) - if not (outgoing and len(outgoing)): - ui.status('No revisions to push.') - return 0 if len(repo.parents()) != 1: ui.status('Cowardly refusing to push branch merge') return 1 + workingrev = repo.parents()[0] + outgoing = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes, workingrev.node()) + if not (outgoing and len(outgoing)): + ui.status('No revisions to push.') + return 0 while outgoing: oldest = outgoing.pop(-1) old_ctx = repo[oldest] @@ -69,14 +70,22 @@ def push_revisions_to_subversion(ui, rep if ctx.node() == oldest: return extra['branch'] = ctx.branch() - hg.clean(repo, needs_transplant) - utility_commands.rebase_commits(ui, repo, hg_repo_path, extrafn=extrafn, **opts) + utility_commands.rebase_commits(ui, repo, hg_repo_path, + extrafn=extrafn, + sourcerev=needs_transplant, + **opts) repo = hg.repository(ui, hge.path) for child in repo[replacement.node()].children(): rebasesrc = node.bin(child.extra().get('rebase_source', node.hex(node.nullid))) if rebasesrc in outgoing: - rebsrcindex = outgoing.index(rebasesrc) - outgoing = outgoing[0:rebsrcindex] + [child.node(), ] + outgoing[rebsrcindex+1:] + while rebasesrc in outgoing: + rebsrcindex = outgoing.index(rebasesrc) + outgoing = (outgoing[0:rebsrcindex] + + [child.node(), ] + outgoing[rebsrcindex+1:]) + children = [c for c in child.children() if c.branch() == child.branch()] + if children: + child = children[0] + rebasesrc = node.bin(child.extra().get('rebase_source', node.hex(node.nullid))) hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, ui_=ui) svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys())) merc_util._encoding = oldencoding diff --git a/util.py b/util.py --- a/util.py +++ b/util.py @@ -82,23 +82,21 @@ class PrefixMatch(object): def __call__(self, fn): return fn.startswith(self.p) -def outgoing_revisions(ui, repo, hg_editor, reverse_map): +def outgoing_revisions(ui, repo, hg_editor, reverse_map, sourcerev): """Given a repo and an hg_editor, determines outgoing revisions for the current working copy state. """ outgoing_rev_hashes = [] - working_rev = repo.parents() - assert len(working_rev) == 1 - working_rev = working_rev[0] - if working_rev.node() in reverse_map: + if sourcerev in reverse_map: return - while (not working_rev.node() in reverse_map - and working_rev.node() != node.nullid): - outgoing_rev_hashes.append(working_rev.node()) - working_rev = working_rev.parents() - assert len(working_rev) == 1 - working_rev = working_rev[0] - if working_rev.node() != node.nullid: + sourcerev = repo[sourcerev] + while (not sourcerev.node() in reverse_map + and sourcerev.node() != node.nullid): + outgoing_rev_hashes.append(sourcerev.node()) + sourcerev = sourcerev.parents() + assert len(sourcerev) == 1 + sourcerev = sourcerev[0] + if sourcerev.node() != node.nullid: return outgoing_rev_hashes diff --git a/utility_commands.py b/utility_commands.py --- a/utility_commands.py +++ b/utility_commands.py @@ -23,11 +23,11 @@ def run_svn_info(ui, repo, hg_repo_path, ui_=ui) svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys())) - o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes) - ha = repo.parents()[0] + workingctx = repo.parents()[0] + o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes, workingctx.node()) if o_r: - ha = repo[o_r[-1]].parents()[0] - r, br = svn_commit_hashes[ha.node()] + workingctx = repo[o_r[-1]].parents()[0] + r, br = svn_commit_hashes[workingctx.node()] if br == None: branchpath = '/trunk' else: @@ -36,7 +36,7 @@ def run_svn_info(ui, repo, hg_repo_path, if url[-1] == '/': url = url[:-1] url = '%s%s' % (url, branchpath) - author = '@'.join(ha.user().split('@')[:-1]) + author = '@'.join(workingctx.user().split('@')[:-1]) ui.status('''URL: %(url)s Repository Root: %(reporoot)s Repository UUID: %(uuid)s @@ -51,7 +51,7 @@ Last Changed Date: %(date)s\n''' % 'author': author, 'revision': r, # TODO I'd like to format this to the user's local TZ if possible - 'date': mutil.datestr(ha.date(), + 'date': mutil.datestr(workingctx.date(), '%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)') }) @@ -65,7 +65,7 @@ def print_parent_revision(ui, repo, hg_r svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys())) ha = repo.parents()[0] - o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes) + o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes, ha.node()) if o_r: ha = repo[o_r[-1]].parents()[0] if ha.node() != node.nullid: @@ -78,7 +78,7 @@ def print_parent_revision(ui, repo, hg_r @util.register_subcommand('rebase') -def rebase_commits(ui, repo, hg_repo_path, extrafn=None, **opts): +def rebase_commits(ui, repo, hg_repo_path, extrafn=None, sourcerev=None, **opts): """Rebases current unpushed revisions onto Subversion head This moves a line of development from making its own head to the top of @@ -92,15 +92,17 @@ def rebase_commits(ui, repo, hg_repo_pat """ extra['branch'] = ctx.branch() extrafn = extrafn2 + if sourcerev is None: + sourcerev = repo.parents()[0].node() hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, ui_=ui) svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys())) - o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes) + o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes, sourcerev=sourcerev) if not o_r: ui.status('Nothing to rebase!\n') return 0 - if len(repo.parents()[0].children()): + if len(repo[sourcerev].children()): ui.status('Refusing to rebase non-head commit like a coward\n') return 0 parent_rev = repo[o_r[-1]].parents()[0] @@ -121,7 +123,7 @@ def rebase_commits(ui, repo, hg_repo_pat return 0 # TODO this is really hacky, there must be a more direct way return rebase.rebase(ui, repo, dest=node.hex(target_rev.node()), - base=node.hex(repo.parents()[0].node()), + base=node.hex(sourcerev), extrafn=extrafn) @@ -133,7 +135,7 @@ def show_outgoing_to_svn(ui, repo, hg_re ui_=ui) svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys())) - o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes) + o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes, repo.parents()[0]) if not (o_r and len(o_r)): ui.status('No outgoing changes found.\n') return 0