~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Martin Pool
  • Date: 2006-01-23 02:09:39 UTC
  • mfrom: (1534.1.11 integration)
  • Revision ID: mbp@sourcefrog.net-20060123020939-567fb193328ed7a6
[merge] robert's integration

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import os
21
21
import errno
22
22
from warnings import warn
 
23
import xml.sax.saxutils
23
24
from cStringIO import StringIO
24
25
 
25
26
 
508
509
        """
509
510
        raise NotImplementedError('fileid_involved_by_set is abstract')
510
511
 
 
512
    def fileid_involved_between_revs(self, from_revid, to_revid):
 
513
        """ This function returns the file_id(s) involved in the
 
514
            changes between the from_revid revision and the to_revid
 
515
            revision
 
516
        """
 
517
        raise NotImplementedError('fileid_involved_between_revs is abstract')
 
518
 
 
519
    def fileid_involved(self, last_revid=None):
 
520
        """ This function returns the file_id(s) involved in the
 
521
            changes up to the revision last_revid
 
522
            If no parametr is passed, then all file_id[s] present in the
 
523
            repository are returned
 
524
        """
 
525
        raise NotImplementedError('fileid_involved is abstract')
 
526
 
 
527
    def fileid_involved_by_set(self, changes):
 
528
        """ This function returns the file_id(s) involved in the
 
529
            changes present in the set 'changes'
 
530
        """
 
531
        raise NotImplementedError('fileid_involved_by_set is abstract')
 
532
 
 
533
 
511
534
class BzrBranch(Branch):
512
535
    """A branch stored in the actual filesystem.
513
536
 
828
851
            ('pending-merges', ''),
829
852
            ('inventory', empty_inv),
830
853
            ('inventory.weave', empty_weave),
831
 
            ('ancestry.weave', empty_weave)
832
854
        ]
833
855
        self._transport.mkdir_multi([cfn(d) for d in dirs], mode=self._dir_mode)
834
856
        self.put_controlfiles(files)
1137
1159
                                revision_id, "sig")
1138
1160
 
1139
1161
    def fileid_involved_between_revs(self, from_revid, to_revid):
1140
 
        """ This function returns the file_id(s) involved in the
1141
 
            changes between the from_revid revision and the to_revid
1142
 
            revision
 
1162
        """Find file_id(s) which are involved in the changes between revisions.
 
1163
 
 
1164
        This determines the set of revisions which are involved, and then
 
1165
        finds all file ids affected by those revisions.
1143
1166
        """
1144
 
        w = self._get_inventory_weave( )
 
1167
        # TODO: jam 20060119 This code assumes that w.inclusions will
 
1168
        #       always be correct. But because of the presence of ghosts
 
1169
        #       it is possible to be wrong.
 
1170
        #       One specific example from Robert Collins:
 
1171
        #       Two branches, with revisions ABC, and AD
 
1172
        #       C is a ghost merge of D.
 
1173
        #       Inclusions doesn't recognize D as an ancestor.
 
1174
        #       If D is ever merged in the future, the weave
 
1175
        #       won't be fixed, because AD never saw revision C
 
1176
        #       to cause a conflict which would force a reweave.
 
1177
        w = self._get_inventory_weave()
1145
1178
        from_set = set(w.inclusions([w.lookup(from_revid)]))
1146
1179
        to_set = set(w.inclusions([w.lookup(to_revid)]))
1147
1180
        included = to_set.difference(from_set)
1148
 
        changed = map(w.idx_to_name,included)
 
1181
        changed = map(w.idx_to_name, included)
1149
1182
        return self._fileid_involved_by_set(changed)
1150
1183
 
1151
1184
    def fileid_involved(self, last_revid=None):
1152
 
        """ This function returns the file_id(s) involved in the
1153
 
            changes up to the revision last_revid
1154
 
            If no parametr is passed, then all file_id[s] present in the
1155
 
            repository are returned
 
1185
        """Find all file_ids modified in the ancestry of last_revid.
 
1186
 
 
1187
        :param last_revid: If None, last_revision() will be used.
1156
1188
        """
1157
 
        w = self._get_inventory_weave( )
 
1189
        w = self._get_inventory_weave()
1158
1190
        if not last_revid:
1159
1191
            changed = set(w._names)
1160
1192
        else:
1163
1195
        return self._fileid_involved_by_set(changed)
1164
1196
 
1165
1197
    def fileid_involved_by_set(self, changes):
1166
 
        """ This function returns the file_id(s) involved in the
1167
 
            changese present in the set changes
 
1198
        """Find all file_ids modified by the set of revisions passed in.
 
1199
 
 
1200
        :param changes: A set() of revision ids
1168
1201
        """
1169
 
        w = self._get_inventory_weave( )
 
1202
        # TODO: jam 20060119 This line does *nothing*, remove it.
 
1203
        #       or better yet, change _fileid_involved_by_set so
 
1204
        #       that it takes the inventory weave, rather than
 
1205
        #       pulling it out by itself.
 
1206
        w = self._get_inventory_weave()
1170
1207
        return self._fileid_involved_by_set(changes)
1171
1208
 
1172
1209
    def _fileid_involved_by_set(self, changes):
1173
 
        w = self._get_inventory_weave( )
1174
 
        file_ids = set( )
 
1210
        """Find the set of file-ids affected by the set of revisions.
 
1211
 
 
1212
        :param changes: A set() of revision ids.
 
1213
        :return: A set() of file ids.
 
1214
        
 
1215
        This peaks at the Weave, interpreting each line, looking to
 
1216
        see if it mentions one of the revisions. And if so, includes
 
1217
        the file id mentioned.
 
1218
        This expects both the Weave format, and the serialization
 
1219
        to have a single line per file/directory, and to have
 
1220
        fileid="" and revision="" on that line.
 
1221
        """
 
1222
        assert self._branch_format in (5, 6), \
 
1223
            "fileid_involved only supported for branches which store inventory as xml"
 
1224
 
 
1225
        w = self._get_inventory_weave()
 
1226
        file_ids = set()
1175
1227
        for line in w._weave:
1176
1228
 
1177
1229
            # it is ugly, but it is due to the weave structure
1178
 
            if not isinstance(line,basestring): continue
 
1230
            if not isinstance(line, basestring): continue
1179
1231
 
1180
1232
            start = line.find('file_id="')+9
1181
1233
            if start < 9: continue
1182
 
            end = line.find('"',start)
 
1234
            end = line.find('"', start)
1183
1235
            assert end>= 0
1184
 
            file_id = line[start:end]
 
1236
            file_id = xml.sax.saxutils.unescape(line[start:end])
1185
1237
 
1186
1238
            # check if file_id is already present
1187
1239
            if file_id in file_ids: continue
1188
1240
 
1189
1241
            start = line.find('revision="')+10
1190
1242
            if start < 10: continue
1191
 
            end = line.find('"',start)
 
1243
            end = line.find('"', start)
1192
1244
            assert end>= 0
1193
 
            revision_id = line[start:end]
 
1245
            revision_id = xml.sax.saxutils.unescape(line[start:end])
1194
1246
 
1195
1247
            if revision_id in changes:
1196
1248
                file_ids.add(file_id)
1261
1313
    filename = normpath(filename)
1262
1314
    while filename != '':
1263
1315
        head, tail = os.path.split(filename)
1264
 
        ## mutter('check %r for control file' % ((head, tail), ))
 
1316
        ## mutter('check %r for control file' % ((head, tail),))
1265
1317
        if tail == bzrlib.BZRDIR:
1266
1318
            return True
1267
1319
        if filename == head: