Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case-insensitive filename handling in Mercurial

I'm using TortoiseHg 0.5 (which includes Mercurial 1.0.2) on Vista64. My understanding from the Mercurial Book is that Mercurial should handle filenames in a case-insensitive manner on a case-insensitive filesystem (such as NTFS, which is what I'm on). However I find that my installation of Mercurial is in fact sensitive to case:

>hg status -A foo
C foo
>hg status -A FOO
? FOO

Could this be a bug in Mercurial, a bug in the TortoiseHg build of Mercurial, or is it something else? How can I achieve case-insensitive filename handling from Mercurial on Windows?

like image 564
Mentat Avatar asked Oct 26 '08 20:10

Mentat


2 Answers

This issue has been resolved in Mercurial 1.1! From the release notes: "Improved correctness in the face of casefolding filesystems".

On Windows, Mercurial now ignores case in its command line arguments:

>hg status -A foo
C foo
>hg status -A FOO
C foo

And it also is aware that filename changes that only involve case are not new files:

>ren foo FOO
>hg status -A fOO
C foo

Thus there's no longer any risk of overlooking changes due to mistypes on the command line.

However, be aware that the contents of the .hgignore file remain case sensitive. This is an issue only if you're using glob syntax; with regexp syntax you can put (?i) at the beginning of patterns to make them insensitive.

like image 75
Mentat Avatar answered Oct 21 '22 19:10

Mentat


I think you misread the hgbook. The intro to section 7.7 is just describing the three different types of case sensitivity that exist in OSs, not saying that mercurial will mirror those semantics.

Later in section 7.7.2 'Detecting case conflicts' it says:

When operating in the working directory, Mercurial honours the naming policy of the filesystem where the working directory is located. If the filesystem is case preserving, but insensitive, Mercurial will treat names that differ only in case as the same.

When you do hg status -A FOO the process that's happening within mercurial is:

  1. Check if a file exists on the file system matching the file argument, 'FOO', -- and at this point it's being case insensitive so it finds 'foo' and says "yup, I've got a file"
  2. Check if there's an entry in the file manifest matching the file argument, 'FOO', and there isn't, so status shows a '?' saying it's a file on disk that hg isn't tracking

To better see mercurial not caring about case on NTFS try these steps:

  1. hg init
  2. echo line > Foo
  3. hg add Foo
  4. hg commit -m 'committed Foo'
  5. move Foo not-foo
  6. move not-foo FOO
  7. hg status

and you should see hg saying that nothing has changed because the only thing that has changed is the case which hg is ignoring for you.

When I do the same thing on linux I instead see:

! Foo
? FOO
like image 7
Ry4an Brase Avatar answered Oct 21 '22 17:10

Ry4an Brase