Skip to content
Snippets Groups Projects
  • Matt Harbison's avatar
    85785cd3
    dirstate: ensure mv source is marked deleted when walking icasefs (issue4760) · 85785cd3
    Matt Harbison authored
    Previously, importing a case-only rename patch on a case insensitive filesystem
    caused the original file to be marked as '!' in status.  The source was being
    forgotten properly in patch.workingbackend.close(), but the call it makes to
    scmutil.marktouched() then put the file back into the 'n' state (but it was
    still missing from the filesystem).
    
    The cause of this was scmutil._interestingfiles() would walk dirstate,
    and since dirstate was able to lstat() the old file via the new name,
    was treating this as a forgotten file, not a removed file.
    scmutil.marktouched() re-adds forgotten files, so dirstate got out of
    sync with the filesystem.
    
    This could be handled with less code in the "kind == regkind or kind
    == lnkkind" branch of dirstate._walkexplicit(), but this avoids
    filesystem accesses unless case collisions occur. _discoverpath() is
    used instead of normalize(), since the dirstate case is given first
    precedence, and the old file is still in it. What matters is the
    actual case in the filesystem.
    85785cd3
    History
    dirstate: ensure mv source is marked deleted when walking icasefs (issue4760)
    Matt Harbison authored
    Previously, importing a case-only rename patch on a case insensitive filesystem
    caused the original file to be marked as '!' in status.  The source was being
    forgotten properly in patch.workingbackend.close(), but the call it makes to
    scmutil.marktouched() then put the file back into the 'n' state (but it was
    still missing from the filesystem).
    
    The cause of this was scmutil._interestingfiles() would walk dirstate,
    and since dirstate was able to lstat() the old file via the new name,
    was treating this as a forgotten file, not a removed file.
    scmutil.marktouched() re-adds forgotten files, so dirstate got out of
    sync with the filesystem.
    
    This could be handled with less code in the "kind == regkind or kind
    == lnkkind" branch of dirstate._walkexplicit(), but this avoids
    filesystem accesses unless case collisions occur. _discoverpath() is
    used instead of normalize(), since the dirstate case is given first
    precedence, and the old file is still in it. What matters is the
    actual case in the filesystem.