~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: aaron.bentley at utoronto
  • Date: 2005-08-27 04:42:41 UTC
  • mfrom: (1092.1.43)
  • mto: (1185.3.4)
  • mto: This revision was merged to the branch mainline in revision 1178.
  • Revision ID: aaron.bentley@utoronto.ca-20050827044241-23d676133b9fc981
Merge of robertc@robertcollins.net-20050826013321-52eee1f1da679ee9

Show diffs side-by-side

added added

removed removed

Lines of Context:
404
404
                         """Inventory for the working copy.""")
405
405
 
406
406
 
407
 
    def add(self, files, ids=None):
 
407
    def add(self, files, verbose=False, ids=None):
408
408
        """Make files versioned.
409
409
 
410
 
        Note that the command line normally calls smart_add instead,
411
 
        which can automatically recurse.
 
410
        Note that the command line normally calls smart_add instead.
412
411
 
413
412
        This puts the files in the Added state, so that they will be
414
413
        recorded by the next commit.
424
423
        TODO: Perhaps have an option to add the ids even if the files do
425
424
              not (yet) exist.
426
425
 
427
 
        TODO: Perhaps yield the ids and paths as they're added.
 
426
        TODO: Perhaps return the ids of the files?  But then again it
 
427
              is easy to retrieve them if they're needed.
 
428
 
 
429
        TODO: Adding a directory should optionally recurse down and
 
430
              add all non-ignored children.  Perhaps do that in a
 
431
              higher-level method.
428
432
        """
429
433
        # TODO: Re-adding a file that is removed in the working copy
430
434
        # should probably put it back with the previous ID.
466
470
                    file_id = gen_file_id(f)
467
471
                inv.add_path(f, kind=kind, file_id=file_id)
468
472
 
 
473
                if verbose:
 
474
                    print 'added', quotefn(f)
 
475
 
469
476
                mutter("add file %s file_id:{%s} kind=%r" % (f, file_id, kind))
470
477
 
471
478
            self._write_inventory(inv)
876
883
 
877
884
    def lookup_revision(self, revision):
878
885
        """Return the revision identifier for a given revision information."""
879
 
        revno, info = self.get_revision_info(revision)
 
886
        revno, info = self._get_revision_info(revision)
880
887
        return info
881
888
 
882
889
 
897
904
        revision can also be a string, in which case it is parsed for something like
898
905
            'date:' or 'revid:' etc.
899
906
        """
 
907
        revno, rev_id = self._get_revision_info(revision)
 
908
        if revno is None:
 
909
            raise bzrlib.errors.NoSuchRevision(self, revision)
 
910
        return revno, rev_id
 
911
 
 
912
    def get_rev_id(self, revno, history=None):
 
913
        """Find the revision id of the specified revno."""
 
914
        if revno == 0:
 
915
            return None
 
916
        if history is None:
 
917
            history = self.revision_history()
 
918
        elif revno <= 0 or revno > len(history):
 
919
            raise bzrlib.errors.NoSuchRevision(self, revno)
 
920
        return history[revno - 1]
 
921
 
 
922
    def _get_revision_info(self, revision):
 
923
        """Return (revno, revision id) for revision specifier.
 
924
 
 
925
        revision can be an integer, in which case it is assumed to be revno
 
926
        (though this will translate negative values into positive ones)
 
927
        revision can also be a string, in which case it is parsed for something
 
928
        like 'date:' or 'revid:' etc.
 
929
 
 
930
        A revid is always returned.  If it is None, the specifier referred to
 
931
        the null revision.  If the revid does not occur in the revision
 
932
        history, revno will be None.
 
933
        """
 
934
        
900
935
        if revision is None:
901
936
            return 0, None
902
937
        revno = None
906
941
            pass
907
942
        revs = self.revision_history()
908
943
        if isinstance(revision, int):
909
 
            if revision == 0:
910
 
                return 0, None
911
 
            # Mabye we should do this first, but we don't need it if revision == 0
912
944
            if revision < 0:
913
945
                revno = len(revs) + revision + 1
914
946
            else:
915
947
                revno = revision
 
948
            rev_id = self.get_rev_id(revno, revs)
916
949
        elif isinstance(revision, basestring):
917
950
            for prefix, func in Branch.REVISION_NAMESPACES.iteritems():
918
951
                if revision.startswith(prefix):
919
 
                    revno = func(self, revs, revision)
 
952
                    result = func(self, revs, revision)
 
953
                    if len(result) > 1:
 
954
                        revno, rev_id = result
 
955
                    else:
 
956
                        revno = result[0]
 
957
                        rev_id = self.get_rev_id(revno, revs)
920
958
                    break
921
959
            else:
922
 
                raise BzrError('No namespace registered for string: %r' % revision)
 
960
                raise BzrError('No namespace registered for string: %r' %
 
961
                               revision)
 
962
        else:
 
963
            raise TypeError('Unhandled revision type %s' % revision)
923
964
 
924
 
        if revno is None or revno <= 0 or revno > len(revs):
925
 
            raise BzrError("no such revision %s" % revision)
926
 
        return revno, revs[revno-1]
 
965
        if revno is None:
 
966
            if rev_id is None:
 
967
                raise bzrlib.errors.NoSuchRevision(self, revision)
 
968
        return revno, rev_id
927
969
 
928
970
    def _namespace_revno(self, revs, revision):
929
971
        """Lookup a revision by revision number"""
930
972
        assert revision.startswith('revno:')
931
973
        try:
932
 
            return int(revision[6:])
 
974
            return (int(revision[6:]),)
933
975
        except ValueError:
934
976
            return None
935
977
    REVISION_NAMESPACES['revno:'] = _namespace_revno
936
978
 
937
979
    def _namespace_revid(self, revs, revision):
938
980
        assert revision.startswith('revid:')
 
981
        rev_id = revision[len('revid:'):]
939
982
        try:
940
 
            return revs.index(revision[6:]) + 1
 
983
            return revs.index(rev_id) + 1, rev_id
941
984
        except ValueError:
942
 
            return None
 
985
            return None, rev_id
943
986
    REVISION_NAMESPACES['revid:'] = _namespace_revid
944
987
 
945
988
    def _namespace_last(self, revs, revision):
947
990
        try:
948
991
            offset = int(revision[5:])
949
992
        except ValueError:
950
 
            return None
 
993
            return (None,)
951
994
        else:
952
995
            if offset <= 0:
953
996
                raise BzrError('You must supply a positive value for --revision last:XXX')
954
 
            return len(revs) - offset + 1
 
997
            return (len(revs) - offset + 1,)
955
998
    REVISION_NAMESPACES['last:'] = _namespace_last
956
999
 
957
1000
    def _namespace_tag(self, revs, revision):
1032
1075
                # TODO: Handle timezone.
1033
1076
                dt = datetime.datetime.fromtimestamp(r.timestamp)
1034
1077
                if first >= dt and (last is None or dt >= last):
1035
 
                    return i+1
 
1078
                    return (i+1,)
1036
1079
        else:
1037
1080
            for i in range(len(revs)):
1038
1081
                r = self.get_revision(revs[i])
1039
1082
                # TODO: Handle timezone.
1040
1083
                dt = datetime.datetime.fromtimestamp(r.timestamp)
1041
1084
                if first <= dt and (last is None or dt <= last):
1042
 
                    return i+1
 
1085
                    return (i+1,)
1043
1086
    REVISION_NAMESPACES['date:'] = _namespace_date
1044
1087
 
1045
1088
    def revision_tree(self, revision_id):
1110
1153
 
1111
1154
            inv.rename(file_id, to_dir_id, to_tail)
1112
1155
 
 
1156
            print "%s => %s" % (from_rel, to_rel)
 
1157
 
1113
1158
            from_abs = self.abspath(from_rel)
1114
1159
            to_abs = self.abspath(to_rel)
1115
1160
            try:
1134
1179
 
1135
1180
        Note that to_name is only the last component of the new name;
1136
1181
        this doesn't change the directory.
1137
 
 
1138
 
        This returns a list of (from_path, to_path) pairs for each
1139
 
        entry that is moved.
1140
1182
        """
1141
 
        result = []
1142
1183
        self.lock_write()
1143
1184
        try:
1144
1185
            ## TODO: Option to move IDs only
1179
1220
            for f in from_paths:
1180
1221
                name_tail = splitpath(f)[-1]
1181
1222
                dest_path = appendpath(to_name, name_tail)
1182
 
                result.append((f, dest_path))
 
1223
                print "%s => %s" % (f, dest_path)
1183
1224
                inv.rename(inv.path2id(f), to_dir_id, name_tail)
1184
1225
                try:
1185
1226
                    os.rename(self.abspath(f), self.abspath(dest_path))
1191
1232
        finally:
1192
1233
            self.unlock()
1193
1234
 
1194
 
        return result
1195
 
 
1196
1235
 
1197
1236
    def revert(self, filenames, old_tree=None, backups=True):
1198
1237
        """Restore selected files to the versions from a previous tree.