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) |