/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/revisionspec.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:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
from __future__ import absolute_import
18
 
 
19
17
 
20
18
from .lazy_import import lazy_import
21
19
lazy_import(globals(), """
37
35
    registry,
38
36
    trace,
39
37
    )
40
 
from .sixish import (
41
 
    text_type,
42
 
    )
 
38
 
 
39
 
 
40
class InvalidRevisionSpec(errors.BzrError):
 
41
 
 
42
    _fmt = ("Requested revision: '%(spec)s' does not exist in branch:"
 
43
            " %(branch_url)s%(extra)s")
 
44
 
 
45
    def __init__(self, spec, branch, extra=None):
 
46
        errors.BzrError.__init__(self, branch=branch, spec=spec)
 
47
        self.branch_url = getattr(branch, 'user_url', str(branch))
 
48
        if extra:
 
49
            self.extra = '\n' + str(extra)
 
50
        else:
 
51
            self.extra = ''
 
52
 
 
53
 
 
54
class InvalidRevisionSpec(errors.BzrError):
 
55
 
 
56
    _fmt = ("Requested revision: '%(spec)s' does not exist in branch:"
 
57
            " %(branch_url)s%(extra)s")
 
58
 
 
59
    def __init__(self, spec, branch, extra=None):
 
60
        errors.BzrError.__init__(self, branch=branch, spec=spec)
 
61
        self.branch_url = getattr(branch, 'user_url', str(branch))
 
62
        if extra:
 
63
            self.extra = '\n' + str(extra)
 
64
        else:
 
65
            self.extra = ''
43
66
 
44
67
 
45
68
class RevisionInfo(object):
141
164
    """
142
165
 
143
166
    prefix = None
144
 
    dwim_catchable_exceptions = (errors.InvalidRevisionSpec,)
 
167
    dwim_catchable_exceptions = (InvalidRevisionSpec,)
145
168
    """Exceptions that RevisionSpec_dwim._match_on will catch.
146
169
 
147
170
    If the revspec is part of ``dwim_revspecs``, it may be tried with an
160
183
        """
161
184
        if spec is None:
162
185
            return RevisionSpec(None, _internal=True)
163
 
        if not isinstance(spec, (str, text_type)):
 
186
        if not isinstance(spec, str):
164
187
            raise TypeError("revision spec needs to be text")
165
188
        match = revspec_registry.get_prefix(spec)
166
189
        if match is not None:
201
224
            # special case - nothing supplied
202
225
            return info
203
226
        elif self.prefix:
204
 
            raise errors.InvalidRevisionSpec(self.user_spec, branch)
 
227
            raise InvalidRevisionSpec(self.user_spec, branch)
205
228
        else:
206
 
            raise errors.InvalidRevisionSpec(self.spec, branch)
 
229
            raise InvalidRevisionSpec(self.spec, branch)
207
230
 
208
231
    def in_history(self, branch):
209
232
        return self._match_on_and_check(branch, revs=None)
318
341
        # Well, I dunno what it is. Note that we don't try to keep track of the
319
342
        # first of last exception raised during the DWIM tries as none seems
320
343
        # really relevant.
321
 
        raise errors.InvalidRevisionSpec(self.spec, branch)
 
344
        raise InvalidRevisionSpec(self.spec, branch)
322
345
 
323
346
    @classmethod
324
347
    def append_possible_revspec(cls, revspec):
378
401
 
379
402
        if revno_spec == '':
380
403
            if not branch_spec:
381
 
                raise errors.InvalidRevisionSpec(self.user_spec,
382
 
                                                 branch, 'cannot have an empty revno and no branch')
 
404
                raise InvalidRevisionSpec(
 
405
                    self.user_spec, branch,
 
406
                    'cannot have an empty revno and no branch')
383
407
            revno = None
384
408
        else:
385
409
            try:
393
417
                    match_revno = tuple((int(number)
394
418
                                         for number in revno_spec.split('.')))
395
419
                except ValueError as e:
396
 
                    raise errors.InvalidRevisionSpec(self.user_spec, branch, e)
 
420
                    raise InvalidRevisionSpec(self.user_spec, branch, e)
397
421
 
398
422
                dotted = True
399
423
 
406
430
                revision_id = branch.dotted_revno_to_revision_id(match_revno,
407
431
                                                                 _cache_reverse=True)
408
432
            except (errors.NoSuchRevision, errors.RevnoOutOfBounds):
409
 
                raise errors.InvalidRevisionSpec(self.user_spec, branch)
 
433
                raise InvalidRevisionSpec(self.user_spec, branch)
410
434
            else:
411
435
                # there is no traditional 'revno' for dotted-decimal revnos.
412
436
                # so for API compatibility we return None.
423
447
            try:
424
448
                revision_id = branch.get_rev_id(revno)
425
449
            except (errors.NoSuchRevision, errors.RevnoOutOfBounds):
426
 
                raise errors.InvalidRevisionSpec(self.user_spec, branch)
 
450
                raise InvalidRevisionSpec(self.user_spec, branch)
427
451
        return branch, revno, revision_id
428
452
 
429
453
    def _as_revision_id(self, context_branch):
471
495
        # self.spec comes straight from parsing the command line arguments,
472
496
        # so we expect it to be a Unicode string. Switch it to the internal
473
497
        # representation.
474
 
        if isinstance(self.spec, text_type):
 
498
        if isinstance(self.spec, str):
475
499
            return cache_utf8.encode(self.spec)
476
500
        return self.spec
477
501
 
506
530
        try:
507
531
            offset = int(self.spec)
508
532
        except ValueError as e:
509
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch, e)
 
533
            raise InvalidRevisionSpec(self.user_spec, context_branch, e)
510
534
 
511
535
        if offset <= 0:
512
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
513
 
                                             'you must supply a positive value')
 
536
            raise InvalidRevisionSpec(
 
537
                self.user_spec, context_branch,
 
538
                'you must supply a positive value')
514
539
 
515
540
        revno = last_revno - offset + 1
516
541
        try:
517
542
            revision_id = context_branch.get_rev_id(revno)
518
543
        except (errors.NoSuchRevision, errors.RevnoOutOfBounds):
519
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch)
 
544
            raise InvalidRevisionSpec(self.user_spec, context_branch)
520
545
        return revno, revision_id
521
546
 
522
547
    def _as_revision_id(self, context_branch):
553
578
    def _match_on(self, branch, revs):
554
579
        r = RevisionSpec.from_string(self.spec)._match_on(branch, revs)
555
580
        if r.revno == 0:
556
 
            raise errors.InvalidRevisionSpec(self.user_spec, branch,
557
 
                                             'cannot go before the null: revision')
 
581
            raise InvalidRevisionSpec(
 
582
                self.user_spec, branch,
 
583
                'cannot go before the null: revision')
558
584
        if r.revno is None:
559
585
            # We need to use the repository history here
560
586
            rev = branch.repository.get_revision(r.rev_id)
568
594
            try:
569
595
                revision_id = branch.get_rev_id(revno, revs)
570
596
            except (errors.NoSuchRevision, errors.RevnoOutOfBounds):
571
 
                raise errors.InvalidRevisionSpec(self.user_spec,
572
 
                                                 branch)
 
597
                raise InvalidRevisionSpec(self.user_spec, branch)
573
598
        return RevisionInfo(branch, revno, revision_id)
574
599
 
575
600
    def _as_revision_id(self, context_branch):
576
601
        base_revision_id = RevisionSpec.from_string(
577
602
            self.spec)._as_revision_id(context_branch)
578
603
        if base_revision_id == revision.NULL_REVISION:
579
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
580
 
                                             'cannot go before the null: revision')
 
604
            raise InvalidRevisionSpec(
 
605
                self.user_spec, context_branch,
 
606
                'cannot go before the null: revision')
581
607
        context_repo = context_branch.repository
582
608
        with context_repo.lock_read():
583
609
            parent_map = context_repo.get_parent_map([base_revision_id])
584
610
        if base_revision_id not in parent_map:
585
611
            # Ghost, or unknown revision id
586
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
587
 
                                             'cannot find the matching revision')
 
612
            raise InvalidRevisionSpec(
 
613
                self.user_spec, context_branch, 'cannot find the matching revision')
588
614
        parents = parent_map[base_revision_id]
589
615
        if len(parents) < 1:
590
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
591
 
                                             'No parents for revision.')
 
616
            raise InvalidRevisionSpec(
 
617
                self.user_spec, context_branch, 'No parents for revision.')
592
618
        return parents[0]
593
619
 
594
620
 
678
704
        else:
679
705
            m = self._date_regex.match(self.spec)
680
706
            if not m or (not m.group('date') and not m.group('time')):
681
 
                raise errors.InvalidRevisionSpec(self.user_spec,
682
 
                                                 branch, 'invalid date')
 
707
                raise InvalidRevisionSpec(
 
708
                    self.user_spec, branch, 'invalid date')
683
709
 
684
710
            try:
685
711
                if m.group('date'):
701
727
                else:
702
728
                    hour, minute, second = 0, 0, 0
703
729
            except ValueError:
704
 
                raise errors.InvalidRevisionSpec(self.user_spec,
705
 
                                                 branch, 'invalid date')
 
730
                raise InvalidRevisionSpec(
 
731
                    self.user_spec, branch, 'invalid date')
706
732
 
707
733
            dt = datetime.datetime(year=year, month=month, day=day,
708
734
                                   hour=hour, minute=minute, second=second)
709
735
        with branch.lock_read():
710
736
            rev = bisect.bisect(_RevListToTimestamps(branch), dt, 1)
711
737
        if rev == branch.revno():
712
 
            raise errors.InvalidRevisionSpec(self.user_spec, branch)
 
738
            raise InvalidRevisionSpec(self.user_spec, branch)
713
739
        return RevisionInfo(branch, rev)
714
740
 
715
741
 
882
908
    """
883
909
 
884
910
    def _raise_invalid(self, numstring, context_branch):
885
 
        raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
886
 
                                         'No such line: %s' % numstring)
 
911
        raise InvalidRevisionSpec(
 
912
            self.user_spec, context_branch,
 
913
            'No such line: %s' % numstring)
887
914
 
888
915
    def _as_revision_id(self, context_branch):
889
916
        path, numstring = self.spec.rsplit(':', 1)
894
921
        tree, file_path = workingtree.WorkingTree.open_containing(path)
895
922
        with tree.lock_read():
896
923
            if not tree.has_filename(file_path):
897
 
                raise errors.InvalidRevisionSpec(self.user_spec,
898
 
                                                 context_branch, "File '%s' is not versioned." %
899
 
                                                 file_path)
 
924
                raise InvalidRevisionSpec(
 
925
                    self.user_spec, context_branch,
 
926
                    "File '%s' is not versioned." % file_path)
900
927
            revision_ids = [r for (r, l) in tree.annotate_iter(file_path)]
901
928
        try:
902
929
            revision_id = revision_ids[index]
903
930
        except IndexError:
904
931
            self._raise_invalid(numstring, context_branch)
905
932
        if revision_id == revision.CURRENT_REVISION:
906
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
907
 
                                             'Line %s has not been committed.' % numstring)
 
933
            raise InvalidRevisionSpec(
 
934
                self.user_spec, context_branch,
 
935
                'Line %s has not been committed.' % numstring)
908
936
        return revision_id
909
937
 
910
938
 
928
956
        result = graph.find_lefthand_merger(revision_id,
929
957
                                            context_branch.last_revision())
930
958
        if result is None:
931
 
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch)
 
959
            raise InvalidRevisionSpec(self.user_spec, context_branch)
932
960
        return result
933
961
 
934
962