~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

MergeĀ fromĀ jam-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
 
511
533
class BzrBranch(Branch):
512
534
    """A branch stored in the actual filesystem.
513
535
 
828
850
            ('pending-merges', ''),
829
851
            ('inventory', empty_inv),
830
852
            ('inventory.weave', empty_weave),
831
 
            ('ancestry.weave', empty_weave)
832
853
        ]
833
854
        self._transport.mkdir_multi([cfn(d) for d in dirs], mode=self._dir_mode)
834
855
        self.put_controlfiles(files)
1137
1158
                                revision_id, "sig")
1138
1159
 
1139
1160
    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
 
1161
        """Find file_id(s) which are involved in the changes between revisions.
 
1162
 
 
1163
        This determines the set of revisions which are involved, and then
 
1164
        finds all file ids affected by those revisions.
1143
1165
        """
 
1166
        # TODO: jam 20060119 This code assumes that w.inclusions will
 
1167
        #       always be correct. But because of the presence of ghosts
 
1168
        #       it is possible to be wrong.
 
1169
        #       One specific example from Robert Collins:
 
1170
        #       Two branches, with revisions ABC, and AD
 
1171
        #       C is a ghost merge of D.
 
1172
        #       Inclusions doesn't recognize D as an ancestor.
 
1173
        #       If D is ever merged in the future, the weave
 
1174
        #       won't be fixed, because AD never saw revision C
 
1175
        #       to cause a conflict which would force a reweave.
1144
1176
        w = self._get_inventory_weave( )
1145
1177
        from_set = set(w.inclusions([w.lookup(from_revid)]))
1146
1178
        to_set = set(w.inclusions([w.lookup(to_revid)]))
1149
1181
        return self._fileid_involved_by_set(changed)
1150
1182
 
1151
1183
    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
 
1184
        """Find all file_ids modified in the ancestry of last_revid.
 
1185
 
 
1186
        :param last_revid: If None, last_revision() will be used.
1156
1187
        """
1157
1188
        w = self._get_inventory_weave( )
1158
1189
        if not last_revid:
1163
1194
        return self._fileid_involved_by_set(changed)
1164
1195
 
1165
1196
    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
 
1197
        """Find all file_ids modified by the set of revisions passed in.
 
1198
 
 
1199
        :param changes: A set() of revision ids
1168
1200
        """
 
1201
        # TODO: jam 20060119 This line does *nothing*, remove it.
 
1202
        #       or better yet, change _fileid_involved_by_set so
 
1203
        #       that it takes the inventory weave, rather than
 
1204
        #       pulling it out by itself.
1169
1205
        w = self._get_inventory_weave( )
1170
1206
        return self._fileid_involved_by_set(changes)
1171
1207
 
1172
1208
    def _fileid_involved_by_set(self, changes):
 
1209
        """Find the set of file-ids affected by the set of revisions.
 
1210
 
 
1211
        :param changes: A set() of revision ids.
 
1212
        :return: A set() of file ids.
 
1213
        
 
1214
        This peaks at the Weave, interpreting each line, looking to
 
1215
        see if it mentions one of the revisions. And if so, includes
 
1216
        the file id mentioned.
 
1217
        This expects both the Weave format, and the serialization
 
1218
        to have a single line per file/directory, and to have
 
1219
        fileid="" and revision="" on that line.
 
1220
        """
 
1221
        assert self._branch_format in (5,6), \
 
1222
            "fileid_involved only supported for branches which store inventory as xml"
 
1223
 
1173
1224
        w = self._get_inventory_weave( )
1174
1225
        file_ids = set( )
1175
1226
        for line in w._weave:
1181
1232
            if start < 9: continue
1182
1233
            end = line.find('"',start)
1183
1234
            assert end>= 0
1184
 
            file_id = line[start:end]
 
1235
            file_id = xml.sax.saxutils.unescape(line[start:end])
1185
1236
 
1186
1237
            # check if file_id is already present
1187
1238
            if file_id in file_ids: continue
1190
1241
            if start < 10: continue
1191
1242
            end = line.find('"',start)
1192
1243
            assert end>= 0
1193
 
            revision_id = line[start:end]
 
1244
            revision_id = xml.sax.saxutils.unescape(line[start:end])
1194
1245
 
1195
1246
            if revision_id in changes:
1196
1247
                file_ids.add(file_id)