/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 dir.py

Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 Canonical Ltd
2
 
#
3
 
# This program is free software; you can redistribute it and/or modify
4
 
# it under the terms of the GNU General Public License as published by
5
 
# the Free Software Foundation; either version 2 of the License, or
6
 
# (at your option) any later version.
7
 
#
8
 
# This program is distributed in the hope that it will be useful,
9
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
# GNU General Public License for more details.
12
 
#
13
 
# You should have received a copy of the GNU General Public License
14
 
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 
 
17
 
"""An adapter between a Git control dir and a Bazaar BzrDir"""
18
 
 
19
 
import os
20
 
 
21
 
import bzrlib
22
 
from bzrlib.lazy_import import lazy_import
23
 
from bzrlib import (
24
 
    bzrdir,
25
 
    lockable_files,
26
 
    urlutils,
27
 
    )
28
 
 
29
 
lazy_import(globals(), """
30
 
from bzrlib.lockable_files import TransportLock
31
 
from bzrlib.plugins.git import (
32
 
    errors,
33
 
    branch,
34
 
    repository,
35
 
    workingtree,
36
 
    )
37
 
""")
38
 
 
39
 
 
40
 
 
41
 
class GitLock(object):
42
 
    """A lock that thunks through to Git."""
43
 
 
44
 
    def lock_write(self, token=None):
45
 
        pass
46
 
 
47
 
    def lock_read(self):
48
 
        pass
49
 
 
50
 
    def unlock(self):
51
 
        pass
52
 
 
53
 
    def peek(self):
54
 
        pass
55
 
 
56
 
 
57
 
class GitLockableFiles(lockable_files.LockableFiles):
58
 
    """Git specific lockable files abstraction."""
59
 
 
60
 
    def __init__(self, lock):
61
 
        self._lock = lock
62
 
        self._transaction = None
63
 
        self._lock_mode = None
64
 
        self._lock_count = 0
65
 
 
66
 
 
67
 
class GitDir(bzrdir.BzrDir):
68
 
    """An adapter to the '.git' dir used by git."""
69
 
 
70
 
    _gitrepository_class = repository.GitRepository
71
 
 
72
 
    def __init__(self, transport, lockfiles, gitrepo, format):
73
 
        self._format = format
74
 
        self.root_transport = transport
75
 
        self._git = gitrepo
76
 
        if gitrepo.bare:
77
 
            self.transport = transport
78
 
        else:
79
 
            self.transport = transport.clone('.git')
80
 
        self._lockfiles = lockfiles
81
 
 
82
 
    def get_branch_transport(self, branch_format):
83
 
        if branch_format is None:
84
 
            return self.transport
85
 
        if isinstance(branch_format, GitBzrDirFormat):
86
 
            return self.transport
87
 
        raise errors.bzr_errors.IncompatibleFormat(branch_format, self._format)
88
 
 
89
 
    get_repository_transport = get_branch_transport
90
 
    get_workingtree_transport = get_branch_transport
91
 
 
92
 
    def is_supported(self):
93
 
        return True
94
 
 
95
 
    def open_branch(self, ignored=None):
96
 
        """'create' a branch for this dir."""
97
 
        repo = self.open_repository()
98
 
        if repo._git.heads == []:
99
 
            head = None
100
 
        else:
101
 
            head = repo._git.head()
102
 
        return branch.GitBranch(self, repo, head, 
103
 
                                    self.root_transport.base, self._lockfiles)
104
 
 
105
 
    def open_repository(self, shared=False):
106
 
        """'open' a repository for this dir."""
107
 
        return self._gitrepository_class(self, self._lockfiles)
108
 
 
109
 
    def open_workingtree(self, recommend_upgrade=True):
110
 
        if self._git.bare:
111
 
            loc = urlutils.unescape_for_display(self.root_transport.base, 'ascii')
112
 
            raise errors.bzr_errors.NoWorkingTree(loc)
113
 
        else:
114
 
            return workingtree.GitWorkingTree(self, self.open_repository(), 
115
 
                                                  self.open_branch())
116
 
 
117
 
    def cloning_metadir(self, stacked=False):
118
 
        if stacked:
119
 
            return bzrlib.bzrdir.format_registry.make_bzrdir("pack-0.92")
120
 
        else:
121
 
            return bzrlib.bzrdir.format_registry.make_bzrdir("1.6")
122
 
 
123
 
    def create_repository(self, shared=False):
124
 
        return self.open_repository()
125
 
 
126
 
 
127
 
class GitBzrDirFormat(bzrdir.BzrDirFormat):
128
 
    """The .git directory control format."""
129
 
 
130
 
    _gitdir_class = GitDir
131
 
    _lock_class = TransportLock
132
 
 
133
 
    @classmethod
134
 
    def _known_formats(self):
135
 
        return set([GitBzrDirFormat()])
136
 
 
137
 
    def open(self, transport, _found=None):
138
 
        """Open this directory.
139
 
 
140
 
        """
141
 
        from bzrlib.plugins.git import git
142
 
        # we dont grok readonly - git isn't integrated with transport.
143
 
        url = transport.base
144
 
        if url.startswith('readonly+'):
145
 
            url = url[len('readonly+'):]
146
 
 
147
 
        try:
148
 
            gitrepo = git.repo.Repo(transport.local_abspath("."))
149
 
        except errors.bzr_errors.NotLocalUrl:
150
 
            raise errors.bzr_errors.NotBranchError(path=transport.base)
151
 
        lockfiles = GitLockableFiles(GitLock())
152
 
        return self._gitdir_class(transport, lockfiles, gitrepo, self)
153
 
 
154
 
    @classmethod
155
 
    def probe_transport(klass, transport):
156
 
        """Our format is present if the transport ends in '.not/'."""
157
 
        # little ugly, but works
158
 
        format = klass()
159
 
        # delegate to the main opening code. This pays a double rtt cost at the
160
 
        # moment, so perhaps we want probe_transport to return the opened thing
161
 
        # rather than an openener ? or we could return a curried thing with the
162
 
        # dir to open already instantiated ? Needs more thought.
163
 
        try:
164
 
            format.open(transport)
165
 
            return format
166
 
        except Exception, e:
167
 
            raise errors.bzr_errors.NotBranchError(path=transport.base)
168
 
        raise errors.bzr_errors.NotBranchError(path=transport.base)
169
 
 
170
 
    def get_format_description(self):
171
 
        return "Local Git Repository"
172
 
 
173
 
    def get_format_string(self):
174
 
        return "Local Git Repository"
175
 
 
176
 
    def initialize_on_transport(self, transport):
177
 
        from bzrlib.transport.local import LocalTransport
178
 
        from bzrlib.plugins.git import git
179
 
 
180
 
        if not isinstance(transport, LocalTransport):
181
 
            raise NotImplementedError(self.initialize, 
182
 
                "Can't create Git Repositories/branches on "
183
 
                "non-local transports")
184
 
 
185
 
        git.repo.Repo.create(transport.local_abspath(".")) 
186
 
        return self.open(transport)
187
 
 
188
 
 
189
 
bzrdir.BzrDirFormat.register_control_format(GitBzrDirFormat)