Mercurial > hgsubversion
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 241:4950b18cf949 | 242:06130689a2c8 |
|---|---|
| 1 import os | 1 import os |
| 2 | 2 |
| 3 from mercurial import hg | |
| 4 from mercurial import node | |
| 3 from mercurial import util as hgutil | 5 from mercurial import util as hgutil |
| 6 | |
| 4 from svn import core | 7 from svn import core |
| 5 from svn import delta | 8 from svn import delta |
| 6 | 9 |
| 7 import hg_delta_editor | 10 import hg_delta_editor |
| 8 import svnwrap | 11 import svnwrap |
| 9 import stupid as stupidmod | 12 import stupid as stupidmod |
| 10 import cmdutil | 13 import cmdutil |
| 11 import util | 14 import util |
| 15 import utility_commands | |
| 12 | 16 |
| 13 | 17 |
| 14 def pull(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None, | 18 def pull(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None, |
| 15 tag_locations='tags', authors=None, filemap=None, **opts): | 19 tag_locations='tags', authors=None, filemap=None, **opts): |
| 16 """pull new revisions from Subversion | 20 """pull new revisions from Subversion |
| 89 else: | 93 else: |
| 90 raise hgutil.Abort(*e.args) | 94 raise hgutil.Abort(*e.args) |
| 91 util.swap_out_encoding(old_encoding) | 95 util.swap_out_encoding(old_encoding) |
| 92 | 96 |
| 93 pull = util.register_subcommand('pull')(pull) | 97 pull = util.register_subcommand('pull')(pull) |
| 98 | |
| 99 | |
| 100 def push(ui, repo, hg_repo_path, svn_url, stupid=False, **opts): | |
| 101 """push revisions starting at a specified head back to Subversion. | |
| 102 """ | |
| 103 old_encoding = util.swap_out_encoding() | |
| 104 hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, | |
| 105 ui_=ui) | |
| 106 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), | |
| 107 hge.revmap.iterkeys())) | |
| 108 user = opts.get('username', hgutil.getuser()) | |
| 109 passwd = opts.get('password', '') | |
| 110 | |
| 111 # Strategy: | |
| 112 # 1. Find all outgoing commits from this head | |
| 113 if len(repo.parents()) != 1: | |
| 114 ui.status('Cowardly refusing to push branch merge') | |
| 115 return 1 | |
| 116 workingrev = repo.parents()[0] | |
| 117 outgoing = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes, workingrev.node()) | |
| 118 if not (outgoing and len(outgoing)): | |
| 119 ui.status('No revisions to push.') | |
| 120 return 0 | |
| 121 while outgoing: | |
| 122 oldest = outgoing.pop(-1) | |
| 123 old_ctx = repo[oldest] | |
| 124 if len(old_ctx.parents()) != 1: | |
| 125 ui.status('Found a branch merge, this needs discussion and ' | |
| 126 'implementation.') | |
| 127 return 1 | |
| 128 base_n = old_ctx.parents()[0].node() | |
| 129 old_children = repo[base_n].children() | |
| 130 svnbranch = repo[base_n].branch() | |
| 131 oldtip = base_n | |
| 132 samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch | |
| 133 and c.node() in svn_commit_hashes] | |
| 134 while samebranchchildren: | |
| 135 oldtip = samebranchchildren[0].node() | |
| 136 samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch | |
| 137 and c.node() in svn_commit_hashes] | |
| 138 # 2. Commit oldest revision that needs to be pushed | |
| 139 base_revision = svn_commit_hashes[base_n][0] | |
| 140 try: | |
| 141 cmdutil.commit_from_rev(ui, repo, old_ctx, hge, svn_url, | |
| 142 base_revision, user, passwd) | |
| 143 except cmdutil.NoFilesException: | |
| 144 ui.warn("Could not push revision %s because it had no changes in svn.\n" % | |
| 145 old_ctx) | |
| 146 return 1 | |
| 147 # 3. Fetch revisions from svn | |
| 148 r = pull(ui, svn_url, hg_repo_path, stupid=stupid, | |
| 149 username=user, password=passwd) | |
| 150 assert not r or r == 0 | |
| 151 # 4. Find the new head of the target branch | |
| 152 repo = hg.repository(ui, hge.path) | |
| 153 oldtipctx = repo[oldtip] | |
| 154 replacement = [c for c in oldtipctx.children() if c not in old_children | |
| 155 and c.branch() == oldtipctx.branch()] | |
| 156 assert len(replacement) == 1, 'Replacement node came back as: %r' % replacement | |
| 157 replacement = replacement[0] | |
| 158 # 5. Rebase all children of the currently-pushing rev to the new branch | |
| 159 heads = repo.heads(old_ctx.node()) | |
| 160 for needs_transplant in heads: | |
| 161 def extrafn(ctx, extra): | |
| 162 if ctx.node() == oldest: | |
| 163 return | |
| 164 extra['branch'] = ctx.branch() | |
| 165 utility_commands.rebase_commits(ui, repo, | |
| 166 extrafn=extrafn, | |
| 167 sourcerev=needs_transplant, | |
| 168 **opts) | |
| 169 repo = hg.repository(ui, hge.path) | |
| 170 for child in repo[replacement.node()].children(): | |
| 171 rebasesrc = node.bin(child.extra().get('rebase_source', node.hex(node.nullid))) | |
| 172 if rebasesrc in outgoing: | |
| 173 while rebasesrc in outgoing: | |
| 174 rebsrcindex = outgoing.index(rebasesrc) | |
| 175 outgoing = (outgoing[0:rebsrcindex] + | |
| 176 [child.node(), ] + outgoing[rebsrcindex+1:]) | |
| 177 children = [c for c in child.children() if c.branch() == child.branch()] | |
| 178 if children: | |
| 179 child = children[0] | |
| 180 rebasesrc = node.bin(child.extra().get('rebase_source', node.hex(node.nullid))) | |
| 181 hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, ui_=ui) | |
| 182 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys())) | |
| 183 util.swap_out_encoding(old_encoding) | |
| 184 return 0 | |
| 185 push = util.register_subcommand('push')(push) | |
| 186 # for git expats | |
| 187 dcommit = util.register_subcommand('dcommit')(push) |
