Wiki Tools

  • Find Page
  • Recent Changes
  • Page History
  • Attachments


Add support for handling working trees on case-insensitive filesystem (CIF), so bzr can follow filesystem policy of access to filenames by different case names.

Note that this page doesn't make a distinction between case-insensitive filesystems and case-preserving file systems as commonly used by Windows. See the CasePreservingWorkingTreeUseCases document for some thoughts on this.


It's important for good Windows support. Even Linux users could facing with CIF: per example by accessing to files on USB Flash disk, formatted as FAT.

Further Details

Good support of CIF allows users to easily change case of their files without explicit notification of bzr, and bzr would not treat such files as missing. This important because changing of filename case may be done implicitly by some pogram without of notification to user. E.g. by some editor or text pocessing program, or the file initially created manually and later refreshed with some autogenerator program that force their own policy about file naming.

It's also important to make ignore patterns (like *.bak) on CIF works also with ignoring case.


Working tree entirely lies in either case insensitive filesystem or case sensitive filesystem.

Use Cases

  • All Windows users everyday works with CIF
  • Linux users working with USB FLash disk with FAT filesystem implicitly faced with CIF
  • A user on a case sensitive system creates a file differing only by case (File.c and file.c). When checking out that project on a CIF, there should be some method of resolution. It could be an early generated conflict, refusing to update. Or it could recognize the conflict and create one of the files as "File.c.moved" or the some other suffix.
  • Windows shells may pass a "incorrectly" cased value for ${PWD} to Python/Bazaar under some circumstances


UI Changes

Support of CIF should be implemented seamless, so no UI changes required.

Although, it could be useful (e.g. for testing or in some sort of cross-platform project) to have global flag to force bzr treats current branch/working tree as one placed on CIF. With such flag bzr should disallow to adding two or more files with names that only differs by case.

Code Changes

  • Auto-detecting of CIF at the opening of WorkingTree by fast check of presence of one of system file inside .bzr directory in wrong case (e.g. test presence of file .bzr/branch-format by accessing via uppercased name .bzr/BRANCH-FORMAT)

  • WorkingTree should simultaneously deal with 2 forms of filename:

    1. real filename (on disk) -- user visible, saved in inventory
    2. normalized name (lowercased for CIF, and without changing of original for non-CIF) -- to compare files
  • All operations by comparing and selecting files should work only with normalized names
    • ignore patterns applied with ignore case flag
    • status of working tree should ignore changes in case
    • adding files by name/pattern should also convert this patterns to normalized form and then used to filter out filenames on disk
    • selecting files to commit also should use normalized name
  • Rename file with only changing case of name should be tracked correctly
  • Initial checkout of tree with 2 or more files with names dfferent only by case should be automatically stopped with corresponding explanation of problem with CIF
  • Merge from non-CIF branch to CIF branch could produce filenames conflits with auto-renaming one of file to foo.moved

Data Migration

It seems that support of CIF don't require changes in inventory format.


Unresolved Issues

  • Does implicit changing of name case should be tracked as rename? Probably, yes.
    • -- This seems to contradict "status of working tree should ignore changes in case", because renames are shown by status, and committable changes really ought to be shown by status


  • Does bzr needs new type of conflicts for collision of files created on non-CIF while merging and checkout to CIF?
    • My guess is that the existing DuplicateEntry conflict type will work fine for this. -- AaronBentley

      Could do though I'm wondering if having CIF-compatibility as all or nothing might be simpler. --StuartColville

  • Should we provide a way for projects to be CIF-compatible, even if developed on case-sensitive filesystems? For example, since Bazaar is a cross-platform project, it would make sense to forbid adding files that differ only in case from existing files. And since a CIF developer might ignore *.BAT, it should match bzr.bat on case-sensitive filesystems. This suggests that case-sensitivity might be a branch property, an inventory property or a revision property as well as a working tree property.

    • I totally concur with this point. Anyone working with devs using a mix of operating Systems that have both CIF and CF, will need to run their project in CIF mode --StuartColville

  • If CIF compatibility is configurable should CIF-compatibility be the default? --StuartColville

  • I'd like to see about implementing this by having everything that accesses the working files go through a bottleneck rather than straight to the filesystem - maybe through methods on WorkingTree/MutableTree. I'm not saying that they should go through Transport, which currently has a more restricted purpose. We can still require that they be local. But that would then give us a clean way to intercept them in the test suite and simulate a case-insensitive or unicode-normalizing filesystem on systems that aren't natively that way. -- MartinPool

    • Is not this bottleneck will be performance bottleneck in the end? --AlexanderBelchenko

      • It seems doubtful. System calls are relatively expensive, and the operations that affect large numbers of files (merge, revert, build_tree) are already going through TreeTransform, which goes through _FileMover. Another layer of indirection would probably not be significant. And we might be able to avoid adding another layer anyhow, by customizing TreeTransform or _FileMover according to case. -- AaronBentley

Questions and Answers