Rev 4943: Bring in Martin <gzlist>'s small updates. in http://bazaar.launchpad.net/~jameinel/bzr/2.1.0rc1-set-mtime

John Arbash Meinel john at arbash-meinel.com
Wed Jan 6 20:08:41 GMT 2010


At http://bazaar.launchpad.net/~jameinel/bzr/2.1.0rc1-set-mtime

------------------------------------------------------------
revno: 4943 [merge]
revision-id: john at arbash-meinel.com-20100106200816-micwvc3rqtcv2hr1
parent: john at arbash-meinel.com-20100106181517-4ktyo41hygkua09c
parent: gzlist at googlemail.com-20100106195902-vi1ckfsu2wurtt8v
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1.0rc1-set-mtime
timestamp: Wed 2010-01-06 14:08:16 -0600
message:
  Bring in Martin <gzlist>'s small updates.
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/_walkdirs_win32.pyx     _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
  bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
  bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2010-01-06 18:15:17 +0000
+++ b/NEWS	2010-01-06 19:50:50 +0000
@@ -67,8 +67,8 @@
 * Operations which update the working tree should now create all files
   with the same mtime. So if you version a generated file and its source,
   when updating you should get the same mtime for both files. We use
-  ``SetFileInformationByHandle`` on Windows, ``futimes()`` on POSIX, an
-  ``os.utime`` otherwise to achieve this effect.
+  ``SetFileTime`` on Windows, ``futimes()`` on POSIX, and ``os.utime``
+  otherwise to achieve this effect.
   (John Arbash Meinel, #488724)
 
 * The 2a format wasn't properly restarting autopacks when something

=== modified file 'bzrlib/_walkdirs_win32.pyx'
--- a/bzrlib/_walkdirs_win32.pyx	2010-01-06 18:15:17 +0000
+++ b/bzrlib/_walkdirs_win32.pyx	2010-01-06 19:50:50 +0000
@@ -59,28 +59,9 @@
     # Wide character functions
     DWORD wcslen(WCHAR *)
 
-    ctypedef struct LARGE_INTEGER:
-        DWORD LowPart
-        DWORD HighPart
-
-    # TODO: Why does the win32 api use LARGE_INTEGER for this structure, but
-    #       FILETIME for the return from FindFirstFileW
-    ctypedef struct FILE_BASIC_INFO:
-         LARGE_INTEGER CreationTime
-         LARGE_INTEGER LastAccessTime
-         LARGE_INTEGER LastWriteTime
-         LARGE_INTEGER ChangeTime
-         DWORD FileAttributes
-
-    ctypedef enum FILE_INFO_BY_HANDLE_CLASS:
-        FileBasicInfo
-
-    int GetFileInformationByHandleEx(
-        HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS type,
-        void* fileInformationBuffer, DWORD bufSize)
-    int SetFileInformationByHandle(
-        HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS type,
-        void* fileInformationBuffer, DWORD bufSize)
+    int SetFileTime(
+        HANDLE hFile, FILETIME *lpCreationTime, FILETIME *lpLastAccessTime,
+        FILETIME *lpLastWriteTime)
 
     long _get_osfhandle(int)
 
@@ -178,8 +159,8 @@
     cdef FILETIME result
 
     val = <__int64>((timestamp + 11644473600.0) * 1.0e7)
-    result.dwHighDateTime = val >> 32
-    result.dwLowDateTime = val & 0xFFFFFFFF
+    result.dwHighDateTime = <DWORD>(val >> 32)
+    result.dwLowDateTime = <DWORD>(val & 0xFFFFFFFF)
     return result
 
 
@@ -291,7 +272,6 @@
 def fset_mtime(f, mtime):
     """See osutils.fset_mtime."""
     cdef HANDLE the_handle
-    cdef FILE_BASIC_INFO bi
     cdef FILETIME ft
     cdef int retval
 
@@ -299,13 +279,6 @@
     the_handle = <HANDLE>(_get_osfhandle(f.fileno()))
     if the_handle == <HANDLE>(-1):
         raise OSError('Invalid fileno') # IOError?
-    retval = GetFileInformationByHandleEx(the_handle, FileBasicInfo,
-                                          &bi, sizeof(FILE_BASIC_INFO))
-    if retval != 1:
-        raise OSError('Failed to GetFileInformationByHandleEx')
-    bi.LastWriteTime.LowPart = ft.dwLowDateTime
-    bi.LastWriteTime.HighPart = ft.dwHighDateTime
-    retval = SetFileInformationByHandle(the_handle, FileBasicInfo,
-                                        &bi, sizeof(FILE_BASIC_INFO))
-    if retval != 1:
-        raise OSError('Failed to SetFileInformationByHandle')
+    retval = SetFileTime(the_handle, NULL, NULL, &ft)
+    if retval == 0:
+        raise WindowsError(GetLastError(), "Failed to set file modified time")

=== modified file 'bzrlib/tests/test_osutils.py'
--- a/bzrlib/tests/test_osutils.py	2010-01-06 17:20:57 +0000
+++ b/bzrlib/tests/test_osutils.py	2010-01-06 19:59:02 +0000
@@ -2008,26 +2008,24 @@
 
 class TestFSetMtime(tests.TestCaseInTempDir):
 
-    def test__utime_fset_mtime(self):
+    def _check_fset_mtime(self, func):
         f = open('test', 'wb')
         try:
             mtime = os.fstat(f.fileno()).st_mtime
             new_mtime = mtime - 20
-            osutils._utime_fset_mtime(f, new_mtime)
-        finally:
-            f.close()
-        self.assertEqual(int(new_mtime), int(os.lstat('test').st_mtime))
-
-    def test_fset_mtime(self):
-        f = open('test', 'wb')
-        new_mtime = time.time()-20.0
-        try:
-            mtime = os.fstat(f.fileno()).st_mtime
-            osutils.fset_mtime(f, new_mtime)
+            func(f, new_mtime)
         finally:
             f.close()
         self.assertNotEqual(mtime, new_mtime)
-        # We don't guarantee any better than 1s resolution, though we try to
+        set_mtime = os.lstat('test').st_mtime
+        # We don't guarantee any better than 2s resolution, due to timestamp
+        # precision limitations on older filesystems such as FAT, but try to
         # use functions that have at least microsecond resolution (1us on
         # POSIX, 100ns on Windows)
-        self.assertEqual(int(new_mtime), int(os.lstat('test').st_mtime))
+        self.assertFalse(int((new_mtime - set_mtime) / 2),
+            "%r != %r within two seconds" % (new_mtime, set_mtime))
+
+    def test_fset_mtime(self):
+        self._check_fset_mtime(osutils.fset_mtime)
+        if osutils.fset_mtime is not osutils._utime_fset_mtime:
+            self._check_fset_mtime(osutils._utime_fset_mtime)

=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py	2010-01-05 22:13:12 +0000
+++ b/bzrlib/tests/test_transform.py	2010-01-06 19:59:02 +0000
@@ -143,7 +143,7 @@
         self.addCleanup(self.wt.unlock)
         # Roll back the clock, so that we know everything is being set to the
         # exact time
-        transform._creation_mtime = time.time() - 10.0
+        transform._creation_mtime = creation_mtime = time.time() - 10.0
         transform.create_file('content-one',
                               transform.create_path('one', root))
         time.sleep(1) # *ugly*
@@ -154,8 +154,9 @@
         fo.close()
         fo, st2 = self.wt.get_file_with_stat(None, path='two', filtered=False)
         fo.close()
-        # We only guarantee 1s resolution
-        self.assertEqual(int(transform._creation_mtime), int(st1.st_mtime))
+        # We only guarantee 2s resolution
+        self.assertFalse(int((creation_mtime - st1.st_mtime) / 2),
+            "%r != %r within two seconds" % (creation_mtime, st1.st_mtime))
         # But if we have more than that, all files should get the same result
         self.assertEqual(st1.st_mtime, st2.st_mtime)
 



More information about the bazaar-commits mailing list