On Wed, 16 Dec 2015 23:37:50 +0100
Magnus Therning <mag...@therning.org> wrote:

> Diego J. writes:
> > When I "checkout" a branch using different Upper Case/Lower Case
> > than the original, the branch doesn't show in "git branch [--list]"
> >
> >
> > <https://lh3.googleusercontent.com/-sIU-pyQEsZ8/VnGJK2sekgI/AAAAAAAAAtc/soIgcKcUwCA/s1600/1.PNG>
> Here's what happens on Linux (git version 2.6.4):
> ~~~
> $ git co mASter
> error: pathspec 'mASter' did not match any file(s) known to git.
> ~~~
> Could this be something related to the case insensitivity of the
> Windows file system?

While (I think) nothing in Git documentation discusses the actual
*implementation* of the concept of a branch in Git, all
"refs" (branches, tags and special things like HEAD, ORIG_HEAD,
MERGE_HEAD, FETCH_HEAD etc) in Git are implemented using plain files
kept on the filesystem (under the ".git" subdirectory).

This means that when one runs `git checkout foObAr` Git actually scans
the ".git/refs/heads" directory trying to file a name named "foObAr"
there.  Git was originally written with POSIX systems in mind, and this
standard dictates that the filesystem has case-sensitive semantics.
This means, that it's okay for the files "foobar" and "foObAr" to
coexist in the same directory.

But on Windows, which traces its heritage to MS-DOS (and beyond)
filesystems are case-insensitive, including all versions of NTFS (what
is used in modern Windows for "regular" partitions -- as opposed to pen
drives etc).  This means two things:

* On NTFS, you can't have two files "foobar" and "foObAr" in the same
  directory because their names are considered the same.
* On NTFS, when you try to open a file named "foObAr" and there exists
  a file named "foobar", it will be opened -- because, again,
  case-insensitive file systems consider these two names to be

One final "trick" is that while NTFS is case-insensitive,
it's case-preserving.  This means when you create a new file and name
it "foObAr", this named will be stored exactly as specified on the
filesystem, but subsequent attempts to access this file as "foobar" or
"foObAr" or "FOOBAR" will all succeed.

So that's what happens: when you run `git checkout foObAr` on Windows,
git looks into the ".git/refs/heads" directory and tries to open a file
named "foObAr" -- representing a branch -- there.  Suppose there's a
file named "foobar" instead.  So it will be opened, read, and the branch
"foobar" checked out.   Note that the "true" name is used everywhere
else in Git because that "foObAr" name was used only to locate the
necessary file; once it was located, it's name as recorded on the file
system is used.  This explains why `git status` shows that "true" name.

You received this message because you are subscribed to the Google Groups "Git 
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to