~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree_4.py

Merge (hopefully the last time) mainline fixes for 0.15.

Show diffs side-by-side

added added

removed removed

Lines of Context:
96
96
from bzrlib.workingtree import WorkingTree, WorkingTree3, WorkingTreeFormat3
97
97
 
98
98
 
 
99
# This is the Windows equivalent of ENOTDIR
 
100
# It is defined in pywin32.winerror, but we don't want a strong dependency for
 
101
# just an error code.
 
102
ERROR_DIRECTORY = 267
 
103
 
 
104
 
99
105
class WorkingTree4(WorkingTree3):
100
106
    """This is the Format 4 working tree.
101
107
 
1163
1169
                entry_index = 0
1164
1170
                while entry_index < len(block[1]):
1165
1171
                    # Mark this file id as having been removed
1166
 
                    ids_to_unversion.discard(block[1][entry_index][0][2])
1167
 
                    if not state._make_absent(block[1][entry_index]):
 
1172
                    entry = block[1][entry_index]
 
1173
                    ids_to_unversion.discard(entry[0][2])
 
1174
                    if (entry[1][0][0] == 'a'
 
1175
                        or not state._make_absent(entry)):
1168
1176
                        entry_index += 1
1169
1177
                # go to the next block. (At the moment we dont delete empty
1170
1178
                # dirblocks)
1643
1651
            output. An unversioned file is defined as one with (False, False)
1644
1652
            for the versioned pair.
1645
1653
        """
1646
 
        utf8_decode = cache_utf8._utf8_decode_with_None
 
1654
        utf8_decode_or_none = cache_utf8._utf8_decode_with_None
1647
1655
        _minikind_to_kind = dirstate.DirState._minikind_to_kind
1648
1656
        # NB: show_status depends on being able to pass in non-versioned files
1649
1657
        # and report them as unknown
1983
1991
            # TODO: the pending list should be lexically sorted?  the
1984
1992
            # interface doesn't require it.
1985
1993
            current_root = search_specific_files.pop()
 
1994
            current_root_unicode = current_root.decode('utf8')
1986
1995
            searched_specific_files.add(current_root)
1987
1996
            # process the entries for this containing directory: the rest will be
1988
1997
            # found by their parents recursively.
1989
1998
            root_entries = _entries_for_path(current_root)
1990
 
            root_abspath = self.target.abspath(current_root)
 
1999
            root_abspath = self.target.abspath(current_root_unicode)
1991
2000
            try:
1992
2001
                root_stat = os.lstat(root_abspath)
1993
2002
            except OSError, e:
2025
2034
                        or result[6][0] != result[6][1] # kind
2026
2035
                        or result[7][0] != result[7][1] # executable
2027
2036
                        ):
2028
 
                        result = (result[0],
2029
 
                            ((utf8_decode(result[1][0])[0]),
2030
 
                             utf8_decode(result[1][1])[0]),) + result[2:]
2031
 
                        yield result
2032
 
            if want_unversioned and not path_handled:
 
2037
                        yield (result[0],
 
2038
                               (utf8_decode_or_none(result[1][0]),
 
2039
                                utf8_decode_or_none(result[1][1])),
 
2040
                               result[2],
 
2041
                               result[3],
 
2042
                               result[4],
 
2043
                               (utf8_decode_or_none(result[5][0]),
 
2044
                                utf8_decode_or_none(result[5][1])),
 
2045
                               result[6],
 
2046
                               result[7],
 
2047
                              )
 
2048
            if want_unversioned and not path_handled and root_dir_info:
2033
2049
                new_executable = bool(
2034
2050
                    stat.S_ISREG(root_dir_info[3].st_mode)
2035
2051
                    and stat.S_IEXEC & root_dir_info[3].st_mode)
2036
 
                yield (None, (None, current_root), True, (False, False),
2037
 
                    (None, None),
2038
 
                    (None, splitpath(current_root)[-1]),
2039
 
                    (None, root_dir_info[2]), (None, new_executable))
 
2052
                yield (None,
 
2053
                       (None, current_root_unicode),
 
2054
                       True,
 
2055
                       (False, False),
 
2056
                       (None, None),
 
2057
                       (None, splitpath(current_root_unicode)[-1]),
 
2058
                       (None, root_dir_info[2]),
 
2059
                       (None, new_executable)
 
2060
                      )
2040
2061
            initial_key = (current_root, '', '')
2041
2062
            block_index, _ = state._find_block_index_from_key(initial_key)
2042
2063
            if block_index == 0:
2050
2071
                try:
2051
2072
                    current_dir_info = dir_iterator.next()
2052
2073
                except OSError, e:
2053
 
                    if e.errno in (errno.ENOENT, errno.ENOTDIR):
2054
 
                        # there may be directories in the inventory even though
2055
 
                        # this path is not a file on disk: so mark it as end of
2056
 
                        # iterator
 
2074
                    # on win32, python2.4 has e.errno == ERROR_DIRECTORY, but
 
2075
                    # python 2.5 has e.errno == EINVAL,
 
2076
                    #            and e.winerror == ERROR_DIRECTORY
 
2077
                    e_winerror = getattr(e, 'winerror', None)
 
2078
                    # there may be directories in the inventory even though
 
2079
                    # this path is not a file on disk: so mark it as end of
 
2080
                    # iterator
 
2081
                    if e.errno in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
 
2082
                        current_dir_info = None
 
2083
                    elif (sys.platform == 'win32'
 
2084
                          and ERROR_DIRECTORY in (e.errno, e_winerror)):
2057
2085
                        current_dir_info = None
2058
2086
                    else:
2059
2087
                        raise
2111
2139
                                    or result[6][0] != result[6][1] # kind
2112
2140
                                    or result[7][0] != result[7][1] # executable
2113
2141
                                    ):
2114
 
                                    result = (result[0],
2115
 
                                        ((utf8_decode(result[1][0])[0]),
2116
 
                                         utf8_decode(result[1][1])[0]),) + result[2:]
2117
 
                                    yield result
 
2142
                                    yield (result[0],
 
2143
                                           (utf8_decode_or_none(result[1][0]),
 
2144
                                            utf8_decode_or_none(result[1][1])),
 
2145
                                           result[2],
 
2146
                                           result[3],
 
2147
                                           result[4],
 
2148
                                           (utf8_decode_or_none(result[5][0]),
 
2149
                                            utf8_decode_or_none(result[5][1])),
 
2150
                                           result[6],
 
2151
                                           result[7],
 
2152
                                          )
2118
2153
                        block_index +=1
2119
2154
                        if (block_index < len(state._dirblocks) and
2120
2155
                            osutils.is_inside(current_root,
2161
2196
                                or result[6][0] != result[6][1] # kind
2162
2197
                                or result[7][0] != result[7][1] # executable
2163
2198
                                ):
2164
 
                                result = (result[0],
2165
 
                                    ((utf8_decode(result[1][0])[0]),
2166
 
                                     utf8_decode(result[1][1])[0]),) + result[2:]
2167
 
                                yield result
 
2199
                                yield (result[0],
 
2200
                                       (utf8_decode_or_none(result[1][0]),
 
2201
                                        utf8_decode_or_none(result[1][1])),
 
2202
                                       result[2],
 
2203
                                       result[3],
 
2204
                                       result[4],
 
2205
                                       (utf8_decode_or_none(result[5][0]),
 
2206
                                        utf8_decode_or_none(result[5][1])),
 
2207
                                       result[6],
 
2208
                                       result[7],
 
2209
                                      )
2168
2210
                    elif current_entry[0][1] != current_path_info[1]:
2169
2211
                        if current_path_info[1] < current_entry[0][1]:
2170
2212
                            # extra file on disk: pass for now, but only
2186
2228
                                    or result[6][0] != result[6][1] # kind
2187
2229
                                    or result[7][0] != result[7][1] # executable
2188
2230
                                    ):
2189
 
                                    result = (result[0],
2190
 
                                        ((utf8_decode(result[1][0])[0]),
2191
 
                                         utf8_decode(result[1][1])[0]),) + result[2:]
2192
 
                                    yield result
 
2231
                                    yield (result[0],
 
2232
                                           (utf8_decode_or_none(result[1][0]),
 
2233
                                            utf8_decode_or_none(result[1][1])),
 
2234
                                           result[2],
 
2235
                                           result[3],
 
2236
                                           result[4],
 
2237
                                           (utf8_decode_or_none(result[5][0]),
 
2238
                                            utf8_decode_or_none(result[5][1])),
 
2239
                                           result[6],
 
2240
                                           result[7],
 
2241
                                          )
2193
2242
                            advance_path = False
2194
2243
                    else:
2195
2244
                        for result in _process_entry(current_entry, current_path_info):
2205
2254
                                or result[6][0] != result[6][1] # kind
2206
2255
                                or result[7][0] != result[7][1] # executable
2207
2256
                                ):
2208
 
                                result = (result[0],
2209
 
                                    ((utf8_decode(result[1][0])[0]),
2210
 
                                     utf8_decode(result[1][1])[0]),) + result[2:]
2211
 
                                yield result
 
2257
                                yield (result[0],
 
2258
                                       (utf8_decode_or_none(result[1][0]),
 
2259
                                        utf8_decode_or_none(result[1][1])),
 
2260
                                       result[2],
 
2261
                                       result[3],
 
2262
                                       result[4],
 
2263
                                       (utf8_decode_or_none(result[5][0]),
 
2264
                                        utf8_decode_or_none(result[5][1])),
 
2265
                                       result[6],
 
2266
                                       result[7],
 
2267
                                      )
2212
2268
                    if advance_entry and current_entry is not None:
2213
2269
                        entry_index += 1
2214
2270
                        if entry_index < len(current_block[1]):
2225
2281
                                    stat.S_ISREG(current_path_info[3].st_mode)
2226
2282
                                    and stat.S_IEXEC & current_path_info[3].st_mode)
2227
2283
                                if want_unversioned:
2228
 
                                    yield (None, (None, current_path_info[0]),
 
2284
                                    yield (None,
 
2285
                                        (None, utf8_decode_or_none(current_path_info[0])),
2229
2286
                                        True,
2230
2287
                                        (False, False),
2231
2288
                                        (None, None),
2232
 
                                        (None, current_path_info[1]),
 
2289
                                        (None, utf8_decode_or_none(current_path_info[1])),
2233
2290
                                        (None, current_path_info[2]),
2234
2291
                                        (None, new_executable))
2235
2292
                            # dont descend into this unversioned path if it is