~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/dirstate.py

  • Committer: Patch Queue Manager
  • Date: 2011-09-08 11:01:15 UTC
  • mfrom: (6123.1.16 gpg-typo)
  • Revision ID: pqm@cupuasso-20110908110115-gbb9benwkdksvzk5
(jelmer) Fix a typo (invalid format identifier) in an error message in
 bzrlib.gpg. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
219
219
"""
220
220
 
221
221
import bisect
 
222
import binascii
222
223
import errno
223
224
import operator
224
225
import os
225
226
from stat import S_IEXEC
226
227
import stat
 
228
import struct
227
229
import sys
228
230
import time
229
231
import zlib
249
251
ERROR_DIRECTORY = 267
250
252
 
251
253
 
 
254
if not getattr(struct, '_compile', None):
 
255
    # Cannot pre-compile the dirstate pack_stat
 
256
    def pack_stat(st, _encode=binascii.b2a_base64, _pack=struct.pack):
 
257
        """Convert stat values into a packed representation."""
 
258
        return _encode(_pack('>LLLLLL', st.st_size, int(st.st_mtime),
 
259
            int(st.st_ctime), st.st_dev, st.st_ino & 0xFFFFFFFF,
 
260
            st.st_mode))[:-1]
 
261
else:
 
262
    # compile the struct compiler we need, so as to only do it once
 
263
    from _struct import Struct
 
264
    _compiled_pack = Struct('>LLLLLL').pack
 
265
    def pack_stat(st, _encode=binascii.b2a_base64, _pack=_compiled_pack):
 
266
        """Convert stat values into a packed representation."""
 
267
        # jam 20060614 it isn't really worth removing more entries if we
 
268
        # are going to leave it in packed form.
 
269
        # With only st_mtime and st_mode filesize is 5.5M and read time is 275ms
 
270
        # With all entries, filesize is 5.9M and read time is maybe 280ms
 
271
        # well within the noise margin
 
272
 
 
273
        # base64 encoding always adds a final newline, so strip it off
 
274
        # The current version
 
275
        return _encode(_pack(st.st_size, int(st.st_mtime), int(st.st_ctime),
 
276
            st.st_dev, st.st_ino & 0xFFFFFFFF, st.st_mode))[:-1]
 
277
        # This is 0.060s / 1.520s faster by not encoding as much information
 
278
        # return _encode(_pack('>LL', int(st.st_mtime), st.st_mode))[:-1]
 
279
        # This is not strictly faster than _encode(_pack())[:-1]
 
280
        # return '%X.%X.%X.%X.%X.%X' % (
 
281
        #      st.st_size, int(st.st_mtime), int(st.st_ctime),
 
282
        #      st.st_dev, st.st_ino, st.st_mode)
 
283
        # Similar to the _encode(_pack('>LL'))
 
284
        # return '%X.%X' % (int(st.st_mtime), st.st_mode)
 
285
 
 
286
 
 
287
def _unpack_stat(packed_stat):
 
288
    """Turn a packed_stat back into the stat fields.
 
289
 
 
290
    This is meant as a debugging tool, should not be used in real code.
 
291
    """
 
292
    (st_size, st_mtime, st_ctime, st_dev, st_ino,
 
293
     st_mode) = struct.unpack('>LLLLLL', binascii.a2b_base64(packed_stat))
 
294
    return dict(st_size=st_size, st_mtime=st_mtime, st_ctime=st_ctime,
 
295
                st_dev=st_dev, st_ino=st_ino, st_mode=st_mode)
 
296
 
 
297
 
252
298
class SHA1Provider(object):
253
299
    """An interface for getting sha1s of a file."""
254
300
 
1850
1896
                    file_id, "This parent is not a directory.")
1851
1897
 
1852
1898
    def _observed_sha1(self, entry, sha1, stat_value,
1853
 
        _stat_to_minikind=_stat_to_minikind):
 
1899
        _stat_to_minikind=_stat_to_minikind, _pack_stat=pack_stat):
1854
1900
        """Note the sha1 of a file.
1855
1901
 
1856
1902
        :param entry: The entry the sha1 is for.
1862
1908
        except KeyError:
1863
1909
            # Unhandled kind
1864
1910
            return None
 
1911
        packed_stat = _pack_stat(stat_value)
1865
1912
        if minikind == 'f':
1866
1913
            if self._cutoff_time is None:
1867
1914
                self._sha_cutoff_time()
1868
1915
            if (stat_value.st_mtime < self._cutoff_time
1869
1916
                and stat_value.st_ctime < self._cutoff_time):
1870
1917
                entry[1][0] = ('f', sha1, stat_value.st_size, entry[1][0][3],
1871
 
                               pack_stat(stat_value))
 
1918
                               packed_stat)
1872
1919
                self._mark_modified([entry])
1873
1920
 
1874
1921
    def _sha_cutoff_time(self):
2427
2474
            raise errors.BzrError('missing num_entries line')
2428
2475
        self._num_entries = int(num_entries_line[len('num_entries: '):-1])
2429
2476
 
2430
 
    def sha1_from_stat(self, path, stat_result):
 
2477
    def sha1_from_stat(self, path, stat_result, _pack_stat=pack_stat):
2431
2478
        """Find a sha1 given a stat lookup."""
2432
 
        return self._get_packed_stat_index().get(pack_stat(stat_result), None)
 
2479
        return self._get_packed_stat_index().get(_pack_stat(stat_result), None)
2433
2480
 
2434
2481
    def _get_packed_stat_index(self):
2435
2482
        """Get a packed_stat index of self._dirblocks."""
3350
3397
 
3351
3398
 
3352
3399
def py_update_entry(state, entry, abspath, stat_value,
3353
 
                 _stat_to_minikind=DirState._stat_to_minikind):
 
3400
                 _stat_to_minikind=DirState._stat_to_minikind,
 
3401
                 _pack_stat=pack_stat):
3354
3402
    """Update the entry based on what is actually on disk.
3355
3403
 
3356
3404
    This function only calculates the sha if it needs to - if the entry is
3369
3417
    except KeyError:
3370
3418
        # Unhandled kind
3371
3419
        return None
3372
 
    packed_stat = pack_stat(stat_value)
 
3420
    packed_stat = _pack_stat(stat_value)
3373
3421
    (saved_minikind, saved_link_or_sha1, saved_file_size,
3374
3422
     saved_executable, saved_packed_stat) = entry[1][0]
3375
3423
 
4248
4296
        _bisect_path_left,
4249
4297
        _bisect_path_right,
4250
4298
        cmp_by_dirs,
4251
 
        pack_stat,
4252
4299
        ProcessEntryC as _process_entry,
4253
4300
        update_entry as update_entry,
4254
4301
        )
4260
4307
        _bisect_path_left,
4261
4308
        _bisect_path_right,
4262
4309
        cmp_by_dirs,
4263
 
        pack_stat,
4264
4310
        )
4265
4311
    # FIXME: It would be nice to be able to track moved lines so that the
4266
4312
    # corresponding python code can be moved to the _dirstate_helpers_py