~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree_4.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-04-26 15:39:04 UTC
  • mfrom: (2456.2.6 rename_iter_changes_109993)
  • Revision ID: pqm@pqm.ubuntu.com-20070426153904-l91p9ybsqpxt2vyv
(John Arbash Meinel) Fix bug #109993 by fixing _iter_changes to not sync an on-disk file with an 'absent' dirblock record.

Show diffs side-by-side

added added

removed removed

Lines of Context:
52
52
    ignores,
53
53
    merge,
54
54
    osutils,
55
 
    revision as _mod_revision,
56
55
    revisiontree,
57
56
    textui,
58
57
    transform,
414
413
 
415
414
        file_abspath = self.abspath(path)
416
415
        state = self.current_dirstate()
417
 
        if stat_value is None:
418
 
            try:
419
 
                stat_value = os.lstat(file_abspath)
420
 
            except OSError, e:
421
 
                if e.errno == errno.ENOENT:
422
 
                    return None
423
 
                else:
424
 
                    raise
425
416
        link_or_sha1 = state.update_entry(entry, file_abspath,
426
417
                                          stat_value=stat_value)
427
418
        if entry[1][0][0] == 'f':
473
464
 
474
465
    @needs_read_lock
475
466
    def id2path(self, file_id):
476
 
        "Convert a file-id to a path."
477
467
        file_id = osutils.safe_file_id(file_id)
478
468
        state = self.current_dirstate()
479
469
        entry = self._get_entry(file_id=file_id)
483
473
        return path_utf8.decode('utf8')
484
474
 
485
475
    if not osutils.supports_executable():
 
476
        @needs_read_lock
486
477
        def is_executable(self, file_id, path=None):
487
 
            """Test if a file is executable or not.
488
 
 
489
 
            Note: The caller is expected to take a read-lock before calling this.
490
 
            """
491
478
            file_id = osutils.safe_file_id(file_id)
492
479
            entry = self._get_entry(file_id=file_id, path=path)
493
480
            if entry == (None, None):
494
481
                return False
495
482
            return entry[1][0][3]
496
483
    else:
 
484
        @needs_read_lock
497
485
        def is_executable(self, file_id, path=None):
498
 
            """Test if a file is executable or not.
499
 
 
500
 
            Note: The caller is expected to take a read-lock before calling this.
501
 
            """
502
486
            if not path:
503
487
                file_id = osutils.safe_file_id(file_id)
504
488
                path = self.id2path(file_id)
538
522
                # path is missing on disk.
539
523
                continue
540
524
 
 
525
    @needs_read_lock
541
526
    def kind(self, file_id):
542
527
        """Return the kind of a file.
543
528
 
544
529
        This is always the actual kind that's on disk, regardless of what it
545
530
        was added as.
546
 
 
547
 
        Note: The caller is expected to take a read-lock before calling this.
548
531
        """
549
532
        relpath = self.id2path(file_id)
550
533
        assert relpath != None, \
1069
1052
            except (errors.NoSuchRevision, errors.RevisionNotPresent):
1070
1053
                revtree = None
1071
1054
            trees.append((revision_id, revtree))
 
1055
        self.current_dirstate()._validate()
1072
1056
        self.set_parent_trees(trees,
1073
1057
            allow_leftmost_as_ghost=allow_leftmost_as_ghost)
 
1058
        self.current_dirstate()._validate()
1074
1059
 
1075
1060
    @needs_tree_write_lock
1076
1061
    def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
1081
1066
            parent tree - i.e. a ghost.
1082
1067
        """
1083
1068
        dirstate = self.current_dirstate()
 
1069
        dirstate._validate()
1084
1070
        if len(parents_list) > 0:
1085
1071
            if not allow_leftmost_as_ghost and parents_list[0][1] is None:
1086
1072
                raise errors.GhostRevisionUnusableHere(parents_list[0][0])
1090
1076
        # missing on access.
1091
1077
        for rev_id, tree in parents_list:
1092
1078
            rev_id = osutils.safe_revision_id(rev_id)
1093
 
            _mod_revision.check_not_reserved_id(rev_id)
1094
1079
            if tree is not None:
1095
1080
                real_trees.append((rev_id, tree))
1096
1081
            else:
1097
1082
                real_trees.append((rev_id,
1098
1083
                    self.branch.repository.revision_tree(None)))
1099
1084
                ghosts.append(rev_id)
 
1085
        dirstate._validate()
1100
1086
        dirstate.set_parent_trees(real_trees, ghosts=ghosts)
 
1087
        dirstate._validate()
1101
1088
        self._make_dirty(reset_inventory=False)
 
1089
        dirstate._validate()
1102
1090
 
1103
1091
    def _set_root_id(self, file_id):
1104
1092
        """See WorkingTree.set_root_id."""
1287
1275
                         _control_files=control_files)
1288
1276
        wt._new_tree()
1289
1277
        wt.lock_tree_write()
 
1278
        wt.current_dirstate()._validate()
1290
1279
        try:
1291
1280
            if revision_id in (None, NULL_REVISION):
1292
1281
                if branch.repository.supports_rich_root():
1294
1283
                else:
1295
1284
                    wt._set_root_id(ROOT_ID)
1296
1285
                wt.flush()
 
1286
                wt.current_dirstate()._validate()
1297
1287
            wt.set_last_revision(revision_id)
1298
1288
            wt.flush()
1299
1289
            basis = wt.basis_tree()
1490
1480
            return parent_details[1]
1491
1481
        return None
1492
1482
 
1493
 
    def get_weave(self, file_id):
1494
 
        return self._repository.weave_store.get_weave(file_id,
1495
 
                self._repository.get_transaction())
1496
 
 
1497
1483
    def get_file(self, file_id):
1498
1484
        return StringIO(self.get_file_text(file_id))
1499
1485
 
1680
1666
            output. An unversioned file is defined as one with (False, False)
1681
1667
            for the versioned pair.
1682
1668
        """
1683
 
        utf8_decode = cache_utf8._utf8_decode
 
1669
        utf8_decode_or_none = cache_utf8._utf8_decode_with_None
1684
1670
        _minikind_to_kind = dirstate.DirState._minikind_to_kind
1685
1671
        # NB: show_status depends on being able to pass in non-versioned files
1686
1672
        # and report them as unknown
1814
1800
        NULL_PARENT_DETAILS = dirstate.DirState.NULL_PARENT_DETAILS
1815
1801
        # Using a list so that we can access the values and change them in
1816
1802
        # nested scope. Each one is [path, file_id, entry]
1817
 
        last_source_parent = [None, None]
1818
 
        last_target_parent = [None, None]
 
1803
        last_source_parent = [None, None, None]
 
1804
        last_target_parent = [None, None, None]
1819
1805
 
1820
1806
        use_filesystem_for_exec = (sys.platform != 'win32')
1821
1807
 
1822
 
        # Just a sentry, so that _process_entry can say that this
1823
 
        # record is handled, but isn't interesting to process (unchanged)
1824
 
        uninteresting = object()
1825
 
 
1826
 
 
1827
 
        old_dirname_to_file_id = {}
1828
 
        new_dirname_to_file_id = {}
1829
 
        # TODO: jam 20070516 - Avoid the _get_entry lookup overhead by
1830
 
        #       keeping a cache of directories that we have seen.
1831
 
 
1832
1808
        def _process_entry(entry, path_info):
1833
1809
            """Compare an entry and real disk to generate delta information.
1834
1810
 
1838
1814
                Basename is returned as a utf8 string because we expect this
1839
1815
                tuple will be ignored, and don't want to take the time to
1840
1816
                decode.
1841
 
            :return: None if these don't match
1842
 
                     A tuple of information about the change, or
1843
 
                     the object 'uninteresting' if these match, but are
1844
 
                     basically identical.
1845
1817
            """
1846
1818
            if source_index is None:
1847
1819
                source_details = NULL_PARENT_DETAILS
1858
1830
                target_minikind = target_details[0]
1859
1831
            else:
1860
1832
                link_or_sha1 = None
1861
 
            file_id = entry[0][2]
1862
1833
            source_minikind = source_details[0]
1863
1834
            if source_minikind in 'fdltr' and target_minikind in 'fdlt':
1864
1835
                # claimed content in both: diff
1886
1857
                else:
1887
1858
                    old_dirname = entry[0][0]
1888
1859
                    old_basename = entry[0][1]
1889
 
                    old_path = path = None
 
1860
                    old_path = path = pathjoin(old_dirname, old_basename)
1890
1861
                if path_info is None:
1891
1862
                    # the file is missing on disk, show as removed.
1892
1863
                    content_change = True
1896
1867
                    # source and target are both versioned and disk file is present.
1897
1868
                    target_kind = path_info[2]
1898
1869
                    if target_kind == 'directory':
1899
 
                        if path is None:
1900
 
                            old_path = path = pathjoin(old_dirname, old_basename)
1901
 
                        new_dirname_to_file_id[path] = file_id
1902
1870
                        if source_minikind != 'd':
1903
1871
                            content_change = True
1904
1872
                        else:
1933
1901
                        target_exec = False
1934
1902
                    else:
1935
1903
                        raise Exception, "unknown kind %s" % path_info[2]
1936
 
                if source_minikind == 'd':
1937
 
                    if path is None:
1938
 
                        old_path = path = pathjoin(old_dirname, old_basename)
1939
 
                    old_dirname_to_file_id[old_path] = file_id
1940
1904
                # parent id is the entry for the path in the target tree
1941
1905
                if old_dirname == last_source_parent[0]:
1942
1906
                    source_parent_id = last_source_parent[1]
1943
1907
                else:
1944
 
                    try:
1945
 
                        source_parent_id = old_dirname_to_file_id[old_dirname]
1946
 
                    except KeyError:
1947
 
                        source_parent_entry = state._get_entry(source_index,
1948
 
                                                               path_utf8=old_dirname)
1949
 
                        source_parent_id = source_parent_entry[0][2]
 
1908
                    source_parent_entry = state._get_entry(source_index,
 
1909
                                                           path_utf8=old_dirname)
 
1910
                    source_parent_id = source_parent_entry[0][2]
1950
1911
                    if source_parent_id == entry[0][2]:
1951
1912
                        # This is the root, so the parent is None
1952
1913
                        source_parent_id = None
1953
1914
                    else:
1954
1915
                        last_source_parent[0] = old_dirname
1955
1916
                        last_source_parent[1] = source_parent_id
 
1917
                        last_source_parent[2] = source_parent_entry
1956
1918
                new_dirname = entry[0][0]
1957
1919
                if new_dirname == last_target_parent[0]:
1958
1920
                    target_parent_id = last_target_parent[1]
1959
1921
                else:
1960
 
                    try:
1961
 
                        target_parent_id = new_dirname_to_file_id[new_dirname]
1962
 
                    except KeyError:
1963
 
                        # TODO: We don't always need to do the lookup, because the
1964
 
                        #       parent entry will be the same as the source entry.
1965
 
                        target_parent_entry = state._get_entry(target_index,
1966
 
                                                               path_utf8=new_dirname)
1967
 
                        assert target_parent_entry != (None, None), (
1968
 
                            "Could not find target parent in wt: %s\nparent of: %s"
1969
 
                            % (new_dirname, entry))
1970
 
                        target_parent_id = target_parent_entry[0][2]
 
1922
                    # TODO: We don't always need to do the lookup, because the
 
1923
                    #       parent entry will be the same as the source entry.
 
1924
                    target_parent_entry = state._get_entry(target_index,
 
1925
                                                           path_utf8=new_dirname)
 
1926
                    assert target_parent_entry != (None, None), (
 
1927
                        "Could not find target parent in wt: %s\nparent of: %s"
 
1928
                        % (new_dirname, entry))
 
1929
                    target_parent_id = target_parent_entry[0][2]
1971
1930
                    if target_parent_id == entry[0][2]:
1972
1931
                        # This is the root, so the parent is None
1973
1932
                        target_parent_id = None
1974
1933
                    else:
1975
1934
                        last_target_parent[0] = new_dirname
1976
1935
                        last_target_parent[1] = target_parent_id
 
1936
                        last_target_parent[2] = target_parent_entry
1977
1937
 
1978
1938
                source_exec = source_details[3]
1979
 
                if (include_unchanged
1980
 
                    or content_change
1981
 
                    or source_parent_id != target_parent_id
1982
 
                    or old_basename != entry[0][1]
1983
 
                    or source_exec != target_exec
1984
 
                    ):
1985
 
                    if old_path is None:
1986
 
                        old_path = path = pathjoin(old_dirname, old_basename)
1987
 
                        old_path_u = utf8_decode(old_path)[0]
1988
 
                        path_u = old_path_u
1989
 
                    else:
1990
 
                        old_path_u = utf8_decode(old_path)[0]
1991
 
                        if old_path == path:
1992
 
                            path_u = old_path_u
1993
 
                        else:
1994
 
                            path_u = utf8_decode(path)[0]
1995
 
                    source_kind = _minikind_to_kind[source_minikind]
1996
 
                    return (entry[0][2],
1997
 
                           (old_path_u, path_u),
1998
 
                           content_change,
1999
 
                           (True, True),
2000
 
                           (source_parent_id, target_parent_id),
2001
 
                           (utf8_decode(old_basename)[0], utf8_decode(entry[0][1])[0]),
2002
 
                           (source_kind, target_kind),
2003
 
                           (source_exec, target_exec))
2004
 
                else:
2005
 
                    return uninteresting
 
1939
                return ((entry[0][2], (old_path, path), content_change,
 
1940
                        (True, True),
 
1941
                        (source_parent_id, target_parent_id),
 
1942
                        (old_basename, entry[0][1]),
 
1943
                        (_minikind_to_kind[source_minikind], target_kind),
 
1944
                        (source_exec, target_exec)),)
2006
1945
            elif source_minikind in 'a' and target_minikind in 'fdlt':
2007
1946
                # looks like a new file
2008
1947
                if path_info is not None:
2021
1960
                            and stat.S_IEXEC & path_info[3].st_mode)
2022
1961
                    else:
2023
1962
                        target_exec = target_details[3]
2024
 
                    return (entry[0][2],
2025
 
                           (None, utf8_decode(path)[0]),
2026
 
                           True,
2027
 
                           (False, True),
2028
 
                           (None, parent_id),
2029
 
                           (None, utf8_decode(entry[0][1])[0]),
2030
 
                           (None, path_info[2]),
2031
 
                           (None, target_exec))
 
1963
                    return ((entry[0][2], (None, path), True,
 
1964
                            (False, True),
 
1965
                            (None, parent_id),
 
1966
                            (None, entry[0][1]),
 
1967
                            (None, path_info[2]),
 
1968
                            (None, target_exec)),)
2032
1969
                else:
2033
1970
                    # but its not on disk: we deliberately treat this as just
2034
1971
                    # never-present. (Why ?! - RBC 20070224)
2043
1980
                parent_id = state._get_entry(source_index, path_utf8=entry[0][0])[0][2]
2044
1981
                if parent_id == entry[0][2]:
2045
1982
                    parent_id = None
2046
 
                return (entry[0][2],
2047
 
                       (utf8_decode(old_path)[0], None),
2048
 
                       True,
2049
 
                       (True, False),
2050
 
                       (parent_id, None),
2051
 
                       (utf8_decode(entry[0][1])[0], None),
2052
 
                       (_minikind_to_kind[source_minikind], None),
2053
 
                       (source_details[3], None))
 
1983
                return ((entry[0][2], (old_path, None), True,
 
1984
                        (True, False),
 
1985
                        (parent_id, None),
 
1986
                        (entry[0][1], None),
 
1987
                        (_minikind_to_kind[source_minikind], None),
 
1988
                        (source_details[3], None)),)
2054
1989
            elif source_minikind in 'fdlt' and target_minikind in 'r':
2055
1990
                # a rename; could be a true rename, or a rename inherited from
2056
1991
                # a renamed parent. TODO: handle this efficiently. Its not
2068
2003
                    "source_minikind=%r, target_minikind=%r"
2069
2004
                    % (source_minikind, target_minikind))
2070
2005
                ## import pdb;pdb.set_trace()
2071
 
            return None
 
2006
            return ()
2072
2007
 
2073
2008
        while search_specific_files:
2074
2009
            # TODO: the pending list should be lexically sorted?  the
2104
2039
                continue
2105
2040
            path_handled = False
2106
2041
            for entry in root_entries:
2107
 
                result = _process_entry(entry, root_dir_info)
2108
 
                if result is not None:
 
2042
                for result in _process_entry(entry, root_dir_info):
 
2043
                    # this check should probably be outside the loop: one
 
2044
                    # 'iterate two trees' api, and then _iter_changes filters
 
2045
                    # unchanged pairs. - RBC 20070226
2109
2046
                    path_handled = True
2110
 
                    if result is not uninteresting:
2111
 
                        yield result
 
2047
                    if (include_unchanged
 
2048
                        or result[2]                    # content change
 
2049
                        or result[3][0] != result[3][1] # versioned status
 
2050
                        or result[4][0] != result[4][1] # parent id
 
2051
                        or result[5][0] != result[5][1] # name
 
2052
                        or result[6][0] != result[6][1] # kind
 
2053
                        or result[7][0] != result[7][1] # executable
 
2054
                        ):
 
2055
                        yield (result[0],
 
2056
                               (utf8_decode_or_none(result[1][0]),
 
2057
                                utf8_decode_or_none(result[1][1])),
 
2058
                               result[2],
 
2059
                               result[3],
 
2060
                               result[4],
 
2061
                               (utf8_decode_or_none(result[5][0]),
 
2062
                                utf8_decode_or_none(result[5][1])),
 
2063
                               result[6],
 
2064
                               result[7],
 
2065
                              )
2112
2066
            if want_unversioned and not path_handled and root_dir_info:
2113
2067
                new_executable = bool(
2114
2068
                    stat.S_ISREG(root_dir_info[3].st_mode)
2168
2122
                   current_block is not None):
2169
2123
                if (current_dir_info and current_block
2170
2124
                    and current_dir_info[0][0] != current_block[0]):
2171
 
                    if current_dir_info[0][0].split('/') < current_block[0].split('/'):
 
2125
                    if current_dir_info[0][0] < current_block[0] :
2172
2126
                        # filesystem data refers to paths not covered by the dirblock.
2173
2127
                        # this has two possibilities:
2174
2128
                        # A) it is versioned but empty, so there is no block for it
2178
2132
                        # new unknown files or directories.
2179
2133
                        # if (B) then we should ignore it, because we don't
2180
2134
                        # recurse into unknown directories.
2181
 
                        path_index = 0
2182
 
                        while path_index < len(current_dir_info[1]):
2183
 
                                current_path_info = current_dir_info[1][path_index]
2184
 
                                if want_unversioned:
 
2135
                        if want_unversioned:
 
2136
                            path_index = 0
 
2137
                            while path_index < len(current_dir_info[1]):
 
2138
                                    current_path_info = current_dir_info[1][path_index]
2185
2139
                                    if current_path_info[2] == 'directory':
2186
2140
                                        if self.target._directory_is_tree_reference(
2187
2141
                                            current_path_info[0].decode('utf8')):
2191
2145
                                        stat.S_ISREG(current_path_info[3].st_mode)
2192
2146
                                        and stat.S_IEXEC & current_path_info[3].st_mode)
2193
2147
                                    yield (None,
2194
 
                                        (None, utf8_decode(current_path_info[0])[0]),
 
2148
                                        (None, utf8_decode_or_none(current_path_info[0])),
2195
2149
                                        True,
2196
2150
                                        (False, False),
2197
2151
                                        (None, None),
2198
 
                                        (None, utf8_decode(current_path_info[1])[0]),
 
2152
                                        (None, utf8_decode_or_none(current_path_info[1])),
2199
2153
                                        (None, current_path_info[2]),
2200
2154
                                        (None, new_executable))
2201
 
                                # dont descend into this unversioned path if it is
2202
 
                                # a dir
2203
 
                                if current_path_info[2] in ('directory',
2204
 
                                                            'tree-reference'):
2205
 
                                    del current_dir_info[1][path_index]
2206
 
                                    path_index -= 1
2207
 
                                path_index += 1
 
2155
                                    # dont descend into this unversioned path if it is
 
2156
                                    # a dir
 
2157
                                    if current_path_info[2] in ('directory',
 
2158
                                                                'tree-reference'):
 
2159
                                        del current_dir_info[1][path_index]
 
2160
                                        path_index -= 1
 
2161
                                    path_index += 1
2208
2162
 
2209
2163
                        # This dir info has been handled, go to the next
2210
2164
                        try:
2222
2176
                        for current_entry in current_block[1]:
2223
2177
                            # entry referring to file not present on disk.
2224
2178
                            # advance the entry only, after processing.
2225
 
                            result = _process_entry(current_entry, None)
2226
 
                            if result is not None:
2227
 
                                if result is not uninteresting:
2228
 
                                    yield result
 
2179
                            for result in _process_entry(current_entry, None):
 
2180
                                # this check should probably be outside the loop: one
 
2181
                                # 'iterate two trees' api, and then _iter_changes filters
 
2182
                                # unchanged pairs. - RBC 20070226
 
2183
                                if (include_unchanged
 
2184
                                    or result[2]                    # content change
 
2185
                                    or result[3][0] != result[3][1] # versioned status
 
2186
                                    or result[4][0] != result[4][1] # parent id
 
2187
                                    or result[5][0] != result[5][1] # name
 
2188
                                    or result[6][0] != result[6][1] # kind
 
2189
                                    or result[7][0] != result[7][1] # executable
 
2190
                                    ):
 
2191
                                    yield (result[0],
 
2192
                                           (utf8_decode_or_none(result[1][0]),
 
2193
                                            utf8_decode_or_none(result[1][1])),
 
2194
                                           result[2],
 
2195
                                           result[3],
 
2196
                                           result[4],
 
2197
                                           (utf8_decode_or_none(result[5][0]),
 
2198
                                            utf8_decode_or_none(result[5][1])),
 
2199
                                           result[6],
 
2200
                                           result[7],
 
2201
                                          )
2229
2202
                        block_index +=1
2230
2203
                        if (block_index < len(state._dirblocks) and
2231
2204
                            osutils.is_inside(current_root,
2260
2233
                        pass
2261
2234
                    elif current_path_info is None:
2262
2235
                        # no path is fine: the per entry code will handle it.
2263
 
                        result = _process_entry(current_entry, current_path_info)
2264
 
                        if result is not None:
2265
 
                            if result is not uninteresting:
2266
 
                                yield result
2267
 
                    elif (current_entry[0][1] != current_path_info[1]
2268
 
                          or current_entry[1][target_index][0] in 'ar'):
2269
 
                        # The current path on disk doesn't match the dirblock
2270
 
                        # record. Either the dirblock is marked as absent, or
2271
 
                        # the file on disk is not present at all in the
2272
 
                        # dirblock. Either way, report about the dirblock
2273
 
                        # entry, and let other code handle the filesystem one.
2274
 
 
2275
 
                        # Compare the basename for these files to determine
2276
 
                        # which comes first
 
2236
                        for result in _process_entry(current_entry, current_path_info):
 
2237
                            # this check should probably be outside the loop: one
 
2238
                            # 'iterate two trees' api, and then _iter_changes filters
 
2239
                            # unchanged pairs. - RBC 20070226
 
2240
                            if (include_unchanged
 
2241
                                or result[2]                    # content change
 
2242
                                or result[3][0] != result[3][1] # versioned status
 
2243
                                or result[4][0] != result[4][1] # parent id
 
2244
                                or result[5][0] != result[5][1] # name
 
2245
                                or result[6][0] != result[6][1] # kind
 
2246
                                or result[7][0] != result[7][1] # executable
 
2247
                                ):
 
2248
                                yield (result[0],
 
2249
                                       (utf8_decode_or_none(result[1][0]),
 
2250
                                        utf8_decode_or_none(result[1][1])),
 
2251
                                       result[2],
 
2252
                                       result[3],
 
2253
                                       result[4],
 
2254
                                       (utf8_decode_or_none(result[5][0]),
 
2255
                                        utf8_decode_or_none(result[5][1])),
 
2256
                                       result[6],
 
2257
                                       result[7],
 
2258
                                      )
 
2259
                    elif current_entry[0][1] != current_path_info[1]:
2277
2260
                        if current_path_info[1] < current_entry[0][1]:
2278
2261
                            # extra file on disk: pass for now, but only
2279
2262
                            # increment the path, not the entry
2281
2264
                        else:
2282
2265
                            # entry referring to file not present on disk.
2283
2266
                            # advance the entry only, after processing.
2284
 
                            result = _process_entry(current_entry, None)
2285
 
                            if result is not None:
2286
 
                                if result is not uninteresting:
2287
 
                                    yield result
 
2267
                            for result in _process_entry(current_entry, None):
 
2268
                                # this check should probably be outside the loop: one
 
2269
                                # 'iterate two trees' api, and then _iter_changes filters
 
2270
                                # unchanged pairs. - RBC 20070226
 
2271
                                path_handled = True
 
2272
                                if (include_unchanged
 
2273
                                    or result[2]                    # content change
 
2274
                                    or result[3][0] != result[3][1] # versioned status
 
2275
                                    or result[4][0] != result[4][1] # parent id
 
2276
                                    or result[5][0] != result[5][1] # name
 
2277
                                    or result[6][0] != result[6][1] # kind
 
2278
                                    or result[7][0] != result[7][1] # executable
 
2279
                                    ):
 
2280
                                    yield (result[0],
 
2281
                                           (utf8_decode_or_none(result[1][0]),
 
2282
                                            utf8_decode_or_none(result[1][1])),
 
2283
                                           result[2],
 
2284
                                           result[3],
 
2285
                                           result[4],
 
2286
                                           (utf8_decode_or_none(result[5][0]),
 
2287
                                            utf8_decode_or_none(result[5][1])),
 
2288
                                           result[6],
 
2289
                                           result[7],
 
2290
                                          )
2288
2291
                            advance_path = False
2289
2292
                    else:
2290
 
                        result = _process_entry(current_entry, current_path_info)
2291
 
                        if result is not None:
2292
 
                            path_handled = True
2293
 
                            if result is not uninteresting:
2294
 
                                yield result
 
2293
                        for result in _process_entry(current_entry, current_path_info):
 
2294
                            # this check should probably be outside the loop: one
 
2295
                            # 'iterate two trees' api, and then _iter_changes filters
 
2296
                            # unchanged pairs. - RBC 20070226
 
2297
                            if current_entry[1][target_index][0] == 'a':
 
2298
                                advance_path = False
 
2299
                                path_handled = False
 
2300
                            else:
 
2301
                                path_handled = True
 
2302
                            if (include_unchanged
 
2303
                                or result[2]                    # content change
 
2304
                                or result[3][0] != result[3][1] # versioned status
 
2305
                                or result[4][0] != result[4][1] # parent id
 
2306
                                or result[5][0] != result[5][1] # name
 
2307
                                or result[6][0] != result[6][1] # kind
 
2308
                                or result[7][0] != result[7][1] # executable
 
2309
                                ):
 
2310
                                yield (result[0],
 
2311
                                       (utf8_decode_or_none(result[1][0]),
 
2312
                                        utf8_decode_or_none(result[1][1])),
 
2313
                                       result[2],
 
2314
                                       result[3],
 
2315
                                       result[4],
 
2316
                                       (utf8_decode_or_none(result[5][0]),
 
2317
                                        utf8_decode_or_none(result[5][1])),
 
2318
                                       result[6],
 
2319
                                       result[7],
 
2320
                                      )
2295
2321
                    if advance_entry and current_entry is not None:
2296
2322
                        entry_index += 1
2297
2323
                        if entry_index < len(current_block[1]):
2308
2334
                                    stat.S_ISREG(current_path_info[3].st_mode)
2309
2335
                                    and stat.S_IEXEC & current_path_info[3].st_mode)
2310
2336
                                yield (None,
2311
 
                                    (None, utf8_decode(current_path_info[0])[0]),
 
2337
                                    (None, utf8_decode_or_none(current_path_info[0])),
2312
2338
                                    True,
2313
2339
                                    (False, False),
2314
2340
                                    (None, None),
2315
 
                                    (None, utf8_decode(current_path_info[1])[0]),
 
2341
                                    (None, utf8_decode_or_none(current_path_info[1])),
2316
2342
                                    (None, current_path_info[2]),
2317
2343
                                    (None, new_executable))
2318
2344
                            # dont descend into this unversioned path if it is