/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

  • Committer: wang
  • Date: 2006-10-29 13:41:32 UTC
  • mto: (2104.4.1 wang_65714)
  • mto: This revision was merged to the branch mainline in revision 2109.
  • Revision ID: wang@ubuntu-20061029134132-3d7f4216f20c4aef
Replace python's difflib by patiencediff because the worst case 
performance is cubic for difflib and people commiting large data 
files are often hurt by this. The worst case performance of patience is 
quadratic. Fix bug 65714.

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
 
    def validate_token(self, token):
57
 
        pass
58
 
 
59
 
 
60
 
class GitLockableFiles(lockable_files.LockableFiles):
61
 
    """Git specific lockable files abstraction."""
62
 
 
63
 
    def __init__(self, transport, lock):
64
 
        self._lock = lock
65
 
        self._transaction = None
66
 
        self._lock_mode = None
67
 
        self._lock_count = 0
68
 
        self._transport = transport
69
 
 
70
 
 
71
 
class GitDir(bzrdir.BzrDir):
72
 
    """An adapter to the '.git' dir used by git."""
73
 
 
74
 
    def is_supported(self):
75
 
        return True
76
 
 
77
 
    def cloning_metadir(self, stacked=False):
78
 
        return bzrlib.bzrdir.format_registry.make_bzrdir("1.9-rich-root")
79
 
 
80
 
 
81
 
class LocalGitDir(GitDir):
82
 
    """An adapter to the '.git' dir used by git."""
83
 
 
84
 
    _gitrepository_class = repository.LocalGitRepository
85
 
 
86
 
    def __init__(self, transport, lockfiles, gitrepo, format):
87
 
        self._format = format
88
 
        self.root_transport = transport
89
 
        self._git = gitrepo
90
 
        if gitrepo.bare:
91
 
            self.transport = transport
92
 
        else:
93
 
            self.transport = transport.clone('.git')
94
 
        self._lockfiles = lockfiles
95
 
 
96
 
    def get_branch_transport(self, branch_format):
97
 
        if branch_format is None:
98
 
            return self.transport
99
 
        if isinstance(branch_format, LocalGitBzrDirFormat):
100
 
            return self.transport
101
 
        raise errors.bzr_errors.IncompatibleFormat(branch_format, self._format)
102
 
 
103
 
    get_repository_transport = get_branch_transport
104
 
    get_workingtree_transport = get_branch_transport
105
 
 
106
 
    def open_branch(self, ignored=None):
107
 
        """'create' a branch for this dir."""
108
 
        repo = self.open_repository()
109
 
        return branch.LocalGitBranch(self, repo, "HEAD", repo._git.head(), self._lockfiles)
110
 
 
111
 
    def open_repository(self, shared=False):
112
 
        """'open' a repository for this dir."""
113
 
        return self._gitrepository_class(self, self._lockfiles)
114
 
 
115
 
    def open_workingtree(self, recommend_upgrade=True):
116
 
        if self._git.bare:
117
 
            loc = urlutils.unescape_for_display(self.root_transport.base, 'ascii')
118
 
            raise errors.bzr_errors.NoWorkingTree(loc)
119
 
        else:
120
 
            return workingtree.GitWorkingTree(self, self.open_repository(), 
121
 
                                                  self.open_branch())
122
 
 
123
 
    def create_repository(self, shared=False):
124
 
        return self.open_repository()
125
 
 
126
 
 
127
 
class GitBzrDirFormat(bzrdir.BzrDirFormat):
128
 
    _lock_class = TransportLock
129
 
 
130
 
    def is_supported(self):
131
 
        return True
132
 
 
133
 
 
134
 
class LocalGitBzrDirFormat(GitBzrDirFormat):
135
 
    """The .git directory control format."""
136
 
 
137
 
    _gitdir_class = LocalGitDir
138
 
 
139
 
    @classmethod
140
 
    def _known_formats(self):
141
 
        return set([LocalGitBzrDirFormat()])
142
 
 
143
 
    def open(self, transport, _found=None):
144
 
        """Open this directory.
145
 
 
146
 
        """
147
 
        from bzrlib.plugins.git import git
148
 
        # we dont grok readonly - git isn't integrated with transport.
149
 
        url = transport.base
150
 
        if url.startswith('readonly+'):
151
 
            url = url[len('readonly+'):]
152
 
 
153
 
        try:
154
 
            gitrepo = git.repo.Repo(transport.local_abspath("."))
155
 
        except errors.bzr_errors.NotLocalUrl:
156
 
            raise errors.bzr_errors.NotBranchError(path=transport.base)
157
 
        lockfiles = GitLockableFiles(transport, GitLock())
158
 
        return self._gitdir_class(transport, lockfiles, gitrepo, self)
159
 
 
160
 
    @classmethod
161
 
    def probe_transport(klass, transport):
162
 
        """Our format is present if the transport ends in '.not/'."""
163
 
        from bzrlib.plugins.git import git
164
 
        # little ugly, but works
165
 
        format = klass()
166
 
        # delegate to the main opening code. This pays a double rtt cost at the
167
 
        # moment, so perhaps we want probe_transport to return the opened thing
168
 
        # rather than an openener ? or we could return a curried thing with the
169
 
        # dir to open already instantiated ? Needs more thought.
170
 
        try:
171
 
            format.open(transport)
172
 
            return format
173
 
        except git.errors.NotGitRepository, e:
174
 
            raise errors.bzr_errors.NotBranchError(path=transport.base)
175
 
        raise errors.bzr_errors.NotBranchError(path=transport.base)
176
 
 
177
 
    def get_format_description(self):
178
 
        return "Local Git Repository"
179
 
 
180
 
    def get_format_string(self):
181
 
        return "Local Git Repository"
182
 
 
183
 
    def initialize_on_transport(self, transport):
184
 
        from bzrlib.transport.local import LocalTransport
185
 
        from bzrlib.plugins.git import git
186
 
 
187
 
        if not isinstance(transport, LocalTransport):
188
 
            raise NotImplementedError(self.initialize, 
189
 
                "Can't create Git Repositories/branches on "
190
 
                "non-local transports")
191
 
 
192
 
        git.repo.Repo.create(transport.local_abspath(".")) 
193
 
        return self.open(transport)
194
 
 
195
 
    def is_supported(self):
196
 
        return True
197
 
 
198
 
 
199
 
class RemoteGitBzrDirFormat(GitBzrDirFormat):
200
 
    """The .git directory control format."""
201
 
 
202
 
    @classmethod
203
 
    def _known_formats(self):
204
 
        return set([RemoteGitBzrDirFormat()])
205
 
 
206
 
    def open(self, transport, _found=None):
207
 
        """Open this directory.
208
 
 
209
 
        """
210
 
        from bzrlib.plugins.git.remote import RemoteGitDir, GitSmartTransport
211
 
        if not isinstance(transport, GitSmartTransport):
212
 
            raise errors.bzr_errors.NotBranchError(transport.base)
213
 
        # we dont grok readonly - git isn't integrated with transport.
214
 
        url = transport.base
215
 
        if url.startswith('readonly+'):
216
 
            url = url[len('readonly+'):]
217
 
 
218
 
        lockfiles = GitLockableFiles(transport, GitLock())
219
 
        return RemoteGitDir(transport, lockfiles, self)
220
 
 
221
 
    @classmethod
222
 
    def probe_transport(klass, transport):
223
 
        """Our format is present if the transport ends in '.not/'."""
224
 
        # little ugly, but works
225
 
        format = klass()
226
 
        from bzrlib.plugins.git.remote import GitSmartTransport
227
 
        if not isinstance(transport, GitSmartTransport):
228
 
            raise errors.bzr_errors.NotBranchError(transport.base)
229
 
        # The only way to know a path exists and contains a valid repository 
230
 
        # is to do a request against it:
231
 
        try:
232
 
            transport.fetch_pack(lambda x: [], None, lambda x: None, 
233
 
                                 lambda x: mutter("git: %s" % x))
234
 
        except GitProtocolException, e:
235
 
            raise errors.bzr_errors.NotBranchError(path=transport.base)
236
 
        else:
237
 
            return format
238
 
        raise errors.bzr_errors.NotBranchError(path=transport.base)
239
 
 
240
 
    def get_format_description(self):
241
 
        return "Remote Git Repository"
242
 
 
243
 
    def get_format_string(self):
244
 
        return "Remote Git Repository"
245
 
 
246
 
    def initialize_on_transport(self, transport):
247
 
        raise errors.bzr_errors.UninitializableFormat(self)
248