/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

More work on roundtrip push support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
from bzrlib import (
21
21
    errors as bzr_errors,
22
22
    lockable_files,
23
 
    trace,
24
23
    urlutils,
25
24
    version_info as bzrlib_version,
26
25
    )
27
 
from bzrlib.bzrdir import CreateRepository
28
 
from bzrlib.transport import do_catching_redirections
29
26
 
30
27
LockWarner = getattr(lockable_files, "_LockWarner", None)
31
28
 
32
 
from bzrlib.controldir import (
33
 
    ControlDir,
34
 
    ControlDirFormat,
35
 
    format_registry,
 
29
from bzrlib.plugins.git import (
 
30
    BareLocalGitControlDirFormat,
 
31
    LocalGitControlDirFormat,
36
32
    )
 
33
try:
 
34
    from bzrlib.controldir import (
 
35
        ControlDir,
 
36
        format_registry,
 
37
        )
 
38
except ImportError:
 
39
    # bzr < 2.3
 
40
    from bzrlib.bzrdir import (
 
41
        BzrDir,
 
42
        format_registry,
 
43
        )
 
44
    ControlDir = BzrDir
37
45
 
38
46
 
39
47
class GitLock(object):
40
48
    """A lock that thunks through to Git."""
41
49
 
42
 
    def __init__(self):
43
 
        self.lock_name = "git lock"
44
 
 
45
50
    def lock_write(self, token=None):
46
51
        pass
47
52
 
85
90
        raise bzr_errors.BzrError("Cannot set configuration")
86
91
 
87
92
 
88
 
class GitControlDirFormat(ControlDirFormat):
89
 
 
90
 
    _lock_class = lockable_files.TransportLock
91
 
 
92
 
    colocated_branches = True
93
 
    fixed_components = True
94
 
 
95
 
    def __eq__(self, other):
96
 
        return type(self) == type(other)
97
 
 
98
 
    def is_supported(self):
99
 
        return True
100
 
 
101
 
    def network_name(self):
102
 
        return "git"
103
 
 
104
 
 
105
93
class GitDir(ControlDir):
106
94
    """An adapter to the '.git' dir used by git."""
107
95
 
120
108
    def _branch_name_to_ref(self, name):
121
109
        raise NotImplementedError(self._branch_name_to_ref)
122
110
 
 
111
    if bzrlib_version >= (2, 2):
 
112
        def open_branch(self, name=None, unsupported=False, 
 
113
            ignore_fallbacks=None):
 
114
            return self._open_branch(name=name,
 
115
                ignore_fallbacks=ignore_fallbacks, unsupported=unsupported)
 
116
    else:
 
117
        def open_branch(self, ignore_fallbacks=None, unsupported=False):
 
118
            return self._open_branch(name=None,
 
119
                ignore_fallbacks=ignore_fallbacks, unsupported=unsupported)
 
120
 
123
121
    def get_config(self):
124
122
        return GitDirConfig()
125
123
 
126
 
    def sprout(self, url, revision_id=None, force_new_repo=False,
127
 
               recurse='down', possible_transports=None,
128
 
               accelerator_tree=None, hardlink=False, stacked=False,
129
 
               source_branch=None, create_tree_if_local=True):
130
 
        from bzrlib.repository import InterRepository
131
 
        from bzrlib.transport.local import LocalTransport
132
 
        from bzrlib.transport import get_transport
133
 
        target_transport = get_transport(url, possible_transports)
134
 
        target_transport.ensure_base()
135
 
        cloning_format = self.cloning_metadir()
136
 
        # Create/update the result branch
137
 
        result = cloning_format.initialize_on_transport(target_transport)
138
 
        source_branch = self.open_branch()
139
 
        source_repository = self.find_repository()
140
 
        try:
141
 
            result_repo = result.find_repository()
142
 
        except bzr_errors.NoRepositoryPresent:
143
 
            result_repo = result.create_repository()
144
 
            target_is_empty = True
145
 
        else:
146
 
            target_is_empty = None # Unknown
147
 
        if stacked:
148
 
            raise bzr_errors.IncompatibleRepositories(source_repository, result_repo)
149
 
        interrepo = InterRepository.get(source_repository, result_repo)
150
 
 
151
 
        if revision_id is not None:
152
 
            determine_wants = interrepo.get_determine_wants_revids(
153
 
                [revision_id], include_tags=True)
154
 
        else:
155
 
            determine_wants = interrepo.determine_wants_all
156
 
        interrepo.fetch_objects(determine_wants=determine_wants,
157
 
            mapping=source_branch.mapping)
158
 
        result_branch = source_branch.sprout(result,
159
 
            revision_id=revision_id, repository=result_repo)
160
 
        if (create_tree_if_local and isinstance(target_transport, LocalTransport)
161
 
            and (result_repo is None or result_repo.make_working_trees())):
162
 
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
163
 
                hardlink=hardlink, from_branch=result_branch)
164
 
            wt.lock_write()
165
 
            try:
166
 
                if wt.path2id('') is None:
167
 
                    try:
168
 
                        wt.set_root_id(self.open_workingtree.get_root_id())
169
 
                    except bzr_errors.NoWorkingTree:
170
 
                        pass
171
 
            finally:
172
 
                wt.unlock()
173
 
        return result
174
 
 
175
 
    def clone_on_transport(self, transport, revision_id=None,
176
 
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
177
 
        create_prefix=False, use_existing_dir=True, no_tree=False):
178
 
        """See ControlDir.clone_on_transport."""
179
 
        if no_tree:
180
 
            format = BareLocalGitControlDirFormat()
181
 
        else:
182
 
            format = LocalGitControlDirFormat()
183
 
        (target_repo, target_controldir, stacking, repo_policy) = format.initialize_on_transport_ex(transport, use_existing_dir=use_existing_dir, create_prefix=create_prefix, force_new_repo=force_new_repo)
184
 
        target_git_repo = target_repo._git
185
 
        source_repo = self.open_repository()
186
 
        source_git_repo = source_repo._git
187
 
        if revision_id is not None:
188
 
            determine_wants = self.get_determine_wants_revids([revision_id], include_tags=True)
189
 
        else:
190
 
            determine_wants = self.determine_wants_all
191
 
        refs = source_git_repo.fetch(target_git_repo, determine_wants)
192
 
        for name, val in refs.iteritems():
193
 
            target_git_repo.refs[name] = val
194
 
        lockfiles = GitLockableFiles(transport, GitLock())
195
 
        return self.__class__(transport, lockfiles, target_git_repo, format)
196
 
 
197
 
    def find_repository(self):
198
 
        """Find the repository that should be used.
199
 
 
200
 
        This does not require a branch as we use it to find the repo for
201
 
        new branches as well as to hook existing branches up to their
202
 
        repository.
203
 
        """
204
 
        return self.open_repository()
205
 
 
206
 
 
207
 
class LocalGitControlDirFormat(GitControlDirFormat):
208
 
    """The .git directory control format."""
209
 
 
210
 
    bare = False
211
 
 
212
 
    @classmethod
213
 
    def _known_formats(self):
214
 
        return set([LocalGitControlDirFormat()])
215
 
 
216
 
    @property
217
 
    def repository_format(self):
218
 
        from bzrlib.plugins.git.repository import GitRepositoryFormat
219
 
        return GitRepositoryFormat()
220
 
 
221
 
    def get_branch_format(self):
222
 
        from bzrlib.plugins.git.branch import GitBranchFormat
223
 
        return GitBranchFormat()
224
 
 
225
 
    def open(self, transport, _found=None):
226
 
        """Open this directory.
227
 
 
228
 
        """
229
 
        from bzrlib.plugins.git.transportgit import TransportRepo
230
 
        gitrepo = TransportRepo(transport)
231
 
        lockfiles = GitLockableFiles(transport, GitLock())
232
 
        return LocalGitDir(transport, lockfiles, gitrepo, self)
233
 
 
234
 
    def get_format_description(self):
235
 
        return "Local Git Repository"
236
 
 
237
 
    def initialize_on_transport(self, transport):
238
 
        from bzrlib.plugins.git.transportgit import TransportRepo
239
 
        TransportRepo.init(transport, bare=self.bare)
240
 
        return self.open(transport)
241
 
 
242
 
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
243
 
        create_prefix=False, force_new_repo=False, stacked_on=None,
244
 
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
245
 
        shared_repo=False, vfs_only=False):
246
 
        def make_directory(transport):
247
 
            transport.mkdir('.')
248
 
            return transport
249
 
        def redirected(transport, e, redirection_notice):
250
 
            trace.note(redirection_notice)
251
 
            return transport._redirected_to(e.source, e.target)
252
 
        try:
253
 
            transport = do_catching_redirections(make_directory, transport,
254
 
                redirected)
255
 
        except bzr_errors.FileExists:
256
 
            if not use_existing_dir:
257
 
                raise
258
 
        except bzr_errors.NoSuchFile:
259
 
            if not create_prefix:
260
 
                raise
261
 
            transport.create_prefix()
262
 
        controldir = self.initialize_on_transport(transport)
263
 
        repository = controldir.open_repository()
264
 
        repository.lock_write()
265
 
        return (repository, controldir, False, CreateRepository(controldir))
266
 
 
267
 
    def is_supported(self):
268
 
        return True
269
 
 
270
 
 
271
 
class BareLocalGitControlDirFormat(LocalGitControlDirFormat):
272
 
 
273
 
    bare = True
274
 
    supports_workingtrees = False
275
 
 
276
 
    def get_format_description(self):
277
 
        return "Local Git Repository (bare)"
278
 
 
279
124
 
280
125
class LocalGitDir(GitDir):
281
126
    """An adapter to the '.git' dir used by git."""
317
162
        return ref
318
163
 
319
164
    def is_control_filename(self, filename):
320
 
        return (filename == '.git' or filename.startswith('.git/'))
 
165
        return filename == '.git' or filename.startswith('.git/')
321
166
 
322
167
    def get_branch_transport(self, branch_format, name=None):
323
168
        if branch_format is None:
340
185
            return self.transport
341
186
        raise bzr_errors.IncompatibleFormat(format, self._format)
342
187
 
343
 
    def open_branch(self, name=None, unsupported=False, ignore_fallbacks=None):
 
188
    def _open_branch(self, name=None, ignore_fallbacks=None, unsupported=False):
344
189
        """'create' a branch for this dir."""
345
190
        repo = self.open_repository()
346
191
        from bzrlib.plugins.git.branch import LocalGitBranch
370
215
                ret.append(self.open_branch(name=name))
371
216
        return ret
372
217
 
373
 
    def open_repository(self):
 
218
    def open_repository(self, shared=False):
374
219
        """'open' a repository for this dir."""
375
220
        return self._gitrepository_class(self, self._lockfiles)
376
221
 
394
239
        raise bzr_errors.NoWorkingTree(loc)
395
240
 
396
241
    def create_repository(self, shared=False):
397
 
        from bzrlib.plugins.git.repository import GitRepositoryFormat
398
 
        if shared:
399
 
            raise bzr_errors.IncompatibleFormat(GitRepositoryFormat(), self._format)
400
242
        return self.open_repository()
401
243
 
402
 
    def create_branch(self, name=None, repository=None):
 
244
    def create_branch(self, name=None):
403
245
        refname = self._branch_name_to_ref(name)
404
246
        from dulwich.protocol import ZERO_SHA
405
247
        self._git.refs[refname or "HEAD"] = ZERO_SHA
416
258
    def create_workingtree(self, revision_id=None, from_branch=None,
417
259
        accelerator_tree=None, hardlink=False):
418
260
        if self._git.bare:
419
 
            raise bzr_errors.UnsupportedOperation(self.create_workingtree, self)
 
261
            raise bzr_errors.BzrError("Can't create working tree in a bare repo")
420
262
        from dulwich.index import write_index
421
263
        from dulwich.pack import SHA1Writer
422
264
        f = open(self.transport.local_abspath("index"), 'w+')
427
269
            f.close()
428
270
        return self.open_workingtree()
429
271
 
430
 
    def _find_or_create_repository(self, force_new_repo=None):
431
 
        return self.create_repository(shared=False)
 
272
    def find_repository(self):
 
273
        """Find the repository that should be used.
 
274
 
 
275
        This does not require a branch as we use it to find the repo for
 
276
        new branches as well as to hook existing branches up to their
 
277
        repository.
 
278
        """
 
279
        return self.open_repository()
432
280
 
433
281
    def _find_creation_modes(self):
434
282
        """Determine the appropriate modes for files and directories.
443
291
        self._mode_check_done = True
444
292
        try:
445
293
            st = self.transport.stat('.')
446
 
        except bzr_errors.TransportNotPossible:
 
294
        except TransportNotPossible:
447
295
            self._dir_mode = None
448
296
            self._file_mode = None
449
297
        else:
474
322
            self._find_creation_modes()
475
323
        return self._dir_mode
476
324
 
 
325