git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: file name case-sensitivity issues

From
Junio C Hamano <junkio@cox.net>
Date
May 25, 2006, 18:17 UTC
Message-ID
<7vac96ufxv.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<20060525154735.GA6119@steel.home>
fork0@t-online.de (Alex Riesen) writes:
> ... Besides, how about when you
> don't _know_, like when cloning onto an usb-stick mounted with
> auto-detection? Will the files with case-different names just
> overwrite each other?

You _do_ realize that example is bogus, don't you? At least I hope you did after you sent it.

You are cloning a project that has mixed cases (say foo and FOO) onto a case challenged filesystem but unfortunately you did not know the filesystem was case challenged in advance. So after the cloning, your checkout results in only one file either foo or FOO but not both, because you cannot have two files whose names are different only in case on such a filesystem.

Tough.

There are some other problems on case challenged filesystems that we _could_ solve but we probably don't right now. You could concentrate on fixing those, instead of talking about unfixable.

There are probably 2 kinds of case-challenged-ness. On non case-challenged filesystems, if I say "rm -f foo Foo; echo >foo; echo >Foo", "ls" says "foo Foo". On case-challenged systems, one of the following would happen:

 * "ls" says "foo".  If I swap the order of the "echo", it says
   "Foo".  The filesystem does record the case but does not
   allow two names with only case difference.
 * "ls" says ef oh oh in a case different from either "foo" nor
   "Foo".  Or it says "foo" but if I swap the order of the
   "echo", it still says "foo".  The filesystem does not record
   the case, and does not allow two names with only case
   difference.  readdir() may do some heuristics such as
   lowercasing the name, but the point is the returned string is
   unrealiable.

I have git installed on a Cygwin on NTFS at work, and I think it is in the former category. git seems to work as expected, modulo that you obviously cannot have two files "foo" and "Foo" in your git-managed project. Probably a patch to delete "Foo" and create "foo" (to make your project friendlier to Windows) and a merge to do the same would work well, though I haven't tried.

What breaks on filesystems in the latter category? I suspect not many.

update-index records the names given by the user (I am assuming that at least the shell is case sensitive), uses that name to stat() and open() to update and/or refresh the cache entry, so that codepath should be OK. Anything that goes from index to find names and then goes to the filesystem with those names (diff family, checkout-index and read-tree -u) should be fine.

ls-files -o/-i would have a hard time, since they need to work with strings read from readdir(), as you found out. That means "git add" and "git clean" may not work.

I do not think of anything else that is affected by readdir() breakage offhand; the core is doing pretty fine as it is (I do not consider ls-files -o/-i a core -- that is more Porcelainish part of the whole package).

I honestly think that on Windows people would not even want to use the core Porcelainish nor even Cogito. The would want a native Window-ish UI that drives the core. I do not think such a program would internally call "git add" nor read from "ls-files -o/-i". It would instead do its own Folder hierarchy traversal, and use "update-index --add --remove" to implement its own "git add/rm" UI, and read from "ls-files" (not -o nor -i) so that it can show tracked and untracked files differently in its Explorer view.

So in that sense, I think ls-files -o/-i issue is quite low priority. It does not matter on sane filesystems, and in the place where it matters the most, the desired solution does not involve ls-files -o/-i working well there.

Having said that, I think you _could_ have a repository configuration that says "this repository sits on a case challenged filesystem", and update ls-files to munge what it gets from readdir() by comparing them against what you have in the index. If your readdir() gives "foo" when you have "FOO" in the index on such a filesystem, you do not say that "foo" is an untracked file -- you just say you found "FOO" as you expected.

Previous: Alex RiesenNext: Christopher Faylor
Message 9 of 10 in “file name case-sensitivity issues”
  1. Alex RiesenMay 23, 2006
  2. Linus TorvaldsMay 23, 2006
  3. Linus TorvaldsMay 23, 2006
  4. Ben CliffordMay 23, 2006
  5. Junio C HamanoMay 24, 2006
  6. Ben CliffordMay 24, 2006
  7. Junio C HamanoMay 23, 2006
  8. Alex RiesenMay 25, 2006
  9. Junio C HamanoMay 25, 2006
  10. Christopher FaylorMay 26, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.