mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 00:45:18 +03:00
a935fc38b4
Summary: On Windows, paths are case insensitive (but the filesystem is case preserving), and thus `open("FILE.TXT")` and `open("file.txt")` refer to the same file. When that file is not materialized and its parent directory isn't yet enumerated, PrjFS will call the PRJ_GET_PLACEHOLDER_INFO_CB with the file name passed in to the `open` call. In this callback, if the passed in name refers to a valid file, it needs to call PrjWritePlaceholderInfo to populate the directory entry. Here is what the documentation for that function states: "For example, if the PRJ_GET_PLACEHOLDER_INFO_CB callback specifies dir1\dir1\FILE.TXT in callbackData->FilePathName, and the provider's backing store contains a file called File.txt in the dir1\dir2 directory, and PrjFileNameCompare returns 0 when comparing the names FILE.TXT and File.txt, then the provider specifies dir1\dir2\File.txt as the value of this parameter." While the documentation doesn't state how that name is used internally, we can infer (and test) that the returned case will be used as the canonical representation of that file, ie: the one that a directory listing will see. Since the PathMap code already does a case insensitive search, we just need to make sure to use what it returns instead of re-using the name used for the search. The only caveat to all of this is the original comment that describe that `metadata.name` can't be used as it causes crashes. From what I can tell, this was written in later 2018, and I believe is no longer relevant: the `metadata.name` field was simply not populated. Reviewed By: wez Differential Revision: D21799627 fbshipit-source-id: aee877cc2d5f057944fcd39b1d59f0e97de6315c
41 lines
1.2 KiB
Python
41 lines
1.2 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright (c) Facebook, Inc. and its affiliates.
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2.
|
|
|
|
import os
|
|
import sys
|
|
|
|
from .lib import testcase
|
|
|
|
|
|
@testcase.eden_repo_test
|
|
# pyre-ignore[13]: T62487924
|
|
class CasingTest(testcase.EdenRepoTest):
|
|
"""Verify that EdenFS behave properly when configured to be case
|
|
insensitive and case preserving.
|
|
"""
|
|
|
|
is_case_insensitive: bool
|
|
|
|
def populate_repo(self) -> None:
|
|
self.is_case_insensitive = sys.platform == "win32"
|
|
|
|
self.repo.write_file("adir1/adir2/a", "Hello!\n")
|
|
self.repo.commit("a")
|
|
|
|
def test_insensitive(self) -> None:
|
|
if self.is_case_insensitive:
|
|
self.assertEqual(self.read_file("adir1/adir2/A"), "Hello!\n")
|
|
|
|
def test_case_preserving(self) -> None:
|
|
if self.is_case_insensitive:
|
|
self.assertEqual(self.read_file("adir1/adir2/A"), "Hello!\n")
|
|
self.assertEqual(os.listdir(self.get_path("adir1/adir2")), ["a"])
|
|
|
|
def test_case_preserving_new_files(self) -> None:
|
|
if self.is_case_insensitive:
|
|
self.write_file("MixedCaseFile", "content\n")
|
|
self.assertIn("MixedCaseFile", os.listdir(self.get_path("")))
|