comparison svncommands.py @ 256:7932d098cb5f

Refactor commands to wrap their hg equivalent adding a --svn flag where sane.
author Augie Fackler <durin42@gmail.com>
date Fri, 10 Apr 2009 18:47:18 -0500
parents 246aaefb1cc0
children ffccf0080e54
comparison
equal deleted inserted replaced
255:246aaefb1cc0 256:7932d098cb5f
1 import os 1 import os
2 import cPickle as pickle 2 import cPickle as pickle
3 3
4 from mercurial import cmdutil as hgcmdutil
5 from mercurial import commands
4 from mercurial import hg 6 from mercurial import hg
5 from mercurial import node 7 from mercurial import node
6 from mercurial import patch 8 from mercurial import patch
7 from mercurial import util as hgutil 9 from mercurial import util as hgutil
8 10
15 import cmdutil 17 import cmdutil
16 import util 18 import util
17 import utility_commands 19 import utility_commands
18 20
19 21
20 def pull(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None, 22 def clone(orig, ui, source, dest=None, **opts):
21 tag_locations='tags', authors=None, filemap=None, **opts): 23 '''clone Subversion repository to a local Mercurial repository.
24
25 If no destination directory name is specified, it defaults to the
26 basename of the source plus "-hg".
27
28 You can specify multiple paths for the location of tags using comma
29 separated values.
30 '''
31 svnurl = ui.expandpath(source)
32 if not cmdutil.issvnurl(svnurl):
33 orig(ui, repo, source=source, dest=dest, *args, **opts)
34
35 if not dest:
36 dest = hg.defaultdest(source) + '-hg'
37 ui.status("Assuming destination %s\n" % dest)
38
39 if os.path.exists(dest):
40 raise hgutil.Abort("destination '%s' already exists" % dest)
41 url = util.normalize_url(svnurl)
42 res = -1
43 try:
44 try:
45 res = pull(None, ui, None, True, opts.pop('svn_stupid', False),
46 source=url, create_new_dest=dest, **opts)
47 except core.SubversionException, e:
48 if e.apr_err == core.SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED:
49 raise hgutil.Abort('It appears svn does not trust the ssl cert for this site.\n'
50 'Please try running svn ls on that url first.')
51 raise
52 finally:
53 if os.path.exists(dest):
54 repo = hg.repository(ui, dest)
55 fp = repo.opener("hgrc", "w", text=True)
56 fp.write("[paths]\n")
57 # percent needs to be escaped for ConfigParser
58 fp.write("default = %(url)s\nsvn = %(url)s\n" % {'url': svnurl.replace('%', '%%')})
59 fp.close()
60 if res is None or res == 0:
61 commands.update(ui, repo, repo['tip'].node())
62
63 return res
64
65
66 def pull(orig, ui, repo, svn=None, svn_stupid=False, source="default", create_new_dest=False,
67 *args, **opts):
22 """pull new revisions from Subversion 68 """pull new revisions from Subversion
23 """ 69 """
70 url = ui.expandpath(source)
71 if not (cmdutil.issvnurl(url) or svn or create_new_dest):
72 orig(ui, repo, source=source, *args, **opts)
73 svn_url = url
24 svn_url = util.normalize_url(svn_url) 74 svn_url = util.normalize_url(svn_url)
25 old_encoding = util.swap_out_encoding() 75 old_encoding = util.swap_out_encoding()
26 skipto_rev=int(skipto_rev) 76 # TODO implement skipto support
27 have_replay = not stupid 77 skipto_rev = 0
78 have_replay = not svn_stupid
28 if have_replay and not callable( 79 if have_replay and not callable(
29 delta.svn_txdelta_apply(None, None, None)[0]): #pragma: no cover 80 delta.svn_txdelta_apply(None, None, None)[0]): #pragma: no cover
30 ui.status('You are using old Subversion SWIG bindings. Replay will not' 81 ui.status('You are using old Subversion SWIG bindings. Replay will not'
31 ' work until you upgrade to 1.5.0 or newer. Falling back to' 82 ' work until you upgrade to 1.5.0 or newer. Falling back to'
32 ' a slower method that may be buggier. Please upgrade, or' 83 ' a slower method that may be buggier. Please upgrade, or'
36 initializing_repo = False 87 initializing_repo = False
37 user = opts.get('username', hgutil.getuser()) 88 user = opts.get('username', hgutil.getuser())
38 passwd = opts.get('password', '') 89 passwd = opts.get('password', '')
39 svn = svnwrap.SubversionRepo(svn_url, user, passwd) 90 svn = svnwrap.SubversionRepo(svn_url, user, passwd)
40 author_host = "@%s" % svn.uuid 91 author_host = "@%s" % svn.uuid
41 tag_locations = tag_locations.split(',') 92 # TODO these should be configurable again, but I'm torn on how.
42 hg_editor = hg_delta_editor.HgChangeReceiver(hg_repo_path, 93 # Maybe this should be configured in .hg/hgrc for each repo? Seems vaguely reasonable.
43 ui_=ui, 94 tag_locations = ['tags', ]
44 subdir=svn.subdir, 95 authors = None
45 author_host=author_host, 96 filemap = None
46 tag_locations=tag_locations, 97 if repo:
47 authors=authors, 98 hg_editor = hg_delta_editor.HgChangeReceiver(repo=repo)
48 filemap=filemap) 99 else:
100 hg_editor = hg_delta_editor.HgChangeReceiver(ui_=ui,
101 path=create_new_dest,
102 subdir=svn.subdir,
103 author_host=author_host,
104 tag_locations=tag_locations,
105 authors=authors,
106 filemap=filemap)
49 if os.path.exists(hg_editor.uuid_file): 107 if os.path.exists(hg_editor.uuid_file):
50 uuid = open(hg_editor.uuid_file).read() 108 uuid = open(hg_editor.uuid_file).read()
51 assert uuid == svn.uuid 109 assert uuid == svn.uuid
52 start = hg_editor.last_known_revision() 110 start = hg_editor.last_known_revision()
53 else: 111 else:
144 l1 = label+':' 202 l1 = label+':'
145 ui.status('%s%s\n' % (l1.ljust(13), 203 ui.status('%s%s\n' % (l1.ljust(13),
146 str(r.__getattribute__(attr)).strip(), )) 204 str(r.__getattribute__(attr)).strip(), ))
147 205
148 206
149 def push(ui, repo, hg_repo_path, svn_url, stupid=False, **opts): 207 def push(orig, ui, repo, dest=None, **opts):
150 """push revisions starting at a specified head back to Subversion. 208 """push revisions starting at a specified head back to Subversion.
151 """ 209 """
210 svnurl = ui.expandpath(dest or 'default-push', dest or 'default')
211 if not cmdutil.issvnurl(svnurl):
212 orig(ui, repo, dest=dest, *args, **opts)
152 old_encoding = util.swap_out_encoding() 213 old_encoding = util.swap_out_encoding()
153 hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, 214 hge = hg_delta_editor.HgChangeReceiver(repo=repo)
154 ui_=ui) 215 assert svnurl == hge.url
155 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), 216 svn_commit_hashes = dict(zip(hge.revmap.itervalues(),
156 hge.revmap.iterkeys())) 217 hge.revmap.iterkeys()))
157 user = opts.get('username', hgutil.getuser()) 218 user = opts.get('username', hgutil.getuser())
158 passwd = opts.get('password', '') 219 passwd = opts.get('password', '')
159 220
185 samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch 246 samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch
186 and c.node() in svn_commit_hashes] 247 and c.node() in svn_commit_hashes]
187 # 2. Commit oldest revision that needs to be pushed 248 # 2. Commit oldest revision that needs to be pushed
188 base_revision = svn_commit_hashes[base_n][0] 249 base_revision = svn_commit_hashes[base_n][0]
189 try: 250 try:
190 cmdutil.commit_from_rev(ui, repo, old_ctx, hge, svn_url, 251 cmdutil.commit_from_rev(ui, repo, old_ctx, hge, svnurl,
191 base_revision, user, passwd) 252 base_revision, user, passwd)
192 except cmdutil.NoFilesException: 253 except cmdutil.NoFilesException:
193 ui.warn("Could not push revision %s because it had no changes in svn.\n" % 254 ui.warn("Could not push revision %s because it had no changes in svn.\n" %
194 old_ctx) 255 old_ctx)
195 return 1 256 return 1
196 # 3. Fetch revisions from svn 257 # 3. Fetch revisions from svn
197 r = pull(ui, svn_url, hg_repo_path, stupid=stupid, 258 r = pull(None, ui, repo, True, stupid=opts.get('svn_stupid', False),
198 username=user, password=passwd) 259 username=user, password=passwd)
199 assert not r or r == 0 260 assert not r or r == 0
200 # 4. Find the new head of the target branch 261 # 4. Find the new head of the target branch
201 repo = hg.repository(ui, hge.path) 262 repo = hg.repository(ui, hge.path)
202 oldtipctx = repo[oldtip] 263 oldtipctx = repo[oldtip]
223 [child.node(), ] + outgoing[rebsrcindex+1:]) 284 [child.node(), ] + outgoing[rebsrcindex+1:])
224 children = [c for c in child.children() if c.branch() == child.branch()] 285 children = [c for c in child.children() if c.branch() == child.branch()]
225 if children: 286 if children:
226 child = children[0] 287 child = children[0]
227 rebasesrc = node.bin(child.extra().get('rebase_source', node.hex(node.nullid))) 288 rebasesrc = node.bin(child.extra().get('rebase_source', node.hex(node.nullid)))
228 hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, ui_=ui) 289 hge = hg_delta_editor.HgChangeReceiver(hge.path, ui_=ui)
229 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys())) 290 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys()))
230 util.swap_out_encoding(old_encoding) 291 util.swap_out_encoding(old_encoding)
231 return 0 292 return 0
232 293
233 294
234 def diff(ui, repo, hg_repo_path, **opts): 295 def diff(orig, ui, repo, *args, **opts):
235 """show a diff of the most recent revision against its parent from svn 296 """show a diff of the most recent revision against its parent from svn
236 """ 297 """
237 hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, 298 if not opts.get('svn', False) or opts.get('change', None):
238 ui_=ui) 299 return orig(ui, repo, *args, **opts)
300 svn_commit_hashes = {}
301 hge = hg_delta_editor.HgChangeReceiver(repo=repo)
239 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), 302 svn_commit_hashes = dict(zip(hge.revmap.itervalues(),
240 hge.revmap.iterkeys())) 303 hge.revmap.iterkeys()))
241 parent = repo.parents()[0] 304 if not opts.get('rev', None):
242 o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes, parent.node()) 305 parent = repo.parents()[0]
243 if o_r: 306 o_r = util.outgoing_revisions(ui, repo, hge, svn_commit_hashes,
244 parent = repo[o_r[-1]].parents()[0] 307 parent.node())
245 base_rev, _junk = svn_commit_hashes[parent.node()] 308 if o_r:
246 it = patch.diff(repo, parent.node(), None, 309 parent = repo[o_r[-1]].parents()[0]
310 opts['rev'] = ['%s:.' % node.hex(parent.node()), ]
311 node1, node2 = hgcmdutil.revpair(repo, opts['rev'])
312 baserev, _junk = svn_commit_hashes.get(node1, (-1, 'junk', ))
313 newrev, _junk = svn_commit_hashes.get(node2, (-1, 'junk', ))
314 it = patch.diff(repo, node1, node2,
247 opts=patch.diffopts(ui, opts={'git': True, 315 opts=patch.diffopts(ui, opts={'git': True,
248 'show_function': False, 316 'show_function': False,
249 'ignore_all_space': False, 317 'ignore_all_space': False,
250 'ignore_space_change': False, 318 'ignore_space_change': False,
251 'ignore_blank_lines': False, 319 'ignore_blank_lines': False,
252 'unified': True, 320 'unified': True,
253 'text': False, 321 'text': False,
254 })) 322 }))
255 ui.write(cmdutil.filterdiff(''.join(it), base_rev)) 323 ui.write(cmdutil.filterdiff(''.join(it), baserev, newrev))
256 324
257 325
258 def rebuildmeta(ui, repo, hg_repo_path, args, **opts): 326 def rebuildmeta(ui, repo, hg_repo_path, args, **opts):
259 """rebuild hgsubversion metadata using values stored in revisions 327 """rebuild hgsubversion metadata using values stored in revisions
260 """ 328 """
418 return 1 486 return 1
419 487
420 488
421 nourl = ['rebuildmeta'] + utility_commands.nourl 489 nourl = ['rebuildmeta'] + utility_commands.nourl
422 table = { 490 table = {
423 'pull': pull,
424 'push': push,
425 'dcommit': push,
426 'update': update, 491 'update': update,
427 'help': help, 492 'help': help,
428 'rebuildmeta': rebuildmeta, 493 'rebuildmeta': rebuildmeta,
429 'diff': diff,
430 'incoming': incoming, 494 'incoming': incoming,
431 } 495 }
432 496
433 table.update(utility_commands.table) 497 table.update(utility_commands.table)
434 498