Skip to content
  • Johannes Schindelin's avatar
    t6042: work around speed optimization on Windows · da43c072
    Johannes Schindelin authored and Junio C Hamano's avatar Junio C Hamano committed
    
    
    When Git determines whether a file has changed, it looks at the mtime,
    at the file size, and to detect changes even if the mtime is the same
    (on Windows, the mtime granularity is 100ns, read: if two files are
    written within the same 100ns time slot, they have the same mtime) and
    even if the file size is the same, Git also looks at the inode/device
    numbers.
    
    This design obviously comes from a Linux background, where `lstat()`
    calls were designed to be cheap.
    
    On Windows, there is no `lstat()`. It has to be emulated. And while
    obtaining the mtime and the file size is not all that expensive (you can
    get both with a single `GetFileAttributesW()` call), obtaining the
    equivalent of the inode and device numbers is very expensive (it
    requires a call to `GetFileInformationByHandle()`, which in turn
    requires a file handle, which is *a lot* more expensive than one might
    imagine).
    
    As it is very uncommon for developers to modify files within 100ns time
    slots, Git for Windows chooses not to fill inode/device numbers
    properly, but simply sets them to 0.
    
    However, in t6042 the files file_v1 and file_v2 are typically written
    within the same 100ns time slot, and they do not differ in file size. So
    the minor modification is not picked up.
    
    Let's work around this issue by avoiding the `git mv` calls in the
    'mod6-setup: chains of rename/rename(1to2) and rename/rename(2to1)' test
    case. The target files are overwritten anyway, so it is not like we
    really rename those files. This fixes the issue because `git add` will
    now add the files as new files (as opposed to existing, just renamed
    files).
    
    Functionally, we do not change anything because we replace two `git mv
    <old> <new>` calls (where `<new>` is completely overwritten and `git
    add`ed later anyway) by `git rm <old>` calls (removing other files, too,
    that are also completely overwritten and `git add`ed later).
    
    Reviewed-by: default avatarElijah Newren <newren@gmail.com>
    Signed-off-by: default avatarJohannes Schindelin <johannes.schindelin@gmx.de>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    da43c072