/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

paths should be unicode when yielded by iter_changes.

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()