/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

Fix test after i18n fixes in bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006-2009 Canonical Ltd
 
2
 
 
3
# Authors: Robert Collins <robert.collins@canonical.com>
 
4
#          Jelmer Vernooij <jelmer@samba.org>
 
5
#          John Carr <john.carr@unrouted.co.uk>
 
6
#
 
7
# This program is free software; you can redistribute it and/or modify
 
8
# it under the terms of the GNU General Public License as published by
 
9
# the Free Software Foundation; either version 2 of the License, or
 
10
# (at your option) any later version.
 
11
#
 
12
# This program is distributed in the hope that it will be useful,
 
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
# GNU General Public License for more details.
 
16
#
 
17
# You should have received a copy of the GNU General Public License
 
18
# along with this program; if not, write to the Free Software
 
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 
 
21
 
 
22
"""A GIT branch and repository format implementation for bzr."""
 
23
 
 
24
import os
 
25
import sys
 
26
 
 
27
import bzrlib
 
28
import bzrlib.api
 
29
 
 
30
from info import (
 
31
    bzr_compatible_versions,
 
32
    bzr_plugin_version as version_info,
 
33
    dulwich_minimum_version,
 
34
    )
 
35
 
 
36
if version_info[3] == 'final':
 
37
    version_string = '%d.%d.%d' % version_info[:3]
 
38
else:
 
39
    version_string = '%d.%d.%d%s%d' % version_info
 
40
__version__ = version_string
 
41
 
 
42
bzrlib.api.require_any_api(bzrlib, bzr_compatible_versions)
 
43
 
 
44
 
 
45
from bzrlib import (
 
46
    errors as bzr_errors,
 
47
    )
 
48
 
 
49
from bzrlib.controldir import (
 
50
    ControlDirFormat,
 
51
    Prober,
 
52
    format_registry,
 
53
    network_format_registry as controldir_network_format_registry,
 
54
    )
 
55
 
 
56
from bzrlib.foreign import (
 
57
    foreign_vcs_registry,
 
58
    )
 
59
from bzrlib.help_topics import (
 
60
    topic_registry,
 
61
    )
 
62
from bzrlib.transport import (
 
63
    register_lazy_transport,
 
64
    register_transport_proto,
 
65
    )
 
66
from bzrlib.commands import (
 
67
    plugin_cmds,
 
68
    )
 
69
from bzrlib.send import (
 
70
    format_registry as send_format_registry,
 
71
    )
 
72
 
 
73
 
 
74
if getattr(sys, "frozen", None):
 
75
    # allow import additional libs from ./_lib for bzr.exe only
 
76
    sys.path.append(os.path.normpath(
 
77
        os.path.join(os.path.dirname(__file__), '_lib')))
 
78
 
 
79
 
 
80
def import_dulwich():
 
81
    try:
 
82
        from dulwich import __version__ as dulwich_version
 
83
    except ImportError:
 
84
        raise bzr_errors.DependencyNotPresent("dulwich",
 
85
            "bzr-git: Please install dulwich, https://launchpad.net/dulwich")
 
86
    else:
 
87
        if dulwich_version < dulwich_minimum_version:
 
88
            raise bzr_errors.DependencyNotPresent("dulwich",
 
89
                "bzr-git: Dulwich is too old; at least %d.%d.%d is required" %
 
90
                    dulwich_minimum_version)
 
91
 
 
92
 
 
93
_versions_checked = False
 
94
def lazy_check_versions():
 
95
    global _versions_checked
 
96
    if _versions_checked:
 
97
        return
 
98
    import_dulwich()
 
99
    _versions_checked = True
 
100
 
 
101
format_registry.register_lazy('git',
 
102
    "bzrlib.plugins.git.dir", "LocalGitControlDirFormat",
 
103
    help='GIT repository.', native=False, experimental=False,
 
104
    )
 
105
 
 
106
format_registry.register_lazy('git-bare',
 
107
    "bzrlib.plugins.git.dir", "BareLocalGitControlDirFormat",
 
108
    help='Bare GIT repository (no working tree).', native=False,
 
109
    experimental=False,
 
110
    )
 
111
 
 
112
from bzrlib.revisionspec import revspec_registry
 
113
revspec_registry.register_lazy("git:", "bzrlib.plugins.git.revspec",
 
114
    "RevisionSpec_git")
 
115
 
 
116
from bzrlib.revisionspec import dwim_revspecs, RevisionSpec_dwim
 
117
if getattr(RevisionSpec_dwim, "append_possible_lazy_revspec", None):
 
118
    RevisionSpec_dwim.append_possible_lazy_revspec(
 
119
        "bzrlib.plugins.git.revspec", "RevisionSpec_git")
 
120
else: # bzr < 2.4
 
121
    from bzrlib.plugins.git.revspec import RevisionSpec_git
 
122
    dwim_revspecs.append(RevisionSpec_git)
 
123
 
 
124
 
 
125
class LocalGitProber(Prober):
 
126
 
 
127
    def probe_transport(self, transport):
 
128
        try:
 
129
            external_url = transport.external_url()
 
130
        except bzr_errors.InProcessTransport:
 
131
            raise bzr_errors.NotBranchError(path=transport.base)
 
132
        if (external_url.startswith("http:") or
 
133
            external_url.startswith("https:")):
 
134
            # Already handled by RemoteGitProber
 
135
            raise bzr_errors.NotBranchError(path=transport.base)
 
136
        try:
 
137
            if not transport.has_any(['.git/HEAD', 'HEAD', 'objects', '.git/objects']):
 
138
                raise bzr_errors.NotBranchError(path=transport.base)
 
139
        except bzr_errors.NoSuchFile:
 
140
            raise bzr_errors.NotBranchError(path=transport.base)
 
141
        from bzrlib import urlutils
 
142
        if urlutils.split(transport.base)[1] == ".git":
 
143
            raise bzr_errors.NotBranchError(path=transport.base)
 
144
        lazy_check_versions()
 
145
        import dulwich
 
146
        from bzrlib.plugins.git.transportgit import TransportRepo
 
147
        try:
 
148
            gitrepo = TransportRepo(transport)
 
149
        except dulwich.errors.NotGitRepository, e:
 
150
            raise bzr_errors.NotBranchError(path=transport.base)
 
151
        else:
 
152
            from bzrlib.plugins.git.dir import (
 
153
                BareLocalGitControlDirFormat,
 
154
                LocalGitControlDirFormat,
 
155
                )
 
156
            if gitrepo.bare:
 
157
                return BareLocalGitControlDirFormat()
 
158
            else:
 
159
                return LocalGitControlDirFormat()
 
160
 
 
161
    @classmethod
 
162
    def known_formats(cls):
 
163
        from bzrlib.plugins.git.dir import (
 
164
            BareLocalGitControlDirFormat,
 
165
            LocalGitControlDirFormat,
 
166
            )
 
167
        return set([BareLocalGitControlDirFormat(), LocalGitControlDirFormat()])
 
168
 
 
169
 
 
170
class RemoteGitProber(Prober):
 
171
 
 
172
    def probe_http_transport(self, transport):
 
173
        from bzrlib import urlutils
 
174
        url = urlutils.join(transport.external_url(), "info/refs") + "?service=git-upload-pack"
 
175
        from bzrlib.transport.http._urllib import HttpTransport_urllib, Request
 
176
        if isinstance(transport, HttpTransport_urllib):
 
177
            req = Request('GET', url, accepted_errors=[200, 403, 404, 405],
 
178
                          headers={"Content-Type": "application/x-git-upload-pack-request"})
 
179
            req.follow_redirections = True
 
180
            resp = transport._perform(req)
 
181
            if resp.code == 404:
 
182
                raise bzr_errors.NotBranchError(transport.base)
 
183
            headers = resp.headers
 
184
        else:
 
185
            try:
 
186
                from bzrlib.transport.http._pycurl import PyCurlTransport
 
187
            except bzr_errors.DependencyNotPresent:
 
188
                raise bzr_errors.NotBranchError(transport.base)
 
189
            else:
 
190
                import pycurl
 
191
                from cStringIO import StringIO
 
192
                if isinstance(transport, PyCurlTransport):
 
193
                    conn = transport._get_curl()
 
194
                    conn.setopt(pycurl.URL, url)
 
195
                    transport._set_curl_options(conn)
 
196
                    conn.setopt(pycurl.HTTPGET, 1)
 
197
                    header = StringIO()
 
198
                    data = StringIO()
 
199
                    conn.setopt(pycurl.HEADERFUNCTION, header.write)
 
200
                    conn.setopt(pycurl.WRITEFUNCTION, data.write)
 
201
                    transport._curl_perform(conn, header,
 
202
                        ["Content-Type: application/x-git-upload-pack-request"])
 
203
                    code = conn.getinfo(pycurl.HTTP_CODE)
 
204
                    if code == 404:
 
205
                        raise bzr_errors.NotBranchError(transport.base)
 
206
                    if code != 200:
 
207
                        raise bzr_errors.InvalidHttpResponse(transport._path,
 
208
                            str(code))
 
209
                    headers = transport._parse_headers(header)
 
210
                else:
 
211
                    raise bzr_errors.NotBranchError(transport.base)
 
212
        ct = headers.getheader("Content-Type")
 
213
        if ct.startswith("application/x-git"):
 
214
            from bzrlib.plugins.git.remote import RemoteGitControlDirFormat
 
215
            return RemoteGitControlDirFormat()
 
216
        else:
 
217
            from bzrlib.plugins.git.dir import (
 
218
                BareLocalGitControlDirFormat,
 
219
                )
 
220
            return BareLocalGitControlDirFormat()
 
221
 
 
222
    def probe_transport(self, transport):
 
223
        try:
 
224
            external_url = transport.external_url()
 
225
        except bzr_errors.InProcessTransport:
 
226
            raise bzr_errors.NotBranchError(path=transport.base)
 
227
 
 
228
        if (external_url.startswith("http:") or
 
229
            external_url.startswith("https:")):
 
230
            return self.probe_http_transport(transport)
 
231
 
 
232
        if (not external_url.startswith("git://") and
 
233
            not external_url.startswith("git+")):
 
234
            raise bzr_errors.NotBranchError(transport.base)
 
235
 
 
236
        # little ugly, but works
 
237
        from bzrlib.plugins.git.remote import (
 
238
            GitSmartTransport,
 
239
            RemoteGitControlDirFormat,
 
240
            )
 
241
        if isinstance(transport, GitSmartTransport):
 
242
            return RemoteGitControlDirFormat()
 
243
        raise bzr_errors.NotBranchError(path=transport.base)
 
244
 
 
245
    @classmethod
 
246
    def known_formats(cls):
 
247
        from bzrlib.plugins.git.remote import RemoteGitControlDirFormat
 
248
        return set([RemoteGitControlDirFormat()])
 
249
 
 
250
 
 
251
if not getattr(Prober, "known_formats", None): # bzr < 2.4
 
252
    from bzrlib.plugins.git.dir import (
 
253
        LocalGitControlDirFormat, BareLocalGitControlDirFormat,
 
254
        )
 
255
    from bzrlib.plugins.git.remote import RemoteGitControlDirFormat
 
256
    ControlDirFormat.register_format(LocalGitControlDirFormat())
 
257
    ControlDirFormat.register_format(BareLocalGitControlDirFormat())
 
258
    ControlDirFormat.register_format(RemoteGitControlDirFormat())
 
259
    # Provide RevisionTree.get_file_revision, so various parts of bzr-svn
 
260
    # can avoid inventories.
 
261
    from bzrlib.revisiontree import RevisionTree
 
262
    def get_file_revision(tree, file_id, path=None):
 
263
        return tree.inventory[file_id].revision
 
264
    RevisionTree.get_file_revision = get_file_revision
 
265
 
 
266
ControlDirFormat.register_prober(LocalGitProber)
 
267
ControlDirFormat._server_probers.insert(0, RemoteGitProber)
 
268
 
 
269
register_transport_proto('git://',
 
270
        help="Access using the Git smart server protocol.")
 
271
register_transport_proto('git+ssh://',
 
272
        help="Access using the Git smart server protocol over SSH.")
 
273
 
 
274
register_lazy_transport("git://", 'bzrlib.plugins.git.remote',
 
275
                        'TCPGitSmartTransport')
 
276
register_lazy_transport("git+ssh://", 'bzrlib.plugins.git.remote',
 
277
                        'SSHGitSmartTransport')
 
278
 
 
279
foreign_vcs_registry.register_lazy("git",
 
280
    "bzrlib.plugins.git.mapping", "foreign_vcs_git", "Stupid content tracker")
 
281
 
 
282
plugin_cmds.register_lazy("cmd_git_import", [], "bzrlib.plugins.git.commands")
 
283
plugin_cmds.register_lazy("cmd_git_object", ["git-objects", "git-cat"],
 
284
    "bzrlib.plugins.git.commands")
 
285
plugin_cmds.register_lazy("cmd_git_refs", [], "bzrlib.plugins.git.commands")
 
286
plugin_cmds.register_lazy("cmd_git_apply", [], "bzrlib.plugins.git.commands")
 
287
 
 
288
def extract_git_foreign_revid(rev):
 
289
    try:
 
290
        foreign_revid = rev.foreign_revid
 
291
    except AttributeError:
 
292
        from bzrlib.plugins.git.mapping import mapping_registry
 
293
        foreign_revid, mapping = \
 
294
            mapping_registry.parse_revision_id(rev.revision_id)
 
295
        return foreign_revid
 
296
    else:
 
297
        from bzrlib.plugins.git.mapping import foreign_vcs_git
 
298
        if rev.mapping.vcs == foreign_vcs_git:
 
299
            return foreign_revid
 
300
        else:
 
301
            raise bzr_errors.InvalidRevisionId(rev.revision_id, None)
 
302
 
 
303
 
 
304
def update_stanza(rev, stanza):
 
305
    mapping = getattr(rev, "mapping", None)
 
306
    try:
 
307
        git_commit = extract_git_foreign_revid(rev)
 
308
    except bzr_errors.InvalidRevisionId:
 
309
        pass
 
310
    else:
 
311
        stanza.add("git-commit", git_commit)
 
312
 
 
313
try:
 
314
    from bzrlib.hooks import install_lazy_named_hook
 
315
except ImportError: # Compatibility with bzr < 2.4
 
316
    from bzrlib.version_info_formats.format_rio import (
 
317
        RioVersionInfoBuilder,
 
318
        )
 
319
    RioVersionInfoBuilder.hooks.install_named_hook('revision', update_stanza,
 
320
        "git commits")
 
321
else:
 
322
    install_lazy_named_hook("bzrlib.version_info_formats.format_rio",
 
323
        "RioVersionInfoBuilder.hooks", "revision", update_stanza,
 
324
        "git commits")
 
325
 
 
326
 
 
327
from bzrlib.transport import transport_server_registry
 
328
transport_server_registry.register_lazy('git',
 
329
    'bzrlib.plugins.git.server',
 
330
    'serve_git',
 
331
    'Git Smart server protocol over TCP. (default port: 9418)')
 
332
 
 
333
 
 
334
from bzrlib.repository import (
 
335
    format_registry as repository_format_registry,
 
336
    network_format_registry as repository_network_format_registry,
 
337
    )
 
338
repository_network_format_registry.register_lazy('git',
 
339
    'bzrlib.plugins.git.repository', 'GitRepositoryFormat')
 
340
 
 
341
try:
 
342
    register_extra_lazy_repository_format = getattr(repository_format_registry,
 
343
        "register_extra_lazy")
 
344
except AttributeError: # bzr < 2.4
 
345
    pass
 
346
else:
 
347
    register_extra_lazy_repository_format('bzrlib.plugins.git.repository',
 
348
        'GitRepositoryFormat')
 
349
 
 
350
from bzrlib.branch import (
 
351
    network_format_registry as branch_network_format_registry,
 
352
    )
 
353
branch_network_format_registry.register_lazy('git',
 
354
    'bzrlib.plugins.git.branch', 'GitBranchFormat')
 
355
 
 
356
try:
 
357
    from bzrlib.branch import (
 
358
        format_registry as branch_format_registry,
 
359
        )
 
360
except ImportError: # bzr < 2.4
 
361
    pass
 
362
else:
 
363
    branch_format_registry.register_extra_lazy(
 
364
        'bzrlib.plugins.git.branch',
 
365
        'GitBranchFormat',
 
366
        )
 
367
 
 
368
try:
 
369
    from bzrlib.workingtree import (
 
370
        format_registry as workingtree_format_registry,
 
371
        )
 
372
except ImportError: # bzr < 2.4
 
373
    pass
 
374
else:
 
375
    workingtree_format_registry.register_extra_lazy(
 
376
        'bzrlib.plugins.git.workingtree',
 
377
        'GitWorkingTreeFormat',
 
378
        )
 
379
 
 
380
controldir_network_format_registry.register_lazy('git',
 
381
    "bzrlib.plugins.git.dir", "GitControlDirFormat")
 
382
 
 
383
send_format_registry.register_lazy('git', 'bzrlib.plugins.git.send',
 
384
                                   'send_git', 'Git am-style diff format')
 
385
 
 
386
topic_registry.register_lazy('git', 'bzrlib.plugins.git.help', 'help_git',
 
387
    'Using Bazaar with Git')
 
388
 
 
389
from bzrlib.diff import format_registry as diff_format_registry
 
390
diff_format_registry.register_lazy('git', 'bzrlib.plugins.git.send',
 
391
    'GitDiffTree', 'Git am-style diff format')
 
392
 
 
393
 
 
394
def update_git_cache(repository, revid):
 
395
    """Update the git cache after a local commit."""
 
396
    if getattr(repository, "_git", None) is not None:
 
397
        return # No need to update cache for git repositories
 
398
 
 
399
    from bzrlib.plugins.git.object_store import BazaarObjectStore
 
400
    if not repository.control_transport.has("git"):
 
401
        return # No existing cache, don't bother updating
 
402
    store = BazaarObjectStore(repository)
 
403
    store.lock_write()
 
404
    try:
 
405
        parent_revisions = set(repository.get_parent_map([revid])[revid])
 
406
        missing_revisions = store._missing_revisions(parent_revisions)
 
407
        if not missing_revisions:
 
408
            # Only update if the cache was up to date previously
 
409
            store._update_sha_map_revision(revid)
 
410
    finally:
 
411
        store.unlock()
 
412
 
 
413
 
 
414
def post_commit_update_cache(local_branch, master_branch, old_revno, old_revid,
 
415
        new_revno, new_revid):
 
416
    if local_branch is not None:
 
417
        update_git_cache(local_branch.repository, new_revid)
 
418
    update_git_cache(master_branch.repository, new_revid)
 
419
 
 
420
 
 
421
try:
 
422
    from bzrlib.hooks import install_lazy_named_hook
 
423
except ImportError: # Compatibility with bzr < 2.4
 
424
    pass
 
425
else:
 
426
    install_lazy_named_hook("bzrlib.branch",
 
427
        "Branch.hooks", "post_commit", post_commit_update_cache,
 
428
        "git cache")
 
429
 
 
430
 
 
431
def test_suite():
 
432
    from bzrlib.plugins.git import tests
 
433
    return tests.test_suite()