Mercurial > hgsubversion
comparison svnrepo.py @ 331:75f082b5897e
Switch to using url scheme wrappers instead of duplicating each command we wrap.
The 'hg svn url' command has been killed; the replacement is
'.hg/hgrc'. More stuff related to its disappearance has been stripped,
including two tests.
HgChangeReceiver now takes a UUID argument, which it uses to ensure
that remote repositories remain unchanged. This is a temporary
solution, and I'm not entirely satisfied with how it's done either.
Access to the UUID file has been isolated in a HgChangeReceiver
property.
Some more tests have been updated to use ui.pushbuffer()/popbuffer(),
and to pass through the Mercurial API.
Moved the arguments to wrappers.pull() to the UI configuration.
Also, remove HgChangeReceiver.opts in favour of a 'usebranchnames'
instance & configuration variable. The name is taken from the
ConvertExtension.
author | Dan Villiom Podlaski Christiansen <danchr@gmail.com> |
---|---|
date | Fri, 15 May 2009 19:18:43 +0200 |
parents | 48ec2d62dc29 |
children |
comparison
equal
deleted
inserted
replaced
330:5f8f2fd4fd54 | 331:75f082b5897e |
---|---|
1 """ | |
2 repository class-based interface for hgsubversion | |
3 | |
4 Copyright (C) 2009, Dan Villiom Podlaski Christiansen <danchr@gmail.com> | |
5 See parent package for licensing. | |
6 | |
7 Internally, Mercurial assumes that every single repository is a localrepository | |
8 subclass: pull() is called on the instance pull *to*, but not the one pulled | |
9 *from*. To work around this, we create two classes: | |
10 | |
11 - svnremoterepo for Subversion repositories, but it doesn't really do anything. | |
12 - svnlocalrepo for local repositories which handles both operations on itself -- | |
13 the local, hgsubversion-enabled clone -- and the remote repository. Decorators | |
14 are used to distinguish and filter these operations from others. | |
15 """ | |
16 | |
1 from mercurial import node | 17 from mercurial import node |
2 from mercurial import util as hgutil | 18 from mercurial import util as hgutil |
3 import mercurial.repo | 19 import mercurial.repo |
4 | 20 |
5 import hg_delta_editor | 21 import hg_delta_editor |
6 import util | 22 import util |
7 import wrappers | 23 import wrappers |
8 | 24 |
9 def generate_repo_class(ui, repo): | 25 def generate_repo_class(ui, repo): |
26 """ This function generates the local repository wrapper. """ | |
27 | |
10 def localsvn(fn): | 28 def localsvn(fn): |
11 ''' | 29 """ |
12 Filter for instance methods which only apply to local Subversion | 30 Filter for instance methods which only apply to local Subversion |
13 repositories. | 31 repositories. |
14 ''' | 32 """ |
15 if util.is_svn_repo(repo): | 33 if util.is_svn_repo(repo): |
16 return fn | 34 return fn |
17 else: | 35 else: |
18 original = repo.__getattribute__(fn.__name__) | 36 return getattr(repo, fn.__name__) |
19 return original | |
20 | 37 |
21 def remotesvn(fn): | 38 def remotesvn(fn): |
22 ''' | 39 """ |
23 Filter for instance methods which require the first argument | 40 Filter for instance methods which require the first argument |
24 to be a remote Subversion repository instance. | 41 to be a remote Subversion repository instance. |
25 ''' | 42 """ |
26 original = repo.__getattribute__(fn.__name__) | 43 original = getattr(repo.__class__, fn.__name__) |
27 def wrapper(self, *args, **opts): | 44 def wrapper(self, *args, **opts): |
28 if not isinstance(args[0], svnremoterepo): | 45 if 'subversion' in getattr(args[0], 'capabilities', []): |
29 return original(*args, **opts) | 46 return fn(self, *args, **opts) |
30 else: | 47 else: |
31 return fn(self, *args, **opts) | 48 return original(self, *args, **opts) |
32 wrapper.__name__ = fn.__name__ + '_wrapper' | 49 wrapper.__name__ = fn.__name__ + '_wrapper' |
33 wrapper.__doc__ = fn.__doc__ | 50 wrapper.__doc__ = fn.__doc__ |
34 return wrapper | 51 return wrapper |
35 | 52 |
36 class svnlocalrepo(repo.__class__): | 53 class svnlocalrepo(repo.__class__): |
37 @remotesvn | 54 @remotesvn |
55 def push(self, remote, force=False, revs=None): | |
56 # TODO: pass on revs | |
57 wrappers.push(self, dest=remote.svnurl, force=force, revs=None) | |
58 | |
59 @remotesvn | |
38 def pull(self, remote, heads=None, force=False): | 60 def pull(self, remote, heads=None, force=False): |
39 try: | 61 try: |
40 lock = self.wlock() | 62 lock = self.wlock() |
41 wrappers.pull(None, self.ui, self, source=remote.path, | 63 wrappers.pull(self, source=remote.svnurl, rev=heads, force=force) |
42 svn=True, rev=heads, force=force) | |
43 except KeyboardInterrupt: | 64 except KeyboardInterrupt: |
44 pass | 65 pass |
45 finally: | 66 finally: |
46 lock.release() | 67 lock.release() |
47 | 68 |
49 def tags(self): | 70 def tags(self): |
50 tags = super(svnlocalrepo, self).tags() | 71 tags = super(svnlocalrepo, self).tags() |
51 hg_editor = hg_delta_editor.HgChangeReceiver(repo=self) | 72 hg_editor = hg_delta_editor.HgChangeReceiver(repo=self) |
52 for tag, source in hg_editor.tags.iteritems(): | 73 for tag, source in hg_editor.tags.iteritems(): |
53 target = hg_editor.get_parent_revision(source[1]+1, source[0]) | 74 target = hg_editor.get_parent_revision(source[1]+1, source[0]) |
54 tags['tag/%s' % tag] = node.hex(target) | 75 tags['tag/%s' % tag] = target |
55 return tags | 76 return tags |
56 | 77 |
57 repo.__class__ = svnlocalrepo | 78 repo.__class__ = svnlocalrepo |
58 | 79 |
59 class svnremoterepo(mercurial.repo.repository): | 80 class svnremoterepo(mercurial.repo.repository): |
81 """ the dumb wrapper for actual Subversion repositories """ | |
82 | |
60 def __init__(self, ui, path): | 83 def __init__(self, ui, path): |
61 self.ui = ui | 84 self.ui = ui |
62 self.path = path | 85 self.path = path |
63 self.capabilities = set(['lookup']) | 86 self.capabilities = set(['lookup', 'subversion']) |
87 | |
88 @property | |
89 def svnurl(self): | |
90 return util.normalize_url(self.path) | |
64 | 91 |
65 def url(self): | 92 def url(self): |
66 return self.path | 93 return self.path |
67 | 94 |
68 def lookup(self, key): | 95 def lookup(self, key): |
80 | 107 |
81 def instance(ui, url, create): | 108 def instance(ui, url, create): |
82 if create: | 109 if create: |
83 raise hgutil.Abort('cannot create new remote Subversion repository') | 110 raise hgutil.Abort('cannot create new remote Subversion repository') |
84 | 111 |
85 if url.startswith('svn+') and not url.startswith('svn+ssh:'): | 112 return svnremoterepo(ui, url) |
86 url = url[4:] | |
87 return svnremoterepo(ui, util.normalize_url(url)) |