Mercurial > hgsubversion
diff svncommands.py @ 242:06130689a2c8
Move push into svncommands.
author | Dirkjan Ochtman <dirkjan@ochtman.nl> |
---|---|
date | Wed, 08 Apr 2009 17:53:48 +0200 |
parents | 4950b18cf949 |
children | 28d0ee605308 |
line wrap: on
line diff
--- a/svncommands.py +++ b/svncommands.py @@ -1,6 +1,9 @@ import os +from mercurial import hg +from mercurial import node from mercurial import util as hgutil + from svn import core from svn import delta @@ -9,6 +12,7 @@ import svnwrap import stupid as stupidmod import cmdutil import util +import utility_commands def pull(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None, @@ -91,3 +95,93 @@ def pull(ui, svn_url, hg_repo_path, skip util.swap_out_encoding(old_encoding) pull = util.register_subcommand('pull')(pull) + + +def push(ui, repo, hg_repo_path, svn_url, stupid=False, **opts): + """push revisions starting at a specified head back to Subversion. + """ + old_encoding = util.swap_out_encoding() + hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, + ui_=ui) + svn_commit_hashes = dict(zip(hge.revmap.itervalues(), + hge.revmap.iterkeys())) + user = opts.get('username', hgutil.getuser()) + passwd = opts.get('password', '') + + # Strategy: + # 1. Find all outgoing commits from this head + 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] + if len(old_ctx.parents()) != 1: + ui.status('Found a branch merge, this needs discussion and ' + 'implementation.') + return 1 + base_n = old_ctx.parents()[0].node() + old_children = repo[base_n].children() + svnbranch = repo[base_n].branch() + oldtip = base_n + samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch + and c.node() in svn_commit_hashes] + while samebranchchildren: + oldtip = samebranchchildren[0].node() + samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch + and c.node() in svn_commit_hashes] + # 2. Commit oldest revision that needs to be pushed + base_revision = svn_commit_hashes[base_n][0] + try: + cmdutil.commit_from_rev(ui, repo, old_ctx, hge, svn_url, + base_revision, user, passwd) + except cmdutil.NoFilesException: + ui.warn("Could not push revision %s because it had no changes in svn.\n" % + old_ctx) + return 1 + # 3. Fetch revisions from svn + r = pull(ui, svn_url, hg_repo_path, stupid=stupid, + username=user, password=passwd) + assert not r or r == 0 + # 4. Find the new head of the target branch + repo = hg.repository(ui, hge.path) + oldtipctx = repo[oldtip] + replacement = [c for c in oldtipctx.children() if c not in old_children + and c.branch() == oldtipctx.branch()] + assert len(replacement) == 1, 'Replacement node came back as: %r' % replacement + replacement = replacement[0] + # 5. Rebase all children of the currently-pushing rev to the new branch + heads = repo.heads(old_ctx.node()) + for needs_transplant in heads: + def extrafn(ctx, extra): + if ctx.node() == oldest: + return + extra['branch'] = ctx.branch() + utility_commands.rebase_commits(ui, repo, + 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: + 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())) + util.swap_out_encoding(old_encoding) + return 0 +push = util.register_subcommand('push')(push) +# for git expats +dcommit = util.register_subcommand('dcommit')(push)