~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

  • Committer: John Arbash Meinel
  • Date: 2010-01-05 18:35:25 UTC
  • mto: (4934.1.9 2.1.0rc1-set-mtime)
  • mto: This revision was merged to the branch mainline in revision 4940.
  • Revision ID: john@arbash-meinel.com-20100105183525-6hbg9m5o76j1cb16
Basic implementation for windows and bug #488724.


The request is that whenever we create a new batch of files,
they should all get the same timestamp.
This is so that if you version both a source file and its generated
result, then when you update to a new version, the system doesn't
think that the generated file needs to be rebuilt.

This is done on Windows using the SetFileInformationByHandle api.
We'll probably implement it on POSIX using futimes.
Though ideally we'd support futimens if it was available.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
import os
18
18
import errno
19
19
from stat import S_ISREG, S_IEXEC
 
20
import time
20
21
 
21
22
from bzrlib.lazy_import import lazy_import
22
23
lazy_import(globals(), """
1131
1132
                raise
1132
1133
 
1133
1134
            f.writelines(contents)
 
1135
            self._set_mtime(f)
1134
1136
        finally:
1135
1137
            f.close()
1136
1138
        self._set_mode(trans_id, mode_id, S_ISREG)
1298
1300
        DiskTreeTransform.__init__(self, tree, limbodir, pb,
1299
1301
                                   tree.case_sensitive)
1300
1302
        self._deletiondir = deletiondir
 
1303
        self._creation_mtime = None
1301
1304
 
1302
1305
    def canonical_path(self, path):
1303
1306
        """Get the canonical tree-relative path"""
1360
1363
        if typefunc(mode):
1361
1364
            os.chmod(self._limbo_name(trans_id), mode)
1362
1365
 
 
1366
    def _set_mtime(self, f):
 
1367
        """All files that are created get the same mtime.
 
1368
 
 
1369
        This time is set by the first object to be created.
 
1370
        """
 
1371
        if self._creation_mtime is None:
 
1372
            self._creation_mtime = time.time()
 
1373
        import ctypes, msvcrt
 
1374
        class BASIC_INFO(ctypes.Structure):
 
1375
             _fields_ = [('CreationTime', ctypes.c_int64),
 
1376
                         ('LastAccessTime', ctypes.c_int64),
 
1377
                         ('LastWriteTime', ctypes.c_int64),
 
1378
                         ('ChangeTime', ctypes.c_int64),
 
1379
                         ('FileAttributes', ctypes.c_uint32),
 
1380
                        ]
 
1381
        bi = BASIC_INFO()
 
1382
        gfi = ctypes.windll.kernel32.GetFileInformationByHandleEx
 
1383
        handle = msvcrt.get_osfhandle(f.fileno())
 
1384
        ret = gfi(handle, 0, ctypes.byref(bi), ctypes.sizeof(bi))
 
1385
        assert ret, "failed to get file information: %d" % (
 
1386
            ctypes.GetLastError(),)
 
1387
        sfi = ctypes.windll.kernel32.SetFileInformationByHandle
 
1388
        bi.LastWriteTime = int((self._creation_mtime + 11644473600.0) * 1.0e7)
 
1389
        ret = sfi(handle, 0, ctypes.byref(bi), ctypes.sizeof(bi))
 
1390
        assert ret, "Failed to set file information: %d" % (
 
1391
            ctypes.GetLastError(),)
 
1392
 
 
1393
 
1363
1394
    def iter_tree_children(self, parent_id):
1364
1395
        """Iterate through the entry's tree children, if any"""
1365
1396
        try: