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

  • Committer: Gustav Hartvigsson
  • Date: 2021-01-09 21:36:27 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20210109213627-h1xwcutzy9m7a99b
Added 'Case Preserving Working Tree Use Cases' from Canonical Wiki

* Addod a page from the Canonical Bazaar wiki
  with information on the scmeatics of case
  perserving filesystems an a case insensitive
  filesystem works.
  
  * Needs re-work, but this will do as it is the
    same inforamoton as what was on the linked
    page in the currint documentation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
"""An adapter between a Git Repository and a Bazaar Branch"""
19
19
 
20
 
from __future__ import absolute_import
21
 
 
22
20
from .. import (
23
21
    check,
24
22
    errors,
34
32
from ..foreign import (
35
33
    ForeignRepository,
36
34
    )
37
 
from ..sixish import (
38
 
    viewitems,
39
 
    viewvalues,
40
 
    )
41
35
 
42
 
from .commit import (
43
 
    GitCommitBuilder,
44
 
    )
45
36
from .filegraph import (
46
37
    GitFileLastChangeScanner,
47
38
    GitFileParentProvider,
48
39
    )
49
40
from .mapping import (
50
41
    default_mapping,
 
42
    encode_git_path,
51
43
    foreign_vcs_git,
52
44
    mapping_registry,
53
45
    )
68
60
    )
69
61
 
70
62
 
71
 
class RepoReconciler(object):
72
 
    """Reconciler that reconciles a repository.
73
 
 
74
 
    """
75
 
 
76
 
    def __init__(self, repo, other=None, thorough=False):
77
 
        """Construct a RepoReconciler.
78
 
 
79
 
        :param thorough: perform a thorough check which may take longer but
80
 
                         will correct non-data loss issues such as incorrect
81
 
                         cached data.
82
 
        """
83
 
        self.repo = repo
84
 
 
85
 
    def reconcile(self):
86
 
        """Perform reconciliation.
87
 
 
88
 
        After reconciliation the following attributes document found issues:
89
 
        inconsistent_parents: The number of revisions in the repository whose
90
 
                              ancestry was being reported incorrectly.
91
 
        garbage_inventories: The number of inventory objects without revisions
92
 
                             that were garbage collected.
93
 
        """
94
 
 
95
 
 
96
63
class GitCheck(check.Check):
97
64
 
98
65
    def __init__(self, repository, check_repo=True):
131
98
            self._report_repo_results(verbose)
132
99
 
133
100
 
134
 
_optimisers_loaded = False
135
 
 
136
 
 
137
 
def lazy_load_optimisers():
138
 
    global _optimisers_loaded
139
 
    if _optimisers_loaded:
140
 
        return
141
 
    from . import interrepo
142
 
    for optimiser in [interrepo.InterRemoteGitNonGitRepository,
143
 
                      interrepo.InterLocalGitNonGitRepository,
144
 
                      interrepo.InterLocalGitLocalGitRepository,
145
 
                      interrepo.InterRemoteGitLocalGitRepository,
146
 
                      interrepo.InterToLocalGitRepository,
147
 
                      interrepo.InterToRemoteGitRepository,
148
 
                      ]:
149
 
        repository.InterRepository.register_optimiser(optimiser)
150
 
    _optimisers_loaded = True
 
101
for optimiser in ['InterRemoteGitNonGitRepository',
 
102
                  'InterLocalGitNonGitRepository',
 
103
                  'InterLocalGitLocalGitRepository',
 
104
                  'InterLocalGitRemoteGitRepository',
 
105
                  'InterRemoteGitLocalGitRepository',
 
106
                  'InterToLocalGitRepository',
 
107
                  'InterToRemoteGitRepository',
 
108
                  ]:
 
109
    repository.InterRepository.register_lazy_optimiser(
 
110
        'breezy.git.interrepo', optimiser)
151
111
 
152
112
 
153
113
class GitRepository(ForeignRepository):
162
122
        super(GitRepository, self).__init__(GitRepositoryFormat(),
163
123
                                            gitdir, control_files=None)
164
124
        self.base = gitdir.root_transport.base
165
 
        lazy_load_optimisers()
166
125
        self._lock_mode = None
167
126
        self._lock_count = 0
168
127
 
241
200
 
242
201
    def reconcile(self, other=None, thorough=False):
243
202
        """Reconcile this repository."""
244
 
        reconciler = RepoReconciler(self, thorough=thorough)
245
 
        reconciler.reconcile()
246
 
        return reconciler
 
203
        from ..reconcile import ReconcileResult
 
204
        ret = ReconcileResult()
 
205
        ret.aborted = False
 
206
        return ret
247
207
 
248
208
    def supports_rich_root(self):
249
209
        return True
289
249
        :param lossy: Whether to discard data that can not be natively
290
250
            represented, when pushing to a foreign VCS
291
251
        """
 
252
        from .commit import (
 
253
            GitCommitBuilder,
 
254
            )
292
255
        builder = GitCommitBuilder(
293
256
            self, parents, config, timestamp, timezone, committer, revprops,
294
257
            revision_id, lossy)
322
285
        for (file_id, revision_id, identifier) in desired_files:
323
286
            per_revision.setdefault(revision_id, []).append(
324
287
                (file_id, identifier))
325
 
        for revid, files in viewitems(per_revision):
 
288
        for revid, files in per_revision.items():
326
289
            try:
327
290
                (commit_id, mapping) = self.lookup_bzr_revision_id(revid)
328
291
            except errors.NoSuchRevision:
340
303
                try:
341
304
                    obj = tree_lookup_path(
342
305
                        self._git.object_store.__getitem__, root_tree,
343
 
                        path.encode('utf-8'))
 
306
                        encode_git_path(path))
344
307
                    if isinstance(obj, tuple):
345
308
                        (mode, item_id) = obj
346
309
                        obj = self._git.object_store[item_id]
372
335
            o = self._git.object_store[sha]
373
336
            if not isinstance(o, Commit):
374
337
                continue
375
 
            rev, roundtrip_revid, verifiers = mapping.import_commit(
376
 
                o, mapping.revision_id_foreign_to_bzr)
377
 
            yield o.id, rev.revision_id, roundtrip_revid
 
338
            revid = mapping.revision_id_foreign_to_bzr(o.id)
 
339
            yield o.id, revid
378
340
 
379
341
    def all_revision_ids(self):
380
342
        ret = set()
381
 
        for git_sha, revid, roundtrip_revid in self._iter_revision_ids():
382
 
            if roundtrip_revid:
383
 
                ret.add(roundtrip_revid)
384
 
            else:
385
 
                ret.add(revid)
 
343
        for git_sha, revid in self._iter_revision_ids():
 
344
            ret.add(revid)
386
345
        return list(ret)
387
346
 
388
347
    def _get_parents(self, revid, no_alternates=False):
438
397
                    this_parent_map[revid] = parents
439
398
            parent_map.update(this_parent_map)
440
399
            pending = set()
441
 
            for values in viewvalues(this_parent_map):
 
400
            for values in this_parent_map.values():
442
401
                pending.update(values)
443
402
            pending = pending.difference(parent_map)
444
403
        return _mod_graph.KnownGraph(parent_map)
478
437
        commit = self._git.object_store.peel_sha(foreign_revid)
479
438
        if not isinstance(commit, Commit):
480
439
            raise NotCommitError(commit.id)
481
 
        rev, roundtrip_revid, verifiers = mapping.import_commit(
482
 
            commit, mapping.revision_id_foreign_to_bzr)
 
440
        revid = mapping.get_revision_id(commit)
483
441
        # FIXME: check testament before doing this?
484
 
        if roundtrip_revid:
485
 
            return roundtrip_revid
486
 
        else:
487
 
            return rev.revision_id
 
442
        return revid
488
443
 
489
444
    def has_signature_for_revision_id(self, revision_id):
490
445
        """Check whether a GPG signature is present for this revision.
536
491
            (git_sha, mapping) = mapping_registry.revision_id_bzr_to_foreign(
537
492
                bzr_revid)
538
493
        except errors.InvalidRevisionId:
539
 
            if mapping is None:
540
 
                mapping = self.get_mapping()
541
 
            try:
542
 
                return (self._git.refs[mapping.revid_as_refname(bzr_revid)],
543
 
                        mapping)
544
 
            except KeyError:
545
 
                # Update refs from Git commit objects
546
 
                # FIXME: Hitting this a lot will be very inefficient...
547
 
                pb = ui.ui_factory.nested_progress_bar()
548
 
                try:
549
 
                    for i, (git_sha, revid, roundtrip_revid) in enumerate(
550
 
                            self._iter_revision_ids()):
551
 
                        if not roundtrip_revid:
552
 
                            continue
553
 
                        pb.update("resolving revision id", i)
554
 
                        refname = mapping.revid_as_refname(roundtrip_revid)
555
 
                        self._git.refs[refname] = git_sha
556
 
                        if roundtrip_revid == bzr_revid:
557
 
                            return git_sha, mapping
558
 
                finally:
559
 
                    pb.finished()
560
 
                raise errors.NoSuchRevision(self, bzr_revid)
 
494
            raise errors.NoSuchRevision(self, bzr_revid)
561
495
        else:
562
496
            return (git_sha, mapping)
563
497
 
570
504
        except KeyError:
571
505
            raise errors.NoSuchRevision(self, revision_id)
572
506
        revision, roundtrip_revid, verifiers = mapping.import_commit(
573
 
            commit, self.lookup_foreign_revision_id)
 
507
            commit, self.lookup_foreign_revision_id, strict=False)
574
508
        if revision is None:
575
509
            raise AssertionError
576
510
        # FIXME: check verifiers ?
612
546
            raise ValueError('invalid revision id %s' % revision_id)
613
547
        return GitRevisionTree(self, revision_id)
614
548
 
615
 
    def get_deltas_for_revisions(self, revisions, specific_fileids=None):
616
 
        """Produce a generator of revision deltas.
617
 
 
618
 
        Note that the input is a sequence of REVISIONS, not revision_ids.
619
 
        Trees will be held in memory until the generator exits.
620
 
        Each delta is relative to the revision's lefthand predecessor.
621
 
 
622
 
        :param specific_fileids: if not None, the result is filtered
623
 
          so that only those file-ids, their parents and their
624
 
          children are included.
625
 
        """
626
 
        # Get the revision-ids of interest
627
 
        required_trees = set()
628
 
        for revision in revisions:
629
 
            required_trees.add(revision.revision_id)
630
 
            required_trees.update(revision.parent_ids[:1])
631
 
 
632
 
        trees = dict((t.get_revision_id(), t) for
633
 
                     t in self.revision_trees(required_trees))
634
 
 
635
 
        # Calculate the deltas
636
 
        for revision in revisions:
637
 
            if not revision.parent_ids:
638
 
                old_tree = self.revision_tree(_mod_revision.NULL_REVISION)
639
 
            else:
640
 
                old_tree = trees[revision.parent_ids[0]]
641
 
            new_tree = trees[revision.revision_id]
642
 
            if specific_fileids is not None:
643
 
                specific_files = [new_tree.id2path(
644
 
                    fid) for fid in specific_fileids]
645
 
            else:
646
 
                specific_files = None
647
 
            yield new_tree.changes_from(
648
 
                old_tree, specific_files=specific_files)
649
 
 
650
549
    def set_make_working_trees(self, trees):
651
550
        raise errors.UnsupportedOperation(self.set_make_working_trees, self)
652
551