~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

Merge HEAD.

Show diffs side-by-side

added added

removed removed

Lines of Context:
303
303
                                                         signature,
304
304
                                                         self.get_transaction())
305
305
 
306
 
    def fileid_involved_between_revs(self, from_revid, to_revid):
307
 
        """Find file_id(s) which are involved in the changes between revisions.
308
 
 
309
 
        This determines the set of revisions which are involved, and then
310
 
        finds all file ids affected by those revisions.
311
 
        """
312
 
        w = self.get_inventory_weave()
313
 
        from_set = set(w.get_ancestry(from_revid))
314
 
        to_set = set(w.get_ancestry(to_revid))
315
 
        changed = to_set.difference(from_set)
316
 
        return self._fileid_involved_by_set(changed)
317
 
 
318
 
    def fileid_involved(self, last_revid=None):
319
 
        """Find all file_ids modified in the ancestry of last_revid.
320
 
 
321
 
        :param last_revid: If None, last_revision() will be used.
322
 
        """
323
 
        w = self.get_inventory_weave()
324
 
        if not last_revid:
325
 
            changed = set(w.versions())
326
 
        else:
327
 
            changed = set(w.get_ancestry(last_revid))
328
 
        return self._fileid_involved_by_set(changed)
329
 
 
330
 
    def fileid_involved_by_set(self, changes):
331
 
        """Find all file_ids modified by the set of revisions passed in.
332
 
 
333
 
        :param changes: A set() of revision ids
334
 
        """
335
 
        # TODO: jam 20060119 This line does *nothing*, remove it.
336
 
        #       or better yet, change _fileid_involved_by_set so
337
 
        #       that it takes the inventory weave, rather than
338
 
        #       pulling it out by itself.
339
 
        return self._fileid_involved_by_set(changes)
340
 
 
341
 
    def _fileid_involved_by_set(self, changes):
342
 
        """Find the set of file-ids affected by the set of revisions.
343
 
 
344
 
        :param changes: A set() of revision ids.
345
 
        :return: A set() of file ids.
346
 
        
347
 
        This peaks at the Weave, interpreting each line, looking to
348
 
        see if it mentions one of the revisions. And if so, includes
349
 
        the file id mentioned.
350
 
        This expects both the Weave format, and the serialization
351
 
        to have a single line per file/directory, and to have
352
 
        fileid="" and revision="" on that line.
 
306
    def fileids_altered_by_revision_ids(self, revision_ids):
 
307
        """Find the file ids and versions affected by revisions.
 
308
 
 
309
        :param revisions: an iterable containing revision ids.
 
310
        :return: a dictionary mapping altered file-ids to an iterable of
 
311
        revision_ids. Each altered file-ids has the exact revision_ids that
 
312
        altered it listed explicitly.
353
313
        """
354
314
        assert isinstance(self._format, (RepositoryFormat5,
355
315
                                         RepositoryFormat6,
356
316
                                         RepositoryFormat7,
357
317
                                         RepositoryFormatKnit1)), \
358
318
            "fileid_involved only supported for branches which store inventory as unnested xml"
359
 
 
 
319
        selected_revision_ids = set(revision_ids)
360
320
        w = self.get_inventory_weave()
361
 
        file_ids = set()
 
321
        result = {}
362
322
 
363
 
        # this code needs to read every line in every inventory for the
364
 
        # inventories [changes]. Seeing a line twice is ok. Seeing a line
365
 
        # not pesent in one of those inventories is unnecessary and not 
 
323
        # this code needs to read every new line in every inventory for the
 
324
        # inventories [revision_ids]. Seeing a line twice is ok. Seeing a line
 
325
        # not pesent in one of those inventories is unnecessary but not 
366
326
        # harmful because we are filtering by the revision id marker in the
367
 
        # inventory lines to only select file ids altered in one of those  
 
327
        # inventory lines : we only select file ids altered in one of those  
368
328
        # revisions. We dont need to see all lines in the inventory because
369
329
        # only those added in an inventory in rev X can contain a revision=X
370
330
        # line.
371
 
        for line in w.iter_lines_added_or_present_in_versions(changes):
 
331
        for line in w.iter_lines_added_or_present_in_versions(selected_revision_ids):
372
332
            start = line.find('file_id="')+9
373
333
            if start < 9: continue
374
334
            end = line.find('"', start)
375
335
            assert end>= 0
376
336
            file_id = _unescape_xml(line[start:end])
377
337
 
378
 
            # check if file_id is already present
379
 
            if file_id in file_ids: continue
380
 
 
381
338
            start = line.find('revision="')+10
382
339
            if start < 10: continue
383
340
            end = line.find('"', start)
384
341
            assert end>= 0
385
342
            revision_id = _unescape_xml(line[start:end])
386
 
            if revision_id in changes:
387
 
                file_ids.add(file_id)
388
 
        return file_ids
 
343
            if revision_id in selected_revision_ids:
 
344
                result.setdefault(file_id, set()).add(revision_id)
 
345
        return result
389
346
 
390
347
    @needs_read_lock
391
348
    def get_inventory_weave(self):
497
454
        raise NotImplementedError(self.is_shared)
498
455
 
499
456
    @needs_write_lock
500
 
    def reconcile(self):
 
457
    def reconcile(self, other=None, thorough=False):
501
458
        """Reconcile this repository."""
502
459
        from bzrlib.reconcile import RepoReconciler
503
 
        reconciler = RepoReconciler(self)
 
460
        reconciler = RepoReconciler(self, thorough=thorough)
504
461
        reconciler.reconcile()
505
462
        return reconciler
506
463
    
814
771
        return vf
815
772
 
816
773
    @needs_write_lock
817
 
    def reconcile(self):
 
774
    def reconcile(self, other=None, thorough=False):
818
775
        """Reconcile this repository."""
819
776
        from bzrlib.reconcile import KnitReconciler
820
 
        reconciler = KnitReconciler(self)
 
777
        reconciler = KnitReconciler(self, thorough=thorough)
821
778
        reconciler.reconcile()
822
779
        return reconciler
823
780