/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

  • Committer: Robert Collins
  • Date: 2010-05-06 11:08:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506110810-h3j07fh5gmw54s25
Cleaner matcher matching revised unlocking protocol.

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
 
            if not transport.has_any(['.git/HEAD', 'HEAD', 'objects', '.git/objects']):
130
 
                raise bzr_errors.NotBranchError(path=transport.base)
131
 
        except bzr_errors.NoSuchFile:
132
 
            raise bzr_errors.NotBranchError(path=transport.base)
133
 
        from bzrlib import urlutils
134
 
        if urlutils.split(transport.base)[1] == ".git":
135
 
            raise bzr_errors.NotBranchError(path=transport.base)
136
 
        lazy_check_versions()
137
 
        import dulwich
138
 
        from bzrlib.plugins.git.transportgit import TransportRepo
139
 
        try:
140
 
            gitrepo = TransportRepo(transport)
141
 
        except dulwich.errors.NotGitRepository, e:
142
 
            raise bzr_errors.NotBranchError(path=transport.base)
143
 
        else:
144
 
            from bzrlib.plugins.git.dir import (
145
 
                BareLocalGitControlDirFormat,
146
 
                LocalGitControlDirFormat,
147
 
                )
148
 
            if gitrepo.bare:
149
 
                return BareLocalGitControlDirFormat()
150
 
            else:
151
 
                return LocalGitControlDirFormat()
152
 
 
153
 
    @classmethod
154
 
    def known_formats(cls):
155
 
        from bzrlib.plugins.git.dir import (
156
 
            BareLocalGitControlDirFormat,
157
 
            LocalGitControlDirFormat,
158
 
            )
159
 
        return set([BareLocalGitControlDirFormat(), LocalGitControlDirFormat()])
160
 
 
161
 
 
162
 
class RemoteGitProber(Prober):
163
 
 
164
 
    def probe_http_transport(self, transport):
165
 
        from bzrlib import urlutils
166
 
        url = urlutils.join(transport.external_url(), "info/refs") + "?service=git-upload-pack"
167
 
        from bzrlib.transport.http._urllib import HttpTransport_urllib, Request
168
 
        if isinstance(transport, HttpTransport_urllib):
169
 
            req = Request('GET', url, accepted_errors=[200, 403, 404, 405],
170
 
                          headers={"Content-Type": "application/x-git-upload-pack-request"})
171
 
            req.follow_redirections = True
172
 
            resp = transport._perform(req)
173
 
            if resp.code == 404:
174
 
                raise bzr_errors.NotBranchError(transport.base)
175
 
            headers = resp.headers
176
 
        else:
177
 
            try:
178
 
                from bzrlib.transport.http._pycurl import PyCurlTransport
179
 
            except bzr_errors.DependencyNotPresent:
180
 
                raise bzr_errors.NotBranchError(transport.base)
181
 
            else:
182
 
                import pycurl
183
 
                from cStringIO import StringIO
184
 
                if isinstance(transport, PyCurlTransport):
185
 
                    conn = transport._get_curl()
186
 
                    conn.setopt(pycurl.URL, url)
187
 
                    transport._set_curl_options(conn)
188
 
                    conn.setopt(pycurl.HTTPGET, 1)
189
 
                    conn.setopt(pycurl.NOBODY, 1)
190
 
                    header = StringIO()
191
 
                    data = StringIO()
192
 
                    conn.setopt(pycurl.HEADERFUNCTION, header.write)
193
 
                    conn.setopt(pycurl.WRITEFUNCTION, data.write)
194
 
                    transport._curl_perform(conn, header,
195
 
                        ["Content-Type: application/x-git-upload-pack-request"])
196
 
                    code = conn.getinfo(pycurl.HTTP_CODE)
197
 
                    if code == 404:
198
 
                        raise bzr_errors.NotBranchError(transport.base)
199
 
                    headers = transport._parse_headers(header)
200
 
                else:
201
 
                    raise bzr_errors.NotBranchError(transport.base)
202
 
        ct = headers.getheader("Content-Type")
203
 
        if ct.startswith("application/x-git"):
204
 
            from bzrlib.plugins.git.remote import RemoteGitControlDirFormat
205
 
            return RemoteGitControlDirFormat()
206
 
        else:
207
 
            from bzrlib.plugins.git.dir import (
208
 
                BareLocalGitControlDirFormat,
209
 
                )
210
 
            return BareLocalGitControlDirFormat()
211
 
 
212
 
    def probe_transport(self, transport):
213
 
        try:
214
 
            external_url = transport.external_url()
215
 
        except bzr_errors.InProcessTransport:
216
 
            raise bzr_errors.NotBranchError(path=transport.base)
217
 
 
218
 
        if (external_url.startswith("http:") or
219
 
            external_url.startswith("https:")):
220
 
            return self.probe_http_transport(transport)
221
 
 
222
 
        if (not external_url.startswith("git://") and
223
 
            not external_url.startswith("git+")):
224
 
            raise bzr_errors.NotBranchError(transport.base)
225
 
 
226
 
        # little ugly, but works
227
 
        from bzrlib.plugins.git.remote import (
228
 
            GitSmartTransport,
229
 
            RemoteGitControlDirFormat,
230
 
            )
231
 
        if isinstance(transport, GitSmartTransport):
232
 
            return RemoteGitControlDirFormat()
233
 
        raise bzr_errors.NotBranchError(path=transport.base)
234
 
 
235
 
    @classmethod
236
 
    def known_formats(cls):
237
 
        from bzrlib.plugins.git.remote import RemoteGitControlDirFormat
238
 
        return set([RemoteGitControlDirFormat()])
239
 
 
240
 
 
241
 
if not getattr(Prober, "known_formats", None): # bzr < 2.4
242
 
    from bzrlib.plugins.git.dir import (
243
 
        LocalGitControlDirFormat, BareLocalGitControlDirFormat,
244
 
        )
245
 
    from bzrlib.plugins.git.remote import RemoteGitControlDirFormat
246
 
    ControlDirFormat.register_format(LocalGitControlDirFormat())
247
 
    ControlDirFormat.register_format(BareLocalGitControlDirFormat())
248
 
    ControlDirFormat.register_format(RemoteGitControlDirFormat())
249
 
    # Provide RevisionTree.get_file_revision, so various parts of bzr-svn
250
 
    # can avoid inventories.
251
 
    from bzrlib.revisiontree import RevisionTree
252
 
    def get_file_revision(tree, file_id, path=None):
253
 
        return tree.inventory[file_id].revision
254
 
    RevisionTree.get_file_revision = get_file_revision
255
 
 
256
 
ControlDirFormat.register_prober(LocalGitProber)
257
 
ControlDirFormat._server_probers.insert(0, RemoteGitProber)
258
 
 
259
 
register_transport_proto('git://',
260
 
        help="Access using the Git smart server protocol.")
261
 
register_transport_proto('git+ssh://',
262
 
        help="Access using the Git smart server protocol over SSH.")
263
 
 
264
 
register_lazy_transport("git://", 'bzrlib.plugins.git.remote',
265
 
                        'TCPGitSmartTransport')
266
 
register_lazy_transport("git+ssh://", 'bzrlib.plugins.git.remote',
267
 
                        'SSHGitSmartTransport')
268
 
 
269
 
foreign_vcs_registry.register_lazy("git",
270
 
    "bzrlib.plugins.git.mapping", "foreign_vcs_git", "Stupid content tracker")
271
 
 
272
 
plugin_cmds.register_lazy("cmd_git_import", [], "bzrlib.plugins.git.commands")
273
 
plugin_cmds.register_lazy("cmd_git_object", ["git-objects", "git-cat"],
274
 
    "bzrlib.plugins.git.commands")
275
 
plugin_cmds.register_lazy("cmd_git_refs", [], "bzrlib.plugins.git.commands")
276
 
plugin_cmds.register_lazy("cmd_git_apply", [], "bzrlib.plugins.git.commands")
277
 
 
278
 
def extract_git_foreign_revid(rev):
279
 
    try:
280
 
        foreign_revid = rev.foreign_revid
281
 
    except AttributeError:
282
 
        from bzrlib.plugins.git.mapping import mapping_registry
283
 
        foreign_revid, mapping = \
284
 
            mapping_registry.parse_revision_id(rev.revision_id)
285
 
        return foreign_revid
286
 
    else:
287
 
        from bzrlib.plugins.git.mapping import foreign_vcs_git
288
 
        if rev.mapping.vcs == foreign_vcs_git:
289
 
            return foreign_revid
290
 
        else:
291
 
            raise bzr_errors.InvalidRevisionId(rev.revision_id, None)
292
 
 
293
 
 
294
 
def update_stanza(rev, stanza):
295
 
    mapping = getattr(rev, "mapping", None)
296
 
    try:
297
 
        git_commit = extract_git_foreign_revid(rev)
298
 
    except bzr_errors.InvalidRevisionId:
299
 
        pass
300
 
    else:
301
 
        stanza.add("git-commit", git_commit)
302
 
 
303
 
try:
304
 
    from bzrlib.hooks import install_lazy_named_hook
305
 
except ImportError: # Compatibility with bzr < 2.4
306
 
    from bzrlib.version_info_formats.format_rio import (
307
 
        RioVersionInfoBuilder,
308
 
        )
309
 
    RioVersionInfoBuilder.hooks.install_named_hook('revision', update_stanza,
310
 
        "git commits")
311
 
else:
312
 
    install_lazy_named_hook("bzrlib.version_info_formats.format_rio",
313
 
        "RioVersionInfoBuilder.hooks", "revision", update_stanza,
314
 
        "git commits")
315
 
 
316
 
 
317
 
from bzrlib.transport import transport_server_registry
318
 
transport_server_registry.register_lazy('git',
319
 
    'bzrlib.plugins.git.server',
320
 
    'serve_git',
321
 
    'Git Smart server protocol over TCP. (default port: 9418)')
322
 
 
323
 
 
324
 
from bzrlib.repository import (
325
 
    format_registry as repository_format_registry,
326
 
    network_format_registry as repository_network_format_registry,
327
 
    )
328
 
repository_network_format_registry.register_lazy('git',
329
 
    'bzrlib.plugins.git.repository', 'GitRepositoryFormat')
330
 
 
331
 
try:
332
 
    register_extra_lazy_repository_format = getattr(repository_format_registry,
333
 
        "register_extra_lazy")
334
 
except AttributeError: # bzr < 2.4
335
 
    pass
336
 
else:
337
 
    register_extra_lazy_repository_format('bzrlib.plugins.git.repository',
338
 
        'GitRepositoryFormat')
339
 
 
340
 
from bzrlib.branch import (
341
 
    network_format_registry as branch_network_format_registry,
342
 
    )
343
 
branch_network_format_registry.register_lazy('git',
344
 
    'bzrlib.plugins.git.branch', 'GitBranchFormat')
345
 
 
346
 
try:
347
 
    from bzrlib.branch import (
348
 
        format_registry as branch_format_registry,
349
 
        )
350
 
except ImportError: # bzr < 2.4
351
 
    pass
352
 
else:
353
 
    branch_format_registry.register_extra_lazy(
354
 
        'bzrlib.plugins.git.branch',
355
 
        'GitBranchFormat',
356
 
        )
357
 
 
358
 
try:
359
 
    from bzrlib.workingtree import (
360
 
        format_registry as workingtree_format_registry,
361
 
        )
362
 
except ImportError: # bzr < 2.4
363
 
    pass
364
 
else:
365
 
    workingtree_format_registry.register_extra_lazy(
366
 
        'bzrlib.plugins.git.workingtree',
367
 
        'GitWorkingTreeFormat',
368
 
        )
369
 
 
370
 
controldir_network_format_registry.register_lazy('git',
371
 
    "bzrlib.plugins.git.dir", "GitControlDirFormat")
372
 
 
373
 
send_format_registry.register_lazy('git', 'bzrlib.plugins.git.send',
374
 
                                   'send_git', 'Git am-style diff format')
375
 
 
376
 
topic_registry.register_lazy('git', 'bzrlib.plugins.git.help', 'help_git',
377
 
    'Using Bazaar with Git')
378
 
 
379
 
from bzrlib.diff import format_registry as diff_format_registry
380
 
diff_format_registry.register_lazy('git', 'bzrlib.plugins.git.send',
381
 
    'GitDiffTree', 'Git am-style diff format')
382
 
 
383
 
 
384
 
def update_git_cache(repository, revid):
385
 
    """Update the git cache after a local commit."""
386
 
    if getattr(repository, "_git", None) is not None:
387
 
        return # No need to update cache for git repositories
388
 
 
389
 
    from bzrlib.plugins.git.object_store import BazaarObjectStore
390
 
    if not repository.control_transport.has("git"):
391
 
        return # No existing cache, don't bother updating
392
 
    store = BazaarObjectStore(repository)
393
 
    store.lock_write()
394
 
    try:
395
 
        parent_revisions = set(repository.get_parent_map([revid])[revid])
396
 
        missing_revisions = store._missing_revisions(parent_revisions)
397
 
        if not missing_revisions:
398
 
            # Only update if the cache was up to date previously
399
 
            store._update_sha_map_revision(revid)
400
 
    finally:
401
 
        store.unlock()
402
 
 
403
 
 
404
 
def post_commit_update_cache(local_branch, master_branch, old_revno, old_revid,
405
 
        new_revno, new_revid):
406
 
    if local_branch is not None:
407
 
        update_git_cache(local_branch.repository, new_revid)
408
 
    update_git_cache(master_branch.repository, new_revid)
409
 
 
410
 
 
411
 
try:
412
 
    from bzrlib.hooks import install_lazy_named_hook
413
 
except ImportError: # Compatibility with bzr < 2.4
414
 
    pass
415
 
else:
416
 
    install_lazy_named_hook("bzrlib.branch",
417
 
        "Branch.hooks", "post_commit", post_commit_update_cache,
418
 
        "git cache")
419
 
 
420
 
 
421
 
def test_suite():
422
 
    from bzrlib.plugins.git import tests
423
 
    return tests.test_suite()