/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

More work on roundtrip push support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
 
45
45
from bzrlib import (
46
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
 
    )
 
47
    osutils,
 
48
    )
 
49
try:
 
50
    from bzrlib.controldir import (
 
51
        ControlDirFormat,
 
52
        ControlDir,
 
53
        Prober,
 
54
        format_registry,
 
55
        )
 
56
except ImportError:
 
57
    # bzr < 2.3
 
58
    from bzrlib.bzrdir import (
 
59
        BzrDirFormat,
 
60
        BzrDir,
 
61
        format_registry,
 
62
        )
 
63
    ControlDir = BzrDir
 
64
    ControlDirFormat = BzrDirFormat
 
65
    Prober = object
 
66
    has_controldir = False
 
67
else:
 
68
    has_controldir = True
55
69
 
56
70
from bzrlib.foreign import (
57
71
    foreign_vcs_registry,
59
73
from bzrlib.help_topics import (
60
74
    topic_registry,
61
75
    )
 
76
from bzrlib.lockable_files import (
 
77
    TransportLock,
 
78
    )
62
79
from bzrlib.transport import (
63
80
    register_lazy_transport,
64
81
    register_transport_proto,
66
83
from bzrlib.commands import (
67
84
    plugin_cmds,
68
85
    )
 
86
from bzrlib.version_info_formats.format_rio import (
 
87
    RioVersionInfoBuilder,
 
88
    )
69
89
from bzrlib.send import (
70
90
    format_registry as send_format_registry,
71
91
    )
113
133
revspec_registry.register_lazy("git:", "bzrlib.plugins.git.revspec",
114
134
    "RevisionSpec_git")
115
135
 
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
 
136
try:
 
137
    from bzrlib.revisionspec import dwim_revspecs
 
138
except ImportError:
 
139
    pass
 
140
else:
121
141
    from bzrlib.plugins.git.revspec import RevisionSpec_git
122
142
    dwim_revspecs.append(RevisionSpec_git)
123
143
 
124
144
 
 
145
class GitControlDirFormat(ControlDirFormat):
 
146
 
 
147
    _lock_class = TransportLock
 
148
 
 
149
    colocated_branches = True
 
150
 
 
151
    def __eq__(self, other):
 
152
        return type(self) == type(other)
 
153
 
 
154
    def is_supported(self):
 
155
        return True
 
156
 
 
157
    def network_name(self):
 
158
        return "git"
 
159
 
 
160
 
125
161
class LocalGitProber(Prober):
126
162
 
127
163
    def probe_transport(self, transport):
128
164
        try:
129
 
            if not transport.has_any(['.git/HEAD', 'HEAD', 'objects', '.git/objects']):
 
165
            if not transport.has_any(['info/refs', '.git/branches',
 
166
                                      'branches']):
130
167
                raise bzr_errors.NotBranchError(path=transport.base)
131
168
        except bzr_errors.NoSuchFile:
132
169
            raise bzr_errors.NotBranchError(path=transport.base)
141
178
        except dulwich.errors.NotGitRepository, e:
142
179
            raise bzr_errors.NotBranchError(path=transport.base)
143
180
        else:
144
 
            from bzrlib.plugins.git.dir import (
145
 
                BareLocalGitControlDirFormat,
146
 
                LocalGitControlDirFormat,
147
 
                )
148
181
            if gitrepo.bare:
149
182
                return BareLocalGitControlDirFormat()
150
183
            else:
151
184
                return LocalGitControlDirFormat()
152
185
 
153
 
    @classmethod
154
 
    def known_formats(cls):
155
 
        from bzrlib.plugins.git.dir import (
156
 
            BareLocalGitControlDirFormat,
157
 
            LocalGitControlDirFormat,
158
 
            )
159
 
        return set([BareLocalGitControlDirFormat(), LocalGitControlDirFormat()])
 
186
 
 
187
class LocalGitControlDirFormat(GitControlDirFormat):
 
188
    """The .git directory control format."""
 
189
 
 
190
    bare = False
 
191
 
 
192
    @classmethod
 
193
    def _known_formats(self):
 
194
        return set([LocalGitControlDirFormat()])
 
195
 
 
196
    def open(self, transport, _found=None):
 
197
        """Open this directory.
 
198
 
 
199
        """
 
200
        lazy_check_versions()
 
201
        from bzrlib.plugins.git.transportgit import TransportRepo
 
202
        gitrepo = TransportRepo(transport)
 
203
        from bzrlib.plugins.git.dir import LocalGitDir, GitLockableFiles, GitLock
 
204
        lockfiles = GitLockableFiles(transport, GitLock())
 
205
        return LocalGitDir(transport, lockfiles, gitrepo, self)
 
206
 
 
207
    @classmethod
 
208
    def probe_transport(klass, transport):
 
209
        prober = LocalGitProber()
 
210
        return prober.probe_transport(transport)
 
211
 
 
212
    def get_format_description(self):
 
213
        return "Local Git Repository"
 
214
 
 
215
    def initialize_on_transport(self, transport):
 
216
        from bzrlib.transport.local import LocalTransport
 
217
 
 
218
        if not isinstance(transport, LocalTransport):
 
219
            raise NotImplementedError(self.initialize,
 
220
                "Can't create Git Repositories/branches on "
 
221
                "non-local transports")
 
222
        lazy_check_versions()
 
223
        from dulwich.repo import Repo
 
224
        Repo.init(transport.local_abspath(".").encode(osutils._fs_enc),
 
225
            bare=self.bare)
 
226
        return self.open(transport)
 
227
 
 
228
    def is_supported(self):
 
229
        return True
 
230
 
 
231
 
 
232
class BareLocalGitControlDirFormat(LocalGitControlDirFormat):
 
233
 
 
234
    bare = True
 
235
    supports_workingtrees = False
 
236
 
 
237
    @classmethod
 
238
    def _known_formats(self):
 
239
        return set([RemoteGitControlDirFormat()])
 
240
 
 
241
    def get_format_description(self):
 
242
        return "Local Git Repository (bare)"
160
243
 
161
244
 
162
245
class RemoteGitProber(Prober):
163
246
 
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
247
    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+")):
 
248
        url = transport.base
 
249
        if url.startswith('readonly+'):
 
250
            url = url[len('readonly+'):]
 
251
        if (not url.startswith("git://") and not url.startswith("git+")):
224
252
            raise bzr_errors.NotBranchError(transport.base)
225
 
 
226
253
        # 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)
 
254
        from bzrlib.plugins.git.remote import GitSmartTransport
 
255
        if not isinstance(transport, GitSmartTransport):
 
256
            raise bzr_errors.NotBranchError(transport.base)
 
257
        return RemoteGitControlDirFormat()
 
258
 
 
259
 
 
260
 
 
261
class RemoteGitControlDirFormat(GitControlDirFormat):
 
262
    """The .git directory control format."""
 
263
 
 
264
    supports_workingtrees = False
234
265
 
235
266
    @classmethod
236
 
    def known_formats(cls):
237
 
        from bzrlib.plugins.git.remote import RemoteGitControlDirFormat
 
267
    def _known_formats(self):
238
268
        return set([RemoteGitControlDirFormat()])
239
269
 
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
 
270
    def open(self, transport, _found=None):
 
271
        """Open this directory.
 
272
 
 
273
        """
 
274
        # we dont grok readonly - git isn't integrated with transport.
 
275
        url = transport.base
 
276
        if url.startswith('readonly+'):
 
277
            url = url[len('readonly+'):]
 
278
        if (not url.startswith("git://") and not url.startswith("git+")):
 
279
            raise bzr_errors.NotBranchError(transport.base)
 
280
        from bzrlib.plugins.git.remote import RemoteGitDir, GitSmartTransport
 
281
        if not isinstance(transport, GitSmartTransport):
 
282
            raise bzr_errors.NotBranchError(transport.base)
 
283
        from bzrlib.plugins.git.dir import GitLockableFiles, GitLock
 
284
        lockfiles = GitLockableFiles(transport, GitLock())
 
285
        return RemoteGitDir(transport, lockfiles, self)
 
286
 
 
287
    @classmethod
 
288
    def probe_transport(klass, transport):
 
289
        """Our format is present if the transport ends in '.not/'."""
 
290
        prober = RemoteGitProber()
 
291
        return prober.probe_transport(transport)
 
292
 
 
293
    def get_format_description(self):
 
294
        return "Remote Git Repository"
 
295
 
 
296
    def initialize_on_transport(self, transport):
 
297
        raise bzr_errors.UninitializableFormat(self)
 
298
 
 
299
 
 
300
if has_controldir:
246
301
    ControlDirFormat.register_format(LocalGitControlDirFormat())
247
302
    ControlDirFormat.register_format(BareLocalGitControlDirFormat())
248
303
    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)
 
304
    ControlDirFormat.register_prober(LocalGitProber)
 
305
    ControlDirFormat.register_prober(RemoteGitProber)
 
306
else:
 
307
    ControlDirFormat.register_control_format(LocalGitControlDirFormat)
 
308
    ControlDirFormat.register_control_format(BareLocalGitControlDirFormat)
 
309
    ControlDirFormat.register_control_format(RemoteGitControlDirFormat)
258
310
 
259
311
register_transport_proto('git://',
260
312
        help="Access using the Git smart server protocol.")
267
319
                        'SSHGitSmartTransport')
268
320
 
269
321
foreign_vcs_registry.register_lazy("git",
270
 
    "bzrlib.plugins.git.mapping", "foreign_vcs_git", "Stupid content tracker")
 
322
    "bzrlib.plugins.git.mapping", "foreign_git", "Stupid content tracker")
271
323
 
272
324
plugin_cmds.register_lazy("cmd_git_import", [], "bzrlib.plugins.git.commands")
273
325
plugin_cmds.register_lazy("cmd_git_object", ["git-objects", "git-cat"],
275
327
plugin_cmds.register_lazy("cmd_git_refs", [], "bzrlib.plugins.git.commands")
276
328
plugin_cmds.register_lazy("cmd_git_apply", [], "bzrlib.plugins.git.commands")
277
329
 
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
330
def update_stanza(rev, stanza):
295
331
    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")
 
332
    if mapping is not None and mapping.revid_prefix.startswith("git-"):
 
333
        stanza.add("git-commit", rev.foreign_revid)
 
334
 
 
335
 
 
336
rio_hooks = getattr(RioVersionInfoBuilder, "hooks", None)
 
337
if rio_hooks is not None:
 
338
    rio_hooks.install_named_hook('revision', update_stanza, None)
315
339
 
316
340
 
317
341
from bzrlib.transport import transport_server_registry
322
346
 
323
347
 
324
348
from bzrlib.repository import (
325
 
    format_registry as repository_format_registry,
326
349
    network_format_registry as repository_network_format_registry,
327
350
    )
328
351
repository_network_format_registry.register_lazy('git',
329
352
    'bzrlib.plugins.git.repository', 'GitRepositoryFormat')
330
353
 
331
354
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")
 
355
    from bzrlib.controldir import (
 
356
        network_format_registry as controldir_network_format_registry,
 
357
        )
 
358
except ImportError:
 
359
    from bzrlib.bzrdir import (
 
360
        network_format_registry as controldir_network_format_registry,
 
361
        )
 
362
controldir_network_format_registry.register('git', GitControlDirFormat)
372
363
 
373
364
send_format_registry.register_lazy('git', 'bzrlib.plugins.git.send',
374
365
                                   'send_git', 'Git am-style diff format')
375
366
 
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
 
 
 
367
topic_registry.register_lazy('git',
 
368
                             'bzrlib.plugins.git.help',
 
369
                             'help_git', 'Using Bazaar with Git')
410
370
 
411
371
try:
412
 
    from bzrlib.hooks import install_lazy_named_hook
413
 
except ImportError: # Compatibility with bzr < 2.4
 
372
    from bzrlib.diff import format_registry as diff_format_registry
 
373
except ImportError:
414
374
    pass
415
375
else:
416
 
    install_lazy_named_hook("bzrlib.branch",
417
 
        "Branch.hooks", "post_commit", post_commit_update_cache,
418
 
        "git cache")
419
 
 
 
376
    diff_format_registry.register_lazy('git', 'bzrlib.plugins.git.send',
 
377
        'GitDiffTree', 'Git am-style diff format')
420
378
 
421
379
def test_suite():
422
380
    from bzrlib.plugins.git import tests