~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Martin Pool
  • Date: 2005-08-29 10:57:01 UTC
  • mfrom: (1092.1.41)
  • Revision ID: mbp@sourcefrog.net-20050829105701-7aaa81ecf1bfee05
- merge in merge improvements and additional tests 
  from aaron and lifeless

robertc@robertcollins.net-20050825131100-85772edabc817481

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