Mercurial > hgsubversion
diff utility_commands.py @ 0:f2636cfed115
Initial import of hgsubversion into a public repository.
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Tue, 30 Sep 2008 11:42:52 -0500 |
parents | |
children | 05800c403321 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/utility_commands.py @@ -0,0 +1,106 @@ +from mercurial import cmdutil +from mercurial import node +from hgext import rebase + +import util +import hg_delta_editor + +@util.register_subcommand('url') +def print_wc_url(ui, repo, hg_repo_path, **opts): + hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, + ui_=ui) + ui.status(hge.url, '\n') + + +@util.register_subcommand('parent') +def print_parent_revision(ui, repo, hg_repo_path, **opts): + """Prints the hg hash and svn revision info for the nearest svn parent of + the current revision""" + hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, + ui_=ui) + svn_commit_hashes = dict(zip(hge.revmap.itervalues(), + hge.revmap.iterkeys())) + ha = repo.parents()[0] + o_r = outgoing_revisions(ui, repo, hge, svn_commit_hashes) + if o_r: + ha = repo[o_r[-1]].parents()[0] + if ha.node() != node.nullid: + r, br = svn_commit_hashes[ha.node()] + ui.status('Working copy parent revision is %s: r%s on %s\n' % + (ha, r, br or 'trunk')) + else: + ui.status('Working copy seems to have no parent svn revision.\n') + return 0 + + +@util.register_subcommand('rebase') +def rebase_commits(ui, repo, hg_repo_path, **opts): + """Rebases the current uncommitted revisions onto the top of the branch. + """ + hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, + ui_=ui) + svn_commit_hashes = dict(zip(hge.revmap.itervalues(), + hge.revmap.iterkeys())) + o_r = outgoing_revisions(ui, repo, hge, svn_commit_hashes) + if not o_r: + ui.status('Nothing to rebase!\n') + return 0 + if len(repo.parents()[0].children()): + ui.status('Refusing to rebase non-head commit like a coward\n') + return 0 + parent_rev = repo[o_r[-1]].parents()[0] + target_rev = parent_rev + p_n = parent_rev.node() + exhausted_choices = False + while target_rev.children() and not exhausted_choices: + for c in target_rev.children(): + exhausted_choices = True + n = c.node() + if (n in svn_commit_hashes and + svn_commit_hashes[n][1] == svn_commit_hashes[p_n][1]): + target_rev = c + exhausted_choices = False + break + if parent_rev == target_rev: + ui.status('Already up to date!\n') + 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())) + + +@util.register_subcommand('outgoing') +def show_outgoing_to_svn(ui, repo, hg_repo_path, **opts): + """Commit the current revision and any required parents back to svn. + """ + hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, + ui_=ui) + svn_commit_hashes = dict(zip(hge.revmap.itervalues(), + hge.revmap.iterkeys())) + o_r = outgoing_revisions(ui, repo, hge, svn_commit_hashes) + if not (o_r and len(o_r)): + ui.status('No outgoing changes found.\n') + return 0 + displayer = cmdutil.show_changeset(ui, repo, opts, buffered=False) + for rev in reversed(o_r): + displayer.show(changenode=rev) + + +def outgoing_revisions(ui, repo, hg_editor, reverse_map): + """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: + 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: + return outgoing_rev_hashes