/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to __init__.py

Register lazily where possible.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2009 Canonical Ltd
2
 
 
 
1
# Copyright (C) 2006 Canonical Ltd
3
2
# Authors: Robert Collins <robert.collins@canonical.com>
4
3
#          Jelmer Vernooij <jelmer@samba.org>
5
4
#          John Carr <john.carr@unrouted.co.uk>
21
20
 
22
21
"""A GIT branch and repository format implementation for bzr."""
23
22
 
24
 
import os
25
 
import sys
26
 
 
27
23
import bzrlib
28
24
import bzrlib.api
29
 
from bzrlib import (
30
 
    bzrdir,
31
 
    errors as bzr_errors,
32
 
    )
33
 
from bzrlib.foreign import (
34
 
    foreign_vcs_registry,
35
 
    )
36
 
from bzrlib.lockable_files import (
37
 
    TransportLock,
38
 
    )
39
 
from bzrlib.transport import (
40
 
    register_lazy_transport,
41
 
    register_transport_proto,
42
 
    )
43
 
from bzrlib.commands import (
44
 
    plugin_cmds,
45
 
    )
46
 
from bzrlib.trace import (
47
 
    warning,
48
 
    )
49
 
 
50
 
# versions ending in 'exp' mean experimental mappings
51
 
# versions ending in 'dev' mean development version
52
 
# versions ending in 'final' mean release (well tested, etc)
53
 
version_info = (0, 2, 0, 'dev', 0)
54
 
 
55
 
if version_info[3] == 'final':
56
 
    version_string = '%d.%d.%d' % version_info[:3]
57
 
else:
58
 
    version_string = '%d.%d.%d%s%d' % version_info
59
 
__version__ = version_string
60
 
 
61
 
MINIMUM_DULWICH_VERSION = (0, 1, 1)
62
 
COMPATIBLE_BZR_VERSIONS = [(1, 13, 0)]
63
 
 
64
 
if getattr(sys, "frozen", None):
65
 
    # allow import additional libs from ./_lib for bzr.exe only
66
 
    sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__), '_lib')))
 
25
from bzrlib import bzrdir
 
26
from bzrlib.foreign import foreign_vcs_registry
 
27
from bzrlib.transport import register_lazy_transport
 
28
from bzrlib.commands import Command, register_command
 
29
from bzrlib.option import Option
 
30
from bzrlib.trace import warning
 
31
 
 
32
MINIMUM_DULWICH_VERSION = (0, 1, 0)
 
33
COMPATIBLE_BZR_VERSIONS = [(1, 12, 0)]
67
34
 
68
35
_versions_checked = False
69
36
def lazy_check_versions():
74
41
    try:
75
42
        from dulwich import __version__ as dulwich_version
76
43
    except ImportError:
77
 
        raise ImportError("bzr-git: Please install dulwich, https://launchpad.net/dulwich")
 
44
        warning("Please install dulwich, https://launchpad.net/dulwich")
 
45
        raise
78
46
    else:
79
47
        if dulwich_version < MINIMUM_DULWICH_VERSION:
80
 
            raise ImportError("bzr-git: Dulwich is too old; at least %d.%d.%d is required" % MINIMUM_DULWICH_VERSION)
 
48
            warning("Dulwich is too old; at least %d.%d.%d is required" % MINIMUM_DULWICH_VERSION)
 
49
            raise ImportError
81
50
 
82
51
bzrlib.api.require_any_api(bzrlib, COMPATIBLE_BZR_VERSIONS)
83
52
 
86
55
    help='GIT repository.', native=False, experimental=True,
87
56
    )
88
57
 
89
 
from bzrlib.revisionspec import revspec_registry
90
 
revspec_registry.register_lazy("git:", "bzrlib.plugins.git.revspec", 
91
 
    "RevisionSpec_git")
92
 
 
93
 
class GitBzrDirFormat(bzrdir.BzrDirFormat):
94
 
    _lock_class = TransportLock
95
 
 
96
 
    def is_supported(self):
97
 
        return True
98
 
 
99
 
 
100
 
class LocalGitBzrDirFormat(GitBzrDirFormat):
101
 
    """The .git directory control format."""
102
 
 
103
 
    @classmethod
104
 
    def _known_formats(self):
105
 
        return set([LocalGitBzrDirFormat()])
106
 
 
107
 
    def open(self, transport, _found=None):
108
 
        """Open this directory.
109
 
 
110
 
        """
111
 
        import dulwich as git
112
 
        # we dont grok readonly - git isn't integrated with transport.
113
 
        url = transport.base
114
 
        if url.startswith('readonly+'):
115
 
            url = url[len('readonly+'):]
116
 
 
117
 
        try:
118
 
            gitrepo = git.repo.Repo(transport.local_abspath("."))
119
 
        except bzr_errors.NotLocalUrl:
120
 
            raise bzr_errors.NotBranchError(path=transport.base)
121
 
        from bzrlib.plugins.git.dir import LocalGitDir, GitLockableFiles, GitLock
122
 
        lockfiles = GitLockableFiles(transport, GitLock())
123
 
        return LocalGitDir(transport, lockfiles, gitrepo, self)
124
 
 
125
 
    @classmethod
126
 
    def probe_transport(klass, transport):
127
 
        """Our format is present if the transport ends in '.not/'."""
128
 
        from bzrlib.transport.local import LocalTransport
129
 
 
130
 
        if not isinstance(transport, LocalTransport):
131
 
            raise bzr_errors.NotBranchError(path=transport.base)
132
 
 
133
 
        # This should quickly filter out most things that are not 
134
 
        # git repositories, saving us the trouble from loading dulwich.
135
 
        if not transport.has(".git") and not transport.has("objects"):
136
 
            raise bzr_errors.NotBranchError(path=transport.base)
137
 
 
138
 
        import dulwich as git
139
 
        format = klass()
140
 
        try:
141
 
            format.open(transport)
142
 
            return format
143
 
        except git.errors.NotGitRepository, e:
144
 
            raise bzr_errors.NotBranchError(path=transport.base)
145
 
        raise bzr_errors.NotBranchError(path=transport.base)
146
 
 
147
 
    def get_format_description(self):
148
 
        return "Local Git Repository"
149
 
 
150
 
    def get_format_string(self):
151
 
        return "Local Git Repository"
152
 
 
153
 
    def initialize_on_transport(self, transport):
154
 
        from bzrlib.transport.local import LocalTransport
155
 
 
156
 
        if not isinstance(transport, LocalTransport):
157
 
            raise NotImplementedError(self.initialize, 
158
 
                "Can't create Git Repositories/branches on "
159
 
                "non-local transports")
160
 
 
161
 
        from dulwich.repo import Repo
162
 
        Repo.create(transport.local_abspath(".")) 
163
 
        return self.open(transport)
164
 
 
165
 
    def is_supported(self):
166
 
        return True
167
 
 
168
 
 
169
 
class RemoteGitBzrDirFormat(GitBzrDirFormat):
170
 
    """The .git directory control format."""
171
 
 
172
 
    @classmethod
173
 
    def _known_formats(self):
174
 
        return set([RemoteGitBzrDirFormat()])
175
 
 
176
 
    def open(self, transport, _found=None):
177
 
        """Open this directory.
178
 
 
179
 
        """
180
 
        # we dont grok readonly - git isn't integrated with transport.
181
 
        url = transport.base
182
 
        if url.startswith('readonly+'):
183
 
            url = url[len('readonly+'):]
184
 
        if (not url.startswith("git://") and 
185
 
            not url.startswith("git+")):
186
 
            raise bzr_errors.NotBranchError(transport.base)
187
 
        from bzrlib.plugins.git.remote import RemoteGitDir, GitSmartTransport
188
 
        if not isinstance(transport, GitSmartTransport):
189
 
            raise bzr_errors.NotBranchError(transport.base)
190
 
        from bzrlib.plugins.git.dir import GitLockableFiles, GitLock
191
 
        lockfiles = GitLockableFiles(transport, GitLock())
192
 
        return RemoteGitDir(transport, lockfiles, self)
193
 
 
194
 
    @classmethod
195
 
    def probe_transport(klass, transport):
196
 
        """Our format is present if the transport ends in '.not/'."""
197
 
        url = transport.base
198
 
        if url.startswith('readonly+'):
199
 
            url = url[len('readonly+'):]
200
 
        if (not url.startswith("git://") and 
201
 
            not url.startswith("git+")):
202
 
            raise bzr_errors.NotBranchError(transport.base)
203
 
        # little ugly, but works
204
 
        format = klass()
205
 
        from bzrlib.plugins.git.remote import GitSmartTransport
206
 
        if not isinstance(transport, GitSmartTransport):
207
 
            raise bzr_errors.NotBranchError(transport.base)
208
 
        # The only way to know a path exists and contains a valid repository 
209
 
        # is to do a request against it:
210
 
        try:
211
 
            transport.fetch_pack(lambda x: [], None, lambda x: None, 
212
 
                                 lambda x: mutter("git: %s" % x))
213
 
        except errors.git_errors.GitProtocolError:
214
 
            raise bzr_errors.NotBranchError(path=transport.base)
215
 
        else:
216
 
            return format
217
 
        raise bzr_errors.NotBranchError(path=transport.base)
218
 
 
219
 
    def get_format_description(self):
220
 
        return "Remote Git Repository"
221
 
 
222
 
    def get_format_string(self):
223
 
        return "Remote Git Repository"
224
 
 
225
 
    def initialize_on_transport(self, transport):
226
 
        raise bzr_errors.UninitializableFormat(self)
227
 
 
228
 
 
229
 
bzrdir.BzrDirFormat.register_control_format(LocalGitBzrDirFormat)
230
 
bzrdir.BzrDirFormat.register_control_format(RemoteGitBzrDirFormat)
231
 
 
232
 
register_transport_proto('git://', 
233
 
        help="Access using the Git smart server protocol.")
234
 
register_transport_proto('git+ssh://', 
235
 
        help="Access using the Git smart server protocol over SSH.")
 
58
lazy_check_versions()
 
59
# TODO: This should be lazier
 
60
from bzrlib.plugins.git.dir import LocalGitBzrDirFormat, RemoteGitBzrDirFormat
 
61
bzrdir.BzrDirFormat.register_control_format_lazy("bzrlib.plugins.git.dir", "LocalGitBzrDirFormat")
 
62
bzrdir.BzrDirFormat.register_control_format_lazy("bzrlib.plugins.git.dir", "RemoteGitBzrDirFormat")
236
63
 
237
64
register_lazy_transport("git://", 'bzrlib.plugins.git.remote',
238
 
                        'TCPGitSmartTransport')
239
 
 
240
 
register_lazy_transport("git+ssh://", 'bzrlib.plugins.git.remote',
241
 
                        'SSHGitSmartTransport')
 
65
                        'GitSmartTransport')
242
66
 
243
67
foreign_vcs_registry.register_lazy("git", 
244
68
                        "bzrlib.plugins.git.mapping", 
245
69
                        "foreign_git",
246
70
                        "Stupid content tracker")
247
71
 
248
 
plugin_cmds.register_lazy("cmd_git_serve", [], "bzrlib.plugins.git.commands")
249
 
plugin_cmds.register_lazy("cmd_git_import", [], "bzrlib.plugins.git.commands")
250
 
 
251
 
def get_rich_root_format():
252
 
    try:
253
 
        return bzrdir.format_registry.make_bzrdir("default-rich-root")
254
 
    except KeyError:
255
 
        return bzrdir.format_registry.make_bzrdir("1.9-rich-root")
 
72
 
 
73
class cmd_git_serve(Command):
 
74
    """Provide access to a Bazaar branch using the git protocol.
 
75
 
 
76
    This command is experimental and doesn't do much yet.
 
77
    """
 
78
    takes_options = [
 
79
        Option('directory',
 
80
               help='serve contents of directory',
 
81
               type=unicode)
 
82
    ]
 
83
 
 
84
    def run(self, directory=None):
 
85
        lazy_check_versions()
 
86
        from dulwich.server import TCPGitServer
 
87
        from bzrlib.plugins.git.server import BzrBackend
 
88
        from bzrlib.trace import warning
 
89
        import os
 
90
 
 
91
        warning("server support in bzr-git is experimental.")
 
92
 
 
93
        if directory is None:
 
94
            directory = os.getcwd()
 
95
 
 
96
        backend = BzrBackend(directory)
 
97
 
 
98
        server = TCPGitServer(backend, 'localhost')
 
99
        server.serve_forever()
 
100
 
 
101
register_command(cmd_git_serve)
 
102
 
 
103
 
 
104
class cmd_git_import(Command):
 
105
    """Import all branches from a git repository.
 
106
 
 
107
    """
 
108
 
 
109
    takes_args = ["src_location", "dest_location"]
 
110
 
 
111
    def run(self, src_location, dest_location):
 
112
        from bzrlib.bzrdir import BzrDir, format_registry
 
113
        from bzrlib.errors import NoRepositoryPresent, NotBranchError
 
114
        from bzrlib.repository import Repository
 
115
        source_repo = Repository.open(src_location)
 
116
        format = format_registry.make_bzrdir('rich-root-pack')
 
117
        try:
 
118
            target_bzrdir = BzrDir.open(dest_location)
 
119
        except NotBranchError:
 
120
            target_bzrdir = BzrDir.create(dest_location, format=format)
 
121
        try:
 
122
            target_repo = target_bzrdir.open_repository()
 
123
        except NoRepositoryPresent:
 
124
            target_repo = target_bzrdir.create_repository(shared=True)
 
125
 
 
126
        target_repo.fetch(source_repo)
 
127
        for name, ref in source_repo._git.heads().iteritems():
 
128
            head_loc = os.path.join(dest_location, name)
 
129
            try:
 
130
                head_bzrdir = BzrDir.open(head_loc)
 
131
            except NotBranchError:
 
132
                head_bzrdir = BzrDir.create(head_loc, format=format)
 
133
            try:
 
134
                head_branch = head_bzrdir.open_branch()
 
135
            except NotBranchError:
 
136
                head_branch = head_bzrdir.create_branch()
 
137
            head_branch.generate_revision_history(source_repo.get_mapping().revision_id_foreign_to_bzr(ref))
 
138
 
 
139
 
 
140
register_command(cmd_git_import)
 
141
 
256
142
 
257
143
def test_suite():
258
144
    from bzrlib.plugins.git import tests