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)