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

  • Committer: Jelmer Vernooij
  • Date: 2019-03-05 07:32:38 UTC
  • mto: (7290.1.21 work)
  • mto: This revision was merged to the branch mainline in revision 7311.
  • Revision ID: jelmer@jelmer.uk-20190305073238-zlqn981opwnqsmzi
Add appveyor configuration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
"""An adapter between a Git control dir and a Bazaar ControlDir."""
19
19
 
20
 
import contextlib
 
20
from __future__ import absolute_import
21
21
 
22
22
from .. import (
23
23
    branch as _mod_branch,
26
26
    osutils,
27
27
    urlutils,
28
28
    )
 
29
from ..sixish import (
 
30
    PY3,
 
31
    viewitems,
 
32
    )
29
33
from ..transport import (
30
34
    do_catching_redirections,
31
35
    get_transport_from_path,
39
43
    RepositoryAcquisitionPolicy,
40
44
    )
41
45
 
42
 
from .mapping import (
43
 
    decode_git_path,
44
 
    encode_git_path,
45
 
    )
46
46
from .push import (
47
47
    GitPushResult,
48
48
    )
182
182
        result_branch = source_branch.sprout(
183
183
            result, revision_id=revision_id, repository=result_repo)
184
184
        if (create_tree_if_local and
185
 
            result.open_branch(name="").name == result_branch.name and
186
185
            isinstance(target_transport, LocalTransport) and
187
186
                (result_repo is None or result_repo.make_working_trees())):
188
 
            wt = result.create_workingtree(
 
187
            result.create_workingtree(
189
188
                accelerator_tree=accelerator_tree,
190
189
                hardlink=hardlink, from_branch=result_branch)
191
 
        else:
192
 
            wt = None
193
 
        if recurse == 'down':
194
 
            with contextlib.ExitStack() as stack:
195
 
                basis = None
196
 
                if wt is not None:
197
 
                    basis = wt.basis_tree()
198
 
                elif result_branch is not None:
199
 
                    basis = result_branch.basis_tree()
200
 
                elif source_branch is not None:
201
 
                    basis = source_branch.basis_tree()
202
 
                if basis is not None:
203
 
                    stack.enter_context(basis.lock_read())
204
 
                    subtrees = basis.iter_references()
205
 
                else:
206
 
                    subtrees = []
207
 
                for path in subtrees:
208
 
                    target = urlutils.join(url, urlutils.escape(path))
209
 
                    sublocation = wt.reference_parent(
210
 
                        path, possible_transports=possible_transports)
211
 
                    if sublocation is None:
212
 
                        trace.warning(
213
 
                            'Ignoring nested tree %s, parent location unknown.',
214
 
                            path)
215
 
                        continue
216
 
                    sublocation.controldir.sprout(
217
 
                        target, basis.get_reference_revision(path),
218
 
                        force_new_repo=force_new_repo, recurse=recurse,
219
 
                        stacked=stacked)
220
 
        if getattr(result_repo, '_git', None):
221
 
            # Don't leak resources:
222
 
            # TODO(jelmer): This shouldn't be git-specific, and possibly
223
 
            # just use read locks.
224
 
            result_repo._git.object_store.close()
225
190
        return result
226
191
 
227
192
    def clone_on_transport(self, transport, revision_id=None,
228
193
                           force_new_repo=False, preserve_stacking=False,
229
194
                           stacked_on=None, create_prefix=False,
230
 
                           use_existing_dir=True, no_tree=False,
231
 
                           tag_selector=None):
 
195
                           use_existing_dir=True, no_tree=False):
232
196
        """See ControlDir.clone_on_transport."""
233
197
        from ..repository import InterRepository
234
198
        from .mapping import default_mapping
235
 
        from ..transport.local import LocalTransport
236
199
        if stacked_on is not None:
237
200
            raise _mod_branch.UnstackableBranchFormat(
238
201
                self._format, self.user_url)
251
214
        interrepo = InterRepository.get(source_repo, target_repo)
252
215
        if revision_id is not None:
253
216
            determine_wants = interrepo.get_determine_wants_revids(
254
 
                [revision_id], include_tags=True, tag_selector=tag_selector)
 
217
                [revision_id], include_tags=True)
255
218
        else:
256
219
            determine_wants = interrepo.determine_wants_all
257
220
        (pack_hint, _, refs) = interrepo.fetch_objects(determine_wants,
258
221
                                                       mapping=default_mapping)
259
 
        for name, val in refs.items():
 
222
        for name, val in viewitems(refs):
260
223
            target_git_repo.refs[name] = val
261
 
        result_dir = LocalGitDir(transport, target_git_repo, format)
 
224
        result_dir = self.__class__(transport, target_git_repo, format)
262
225
        if revision_id is not None:
263
226
            result_dir.open_branch().set_last_revision(revision_id)
264
 
        if not no_tree and isinstance(result_dir.root_transport, LocalTransport):
 
227
        try:
 
228
            # Cheaper to check if the target is not local, than to try making
 
229
            # the tree and fail.
 
230
            result_dir.root_transport.local_abspath('.')
265
231
            if result_dir.open_repository().make_working_trees():
266
 
                try:
267
 
                    local_wt = self.open_workingtree()
268
 
                except brz_errors.NoWorkingTree:
269
 
                    pass
270
 
                except brz_errors.NotLocalUrl:
271
 
                    result_dir.create_workingtree(revision_id=revision_id)
272
 
                else:
273
 
                    local_wt.clone(result_dir, revision_id=revision_id)
 
232
                self.open_workingtree().clone(
 
233
                    result_dir, revision_id=revision_id)
 
234
        except (brz_errors.NoWorkingTree, brz_errors.NotLocalUrl):
 
235
            pass
274
236
 
275
237
        return result_dir
276
238
 
305
267
        """
306
268
        return UseExistingRepository(self.find_repository())
307
269
 
308
 
    def branch_names(self):
309
 
        from .refs import ref_to_branch_name
310
 
        ret = []
311
 
        for ref in self.get_refs_container().keys():
312
 
            try:
313
 
                branch_name = ref_to_branch_name(ref)
314
 
            except UnicodeDecodeError:
315
 
                trace.warning("Ignoring branch %r with unicode error ref", ref)
316
 
                continue
317
 
            except ValueError:
318
 
                continue
319
 
            ret.append(branch_name)
320
 
        return ret
321
 
 
322
270
    def get_branches(self):
323
271
        from .refs import ref_to_branch_name
324
272
        ret = {}
325
273
        for ref in self.get_refs_container().keys():
326
274
            try:
327
275
                branch_name = ref_to_branch_name(ref)
 
276
            except ValueError:
 
277
                continue
328
278
            except UnicodeDecodeError:
329
279
                trace.warning("Ignoring branch %r with unicode error ref", ref)
330
280
                continue
331
 
            except ValueError:
332
 
                continue
333
281
            ret[branch_name] = self.open_branch(ref=ref)
334
282
        return ret
335
283
 
338
286
 
339
287
    def push_branch(self, source, revision_id=None, overwrite=False,
340
288
                    remember=False, create_prefix=False, lossy=False,
341
 
                    name=None, tag_selector=None):
 
289
                    name=None):
342
290
        """Push the source branch into this ControlDir."""
343
291
        push_result = GitPushResult()
344
292
        push_result.workingtree_updated = None
351
299
        target = self.open_branch(name, nascent_ok=True)
352
300
        push_result.branch_push_result = source.push(
353
301
            target, overwrite=overwrite, stop_revision=revision_id,
354
 
            lossy=lossy, tag_selector=tag_selector)
 
302
            lossy=lossy)
355
303
        push_result.new_revid = push_result.branch_push_result.new_revid
356
304
        push_result.old_revid = push_result.branch_push_result.old_revid
357
 
        try:
358
 
            wt = self.open_workingtree()
359
 
        except brz_errors.NoWorkingTree:
360
 
            push_result.workingtree_updated = None
361
 
        else:
362
 
            if self.open_branch(name="").name == target.name:
363
 
                wt._update_git_tree(
364
 
                    old_revision=push_result.old_revid,
365
 
                    new_revision=push_result.new_revid)
366
 
                push_result.workingtree_updated = True
367
 
            else:
368
 
                push_result.workingtree_updated = False
369
305
        push_result.target_branch = target
370
306
        if source.get_push_location() is None or remember:
371
307
            source.set_push_location(push_result.target_branch.base)
402
338
        from .transportgit import TransportRepo
403
339
 
404
340
        def _open(transport):
405
 
            try:
406
 
                return TransportRepo(transport, self.bare,
407
 
                                     refs_text=getattr(self, "_refs_text", None))
408
 
            except ValueError as e:
409
 
                if e.args == ('Expected file to start with \'gitdir: \'', ):
410
 
                    raise brz_errors.NotBranchError(path=transport.base)
411
 
                raise
 
341
            return TransportRepo(transport, self.bare,
 
342
                                 refs_text=getattr(self, "_refs_text", None))
412
343
 
413
344
        def redirected(transport, e, redirection_notice):
414
345
            trace.note(redirection_notice)
415
346
            return transport._redirected_to(e.source, e.target)
416
347
        gitrepo = do_catching_redirections(_open, transport, redirected)
417
 
        if not _found and not gitrepo._controltransport.has('objects'):
 
348
        if not gitrepo._controltransport.has('HEAD'):
418
349
            raise brz_errors.NotBranchError(path=transport.base)
419
350
        return LocalGitDir(transport, gitrepo, self)
420
351
 
432
363
                                   stack_on_pwd=None, repo_format_name=None,
433
364
                                   make_working_trees=None,
434
365
                                   shared_repo=False, vfs_only=False):
435
 
        if shared_repo:
436
 
            raise brz_errors.SharedRepositoriesUnsupported(self)
437
 
 
438
366
        def make_directory(transport):
439
367
            transport.mkdir('.')
440
368
            return transport
473
401
            raise brz_errors.NotBranchError(path=transport.base)
474
402
        return external_url.startswith("file:")
475
403
 
476
 
    def is_control_filename(self, filename):
477
 
        return (filename == '.git'
478
 
                or filename.startswith('.git/')
479
 
                or filename.startswith('.git\\'))
480
 
 
481
404
 
482
405
class BareLocalGitControlDirFormat(LocalGitControlDirFormat):
483
406
 
487
410
    def get_format_description(self):
488
411
        return "Local Git Repository (bare)"
489
412
 
490
 
    def is_control_filename(self, filename):
491
 
        return False
492
 
 
493
413
 
494
414
class LocalGitDir(GitDir):
495
415
    """An adapter to the '.git' dir used by git."""
523
443
            self.transport = transport.clone('.git')
524
444
        self._mode_check_done = None
525
445
 
 
446
    def is_control_filename(self, filename):
 
447
        return (filename == '.git'
 
448
                or filename.startswith('.git/')
 
449
                or filename.startswith('.git\\'))
 
450
 
526
451
    def _get_symref(self, ref):
527
452
        ref_chain, unused_sha = self._git.refs.follow(ref)
528
453
        if len(ref_chain) == 1:
546
471
                    target_branch._format, self._format)
547
472
            # TODO(jelmer): Do some consistency checking across branches..
548
473
            self.control_transport.put_bytes(
549
 
                'commondir', encode_git_path(target_path))
 
474
                'commondir', target_path.encode('utf-8'))
550
475
            # TODO(jelmer): Urgh, avoid mucking about with internals.
551
476
            self._git._commontransport = (
552
477
                target_branch.repository._git._commontransport.clone())
586
511
                base_url = self.user_url.rstrip('/')
587
512
            else:
588
513
                base_url = urlutils.local_path_to_url(
589
 
                    decode_git_path(commondir)).rstrip('/.git/') + '/'
 
514
                    commondir.decode(osutils._fs_enc)).rstrip('/.git/') + '/'
 
515
            if not PY3:
 
516
                params = {k: v.encode('utf-8') for (k, v) in viewitems(params)}
590
517
            return urlutils.join_segment_parameters(base_url, params)
591
518
        return None
592
519