/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

First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.

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 git, 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
 
class GitLock(object):
41
 
    """A lock that thunks through to Git."""
42
 
 
43
 
    def lock_write(self, token=None):
44
 
        pass
45
 
 
46
 
    def lock_read(self):
47
 
        pass
48
 
 
49
 
    def unlock(self):
50
 
        pass
51
 
 
52
 
    def peek(self):
53
 
        pass
54
 
 
55
 
 
56
 
class GitLockableFiles(lockable_files.LockableFiles):
57
 
    """Git specific lockable files abstraction."""
58
 
 
59
 
    def __init__(self, lock):
60
 
        self._lock = lock
61
 
        self._transaction = None
62
 
        self._lock_mode = None
63
 
        self._lock_count = 0
64
 
 
65
 
 
66
 
class GitDir(bzrdir.BzrDir):
67
 
    """An adapter to the '.git' dir used by git."""
68
 
 
69
 
    _gitrepository_class = repository.GitRepository
70
 
 
71
 
    def __init__(self, transport, lockfiles, gitrepo, format):
72
 
        self._format = format
73
 
        self.root_transport = transport
74
 
        self._git = gitrepo
75
 
        if gitrepo.bare:
76
 
            self.transport = transport
77
 
        else:
78
 
            self.transport = transport.clone('.git')
79
 
        self._lockfiles = lockfiles
80
 
 
81
 
    def get_branch_transport(self, branch_format):
82
 
        if branch_format is None:
83
 
            return self.transport
84
 
        if isinstance(branch_format, GitBzrDirFormat):
85
 
            return self.transport
86
 
        raise errors.bzr_errors.IncompatibleFormat(branch_format, self._format)
87
 
 
88
 
    get_repository_transport = get_branch_transport
89
 
    get_workingtree_transport = get_branch_transport
90
 
 
91
 
    def is_supported(self):
92
 
        return True
93
 
 
94
 
    def open_branch(self, ignored=None):
95
 
        """'create' a branch for this dir."""
96
 
        repo = self.open_repository()
97
 
        if repo._git.heads == []:
98
 
            head = None
99
 
        else:
100
 
            head = repo._git.heads[0].commit.id
101
 
        return branch.GitBranch(self, repo, head, 
102
 
                                    self.root_transport.base, self._lockfiles)
103
 
 
104
 
    def open_repository(self, shared=False):
105
 
        """'open' a repository for this dir."""
106
 
        return self._gitrepository_class(self, self._lockfiles)
107
 
 
108
 
    def open_workingtree(self, recommend_upgrade=True):
109
 
        if self._git.bare:
110
 
            loc = urlutils.unescape_for_display(self.root_transport.base, 'ascii')
111
 
            raise errors.bzr_errors.NoWorkingTree(loc)
112
 
        else:
113
 
            return workingtree.GitWorkingTree(self, self.open_repository(), 
114
 
                                                  self.open_branch())
115
 
 
116
 
    def cloning_metadir(self, stacked=False):
117
 
        if stacked:
118
 
            return bzrlib.bzrdir.format_registry.make_bzrdir("pack-0.92")
119
 
        else:
120
 
            return bzrlib.bzrdir.format_registry.make_bzrdir("1.6")
121
 
 
122
 
    def create_repository(self, shared=False):
123
 
        return self.open_repository()
124
 
 
125
 
 
126
 
class GitBzrDirFormat(bzrdir.BzrDirFormat):
127
 
    """The .git directory control format."""
128
 
 
129
 
    _gitdir_class = GitDir
130
 
    _lock_class = TransportLock
131
 
 
132
 
    @classmethod
133
 
    def _known_formats(self):
134
 
        return set([GitBzrDirFormat()])
135
 
 
136
 
    def open(self, transport, _found=None):
137
 
        """Open this directory.
138
 
 
139
 
        """
140
 
        # we dont grok readonly - git isn't integrated with transport.
141
 
        url = transport.base
142
 
        if url.startswith('readonly+'):
143
 
            url = url[len('readonly+'):]
144
 
 
145
 
        try:
146
 
            gitrepo = git.repo.Repo(transport.local_abspath("."))
147
 
        except errors.bzr_errors.NotLocalUrl:
148
 
            raise errors.bzr_errors.NotBranchError(path=transport.base)
149
 
        lockfiles = GitLockableFiles(GitLock())
150
 
        return self._gitdir_class(transport, lockfiles, gitrepo, self)
151
 
 
152
 
    @classmethod
153
 
    def probe_transport(klass, transport):
154
 
        """Our format is present if the transport ends in '.not/'."""
155
 
        # little ugly, but works
156
 
        format = klass()
157
 
        # delegate to the main opening code. This pays a double rtt cost at the
158
 
        # moment, so perhaps we want probe_transport to return the opened thing
159
 
        # rather than an openener ? or we could return a curried thing with the
160
 
        # dir to open already instantiated ? Needs more thought.
161
 
        try:
162
 
            format.open(transport)
163
 
            return format
164
 
        except Exception, e:
165
 
            raise errors.bzr_errors.NotBranchError(path=transport.base)
166
 
        raise errors.bzr_errors.NotBranchError(path=transport.base)
167
 
 
168
 
    def get_format_description(self):
169
 
        return "Local Git Repository"
170
 
 
171
 
    def get_format_string(self):
172
 
        return "Local Git Repository"
173
 
 
174
 
    def initialize_on_transport(self, transport):
175
 
        from bzrlib.transport.local import LocalTransport
176
 
 
177
 
        if not isinstance(transport, LocalTransport):
178
 
            raise NotImplementedError(self.initialize, 
179
 
                "Can't create Git Repositories/branches on "
180
 
                "non-local transports")
181
 
 
182
 
        git.repo.Repo.create(transport.local_abspath(".")) 
183
 
        return self.open(transport)
184
 
 
185
 
 
186
 
bzrdir.BzrDirFormat.register_control_format(GitBzrDirFormat)