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