My favorites | Sign in
Logo
                
New issue | Search
for
| Advanced search | Search tips
Issue 286: Case Sensitity of Directory Names
2 people starred this issue and may be notified of changes. Back to list
Status:  New
Owner:  ----


Sign in to add a comment
 
Reported by robc.the.geek, Jul 01, 2009
What steps will reproduce the problem?
1. Create a directory with some files in and add/commit.
2. Rename the directory to the SAME NAME, but with different casing.
 (e.g. from "files" to "Files")
3. Then do a git status. Note that it is reporting the directory as
untracked, yet you cannot add since the directory is actually already tracked,

What is the expected output? What do you see instead?

I would expect for no changes to be reported since the filename is
technically the same (by Windows standards)

What version of the product are you using? On what operating system?
Git 1.6.3 on Win7 RC

Please provide any additional information below.

In terms of resolution, I guess I would expect:
Either have "git status" be case-insensitive with files/directory names (as
Windows is) OR remove the case-sensitivity on (what I assume to be) the
tracked files lookup on "git add"

Comment 1 by patthoyts, Jul 01, 2009
First check that the core.ignorecase flag has been set true (seems so by default)
 git config --get core.ignorecase

I find that while I cannot 'git mv' a file onto itself I can use an intermediate file
to get the job done and git is then happy about this. Here is a transcript:

C:\temp\g2>git init
Initialized empty Git repository in C:/temp/g2/.git/

C:\temp\g2>git config core.ignorecase true

C:\temp\g2>echo HELLO > HELLO.txt

C:\temp\g2>git add HELLO.txt & git commit -m "Added HELLO"
[master (root-commit) 4ee6ac0] Added HELLO
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 HELLO.txt

C:\temp\g2>git mv HELLO.txt Hello.txt
fatal: destination exists, source=HELLO.txt, destination=Hello.txt

C:\temp\g2>git mv HELLO.txt Hello.txt.tmp

C:\temp\g2>git mv Hello.txt.tmp Hello.txt

C:\temp\g2>git st
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       renamed:    HELLO.txt -> Hello.txt
#

C:\temp\g2>git commit -m "Renamed it"
[master f72a97b] Renamed it
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename HELLO.txt => Hello.txt (100%)

C:\temp\g2>git log --pretty=oneline --abbrev-commit
f72a97b Renamed it
4ee6ac0 Added HELLO

At this point I can checkout the 4ee6ac0 version and get HELLO.txt and move back to
the f72a97b version and get Hello.txt again.


Comment 2 by robc.the.geek, Jul 01, 2009
I never actually tested with files since I have never had an issue.. I did however
check the ignorecase option and can confirm it is set to true.

The problem still remains for directories:

Rob@DESKTOP /c/temp/Test
$ git init
Initialized empty Git repository in C:/temp/Test/.git/

Rob@DESKTOP /c/temp/Test (master)
$ mkdir TEST

Rob@DESKTOP /c/temp/Test (master)
$ echo "hi" > test\\hi.txt

Rob@DESKTOP /c/temp/Test (master)
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       TEST/
nothing added to commit but untracked files present (use "git add" to track)

Rob@DESKTOP /c/temp/Test (master)
$ git add . & git commit -a -m "Added Files"
[1] 3604
warning: LF will be replaced by CRLF in TEST/hi.txt
[master (root-commit) a78e46b] Added Files
warning: LF will be replaced by CRLF in TEST/hi.txt
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 TEST/hi.txt
[1]+  Done                    git add .

Rob@DESKTOP /c/temp/Test (master)
$ git status
# On branch master
nothing to commit (working directory clean)

Rob@DESKTOP /c/temp/Test (master)
$ mv TEST test1

Rob@DESKTOP /c/temp/Test (master)
$ mv test1 test

Rob@DESKTOP /c/temp/Test (master)
$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       test/
nothing added to commit but untracked files present (use "git add" to track)

Rob@DESKTOP /c/temp/Test (master)
$ git add .

Rob@DESKTOP /c/temp/Test (master)
$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       test/
nothing added to commit but untracked files present (use "git add" to track)

Note here that the "test" folder is reported as not being tracked, but cannot be then
added since it is already being tracked as "TEST"..

I hope that clarifies enough, if not, please do shout.
Comment 3 by patthoyts, Jul 02, 2009
I would say the the important difference here is that you are using 'mv' to rename
the directory or file. You should use 'git mv'. The example I posted previously works
just as well with a directory but again using 'git mv' to notify git that you are
moving things about.
Comment 4 by robc.the.geek, Jul 02, 2009
Ah yes, I can replicate that it works fine with "git mv" - and I agree with the
sentiment that files should be moved as such.

However,
I actually came across this because I made the change in VS. And the main reason I am
raising the issue is because the same behaviour is not exhibited by files - so, my
question (playing devils advocate) would be "Why the difference?"

I can understand that the "blue skies" approach renders this "not a bug" but I think
from a usability perspective, it would make sense to have files and folders treated
the same way?

Thoughts?

PS: Keep up the great work, I am pretty new to Git and loving it :) I have never had
such a smooth transition :)
Comment 6 by kusmabite, Aug 11, 2009
I had a quick peek at this one, and it seems to be a tricky one. The symptoms are a 
bit nasty:
- The newly added folder is listed as untracked, but...
- The old folder-contents is not listed as missing.

I guess we should either show it as untracked (and thus detect the contents as 
missing as well) or accept the folder as completely unchanged. This something-in-the-
middle behavior is undesirable.

The folder seems to be listed as untracked because directory_exists_in_index() tries 
to compare the old name to the new name, and ending up not finding a match for the 
new folder (even though the file inside it remains tracked!). A very rude patch 
(inlined below) was written to try to work around the issue. Now... for my minimal 
case, this works - the directory is no longer listed as untracked. But I strongly 
expect this to be a BROKEN patch for at least the following reason: Case insensitive comparison should break binary searching, as the casing should return the wrong 
position if I had more files in the index. 

---
 dir.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/dir.c b/dir.c
index e05b850..c55a15c 100644
--- a/dir.c
+++ b/dir.c
@@ -444,7 +444,7 @@ static enum exist_status directory_exists_in_index(const char 
*dirname, int len)
                struct cache_entry *ce = active_cache[pos++];
                unsigned char endchar;

-               if (strncmp(ce->name, dirname, len))
+               if (strnicmp(ce->name, dirname, len))
                        break;
                endchar = ce->name[len];
                if (endchar > '/')
--
1.6.4.msysgit.0.2.gcb017.dirty
Comment 7 by johannes.schindelin, Aug 13, 2009
I think this must be guarded by "if (ignore_case)"...
Sign in to add a comment

Hosted by Google Code