~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/dirstate.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-07-29 05:19:09 UTC
  • mfrom: (4570.2.1 refactor-dirstate)
  • Revision ID: pqm@pqm.ubuntu.com-20090729051909-5t1y5hnh1pb7lalk
(robertc) Refactor dirstate to permit iter_changes changes to use
        calculated info about whether changes have occured. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
3164
3164
 
3165
3165
class ProcessEntryPython(object):
3166
3166
 
3167
 
    __slots__ = ["old_dirname_to_file_id", "new_dirname_to_file_id", "uninteresting",
 
3167
    __slots__ = ["old_dirname_to_file_id", "new_dirname_to_file_id",
3168
3168
        "last_source_parent", "last_target_parent", "include_unchanged",
3169
3169
        "use_filesystem_for_exec", "utf8_decode", "searched_specific_files",
3170
3170
        "search_specific_files", "state", "source_index", "target_index",
3175
3175
        want_unversioned, tree):
3176
3176
        self.old_dirname_to_file_id = {}
3177
3177
        self.new_dirname_to_file_id = {}
3178
 
        # Just a sentry, so that _process_entry can say that this
3179
 
        # record is handled, but isn't interesting to process (unchanged)
3180
 
        self.uninteresting = object()
3181
3178
        # Using a list so that we can access the values and change them in
3182
3179
        # nested scope. Each one is [path, file_id, entry]
3183
3180
        self.last_source_parent = [None, None]
3206
3203
            Basename is returned as a utf8 string because we expect this
3207
3204
            tuple will be ignored, and don't want to take the time to
3208
3205
            decode.
3209
 
        :return: None if these don't match
3210
 
                 A tuple of information about the change, or
3211
 
                 the object 'uninteresting' if these match, but are
3212
 
                 basically identical.
 
3206
        :return: (iter_changes_result, changed). If the entry has not been
 
3207
            handled then changed is None. Otherwise it is False if no content
 
3208
            or metadata changes have occured, and None if any content or
 
3209
            metadata change has occured. If self.include_unchanged is True then
 
3210
            if changed is not None, iter_changes_result will always be a result
 
3211
            tuple. Otherwise, iter_changes_result is None unless changed is
 
3212
            True.
3213
3213
        """
3214
3214
        if self.source_index is None:
3215
3215
            source_details = DirState.NULL_PARENT_DETAILS
3320
3320
                    old_path = path = pathjoin(old_dirname, old_basename)
3321
3321
                self.old_dirname_to_file_id[old_path] = file_id
3322
3322
            # parent id is the entry for the path in the target tree
3323
 
            if old_dirname == self.last_source_parent[0]:
 
3323
            if old_basename and old_dirname == self.last_source_parent[0]:
3324
3324
                source_parent_id = self.last_source_parent[1]
3325
3325
            else:
3326
3326
                try:
3336
3336
                    self.last_source_parent[0] = old_dirname
3337
3337
                    self.last_source_parent[1] = source_parent_id
3338
3338
            new_dirname = entry[0][0]
3339
 
            if new_dirname == self.last_target_parent[0]:
 
3339
            if entry[0][1] and new_dirname == self.last_target_parent[0]:
3340
3340
                target_parent_id = self.last_target_parent[1]
3341
3341
            else:
3342
3342
                try:
3359
3359
                    self.last_target_parent[1] = target_parent_id
3360
3360
 
3361
3361
            source_exec = source_details[3]
3362
 
            if (self.include_unchanged
3363
 
                or content_change
 
3362
            changed = (content_change
3364
3363
                or source_parent_id != target_parent_id
3365
3364
                or old_basename != entry[0][1]
3366
3365
                or source_exec != target_exec
3367
 
                ):
 
3366
                )
 
3367
            if not changed and not self.include_unchanged:
 
3368
                return None, False
 
3369
            else:
3368
3370
                if old_path is None:
3369
3371
                    old_path = path = pathjoin(old_dirname, old_basename)
3370
3372
                    old_path_u = self.utf8_decode(old_path)[0]
3383
3385
                       (source_parent_id, target_parent_id),
3384
3386
                       (self.utf8_decode(old_basename)[0], self.utf8_decode(entry[0][1])[0]),
3385
3387
                       (source_kind, target_kind),
3386
 
                       (source_exec, target_exec))
3387
 
            else:
3388
 
                return self.uninteresting
 
3388
                       (source_exec, target_exec)), changed
3389
3389
        elif source_minikind in 'a' and target_minikind in 'fdlt':
3390
3390
            # looks like a new file
3391
3391
            path = pathjoin(entry[0][0], entry[0][1])
3412
3412
                       (None, parent_id),
3413
3413
                       (None, self.utf8_decode(entry[0][1])[0]),
3414
3414
                       (None, path_info[2]),
3415
 
                       (None, target_exec))
 
3415
                       (None, target_exec)), True
3416
3416
            else:
3417
3417
                # Its a missing file, report it as such.
3418
3418
                return (entry[0][2],
3422
3422
                       (None, parent_id),
3423
3423
                       (None, self.utf8_decode(entry[0][1])[0]),
3424
3424
                       (None, None),
3425
 
                       (None, False))
 
3425
                       (None, False)), True
3426
3426
        elif source_minikind in 'fdlt' and target_minikind in 'a':
3427
3427
            # unversioned, possibly, or possibly not deleted: we dont care.
3428
3428
            # if its still on disk, *and* theres no other entry at this
3440
3440
                   (parent_id, None),
3441
3441
                   (self.utf8_decode(entry[0][1])[0], None),
3442
3442
                   (DirState._minikind_to_kind[source_minikind], None),
3443
 
                   (source_details[3], None))
 
3443
                   (source_details[3], None)), True
3444
3444
        elif source_minikind in 'fdlt' and target_minikind in 'r':
3445
3445
            # a rename; could be a true rename, or a rename inherited from
3446
3446
            # a renamed parent. TODO: handle this efficiently. Its not
3458
3458
                "source_minikind=%r, target_minikind=%r"
3459
3459
                % (source_minikind, target_minikind))
3460
3460
            ## import pdb;pdb.set_trace()
3461
 
        return None
 
3461
        return None, None
3462
3462
 
3463
3463
    def __iter__(self):
3464
3464
        return self
3468
3468
        utf8_decode = cache_utf8._utf8_decode
3469
3469
        _cmp_by_dirs = cmp_by_dirs
3470
3470
        _process_entry = self._process_entry
3471
 
        uninteresting = self.uninteresting
3472
3471
        search_specific_files = self.search_specific_files
3473
3472
        searched_specific_files = self.searched_specific_files
3474
3473
        splitpath = osutils.splitpath
3544
3543
                continue
3545
3544
            path_handled = False
3546
3545
            for entry in root_entries:
3547
 
                result = _process_entry(entry, root_dir_info)
3548
 
                if result is not None:
 
3546
                result, changed = _process_entry(entry, root_dir_info)
 
3547
                if changed is not None:
3549
3548
                    path_handled = True
3550
 
                    if result is not uninteresting:
 
3549
                    if changed or self.include_unchanged:
3551
3550
                        yield result
3552
3551
            if self.want_unversioned and not path_handled and root_dir_info:
3553
3552
                new_executable = bool(
3663
3662
                        for current_entry in current_block[1]:
3664
3663
                            # entry referring to file not present on disk.
3665
3664
                            # advance the entry only, after processing.
3666
 
                            result = _process_entry(current_entry, None)
3667
 
                            if result is not None:
3668
 
                                if result is not uninteresting:
 
3665
                            result, changed = _process_entry(current_entry, None)
 
3666
                            if changed is not None:
 
3667
                                if changed or self.include_unchanged:
3669
3668
                                    yield result
3670
3669
                        block_index +=1
3671
3670
                        if (block_index < len(self.state._dirblocks) and
3701
3700
                        pass
3702
3701
                    elif current_path_info is None:
3703
3702
                        # no path is fine: the per entry code will handle it.
3704
 
                        result = _process_entry(current_entry, current_path_info)
3705
 
                        if result is not None:
3706
 
                            if result is not uninteresting:
 
3703
                        result, changed = _process_entry(current_entry, current_path_info)
 
3704
                        if changed is not None:
 
3705
                            if changed or self.include_unchanged:
3707
3706
                                yield result
3708
3707
                    elif (current_entry[0][1] != current_path_info[1]
3709
3708
                          or current_entry[1][self.target_index][0] in 'ar'):
3722
3721
                        else:
3723
3722
                            # entry referring to file not present on disk.
3724
3723
                            # advance the entry only, after processing.
3725
 
                            result = _process_entry(current_entry, None)
3726
 
                            if result is not None:
3727
 
                                if result is not uninteresting:
 
3724
                            result, changed = _process_entry(current_entry, None)
 
3725
                            if changed is not None:
 
3726
                                if changed or self.include_unchanged:
3728
3727
                                    yield result
3729
3728
                            advance_path = False
3730
3729
                    else:
3731
 
                        result = _process_entry(current_entry, current_path_info)
3732
 
                        if result is not None:
 
3730
                        result, changed = _process_entry(current_entry, current_path_info)
 
3731
                        if changed is not None:
3733
3732
                            path_handled = True
3734
 
                            if result is not uninteresting:
 
3733
                            if changed or self.include_unchanged:
3735
3734
                                yield result
3736
3735
                    if advance_entry and current_entry is not None:
3737
3736
                        entry_index += 1