{"thread":{"id":"41051","subject":"Case insensitive branch names","startedAt":"2015-12-21T10:22:52Z","lastAt":"2015-12-21T19:58:53Z","messageCount":5,"participants":["Philip Oakley","Duy Nguyen","Junio C Hamano","Torsten Bögershausen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"274800","messageId":"D350A5BC87B74A53B5BE4B10BC658208@PhilipOakley","threadId":"41051","inReplyTo":null,"subject":"Case insensitive branch names","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2015-12-21T10:22:52Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"On the Git User's list, Diego J. reported that:\n\n'When I \"checkout\" a branch using different Upper Case/Lower Case than the\noriginal, the branch doesn't show in \"git branch [--list]\"' [1]\n\nWhile case sensitivity for filenames is a common issue on Windows and the\nlike, I haven't seen any discussion regarding ref name sensitivity - any\npointers to past discussions?\n\nIn particular, if I have a branch 'nocase', and ask to checkout 'NoCase',\nthen git(-for-Windows) will happily say that 'NoCase' has been checked out,\nbut then it gets confusing.\n\nWe are both, not on any branch, and yet not detached. In fact HEAD points to\nNoCase (which does not exist with that case setting). The checkout is\nactually of 'nocase', and 'git branch' does not mark any branch ref current\n(with the *). [see test script: 2].\n\nWhile this is the way it is, should the 'git checkout' in some way check for\nthe branch case sensitivity issue?\n\nFor example, maybe simply correcting the checkout name to that as recorded\nin the File System (but that has lots of code impact because the path and \nname are distinct elements of the branch struct), or maybe a warning could \nbe emitted (config?), or even\nan err/die.\n\nMy gut feeling was that, at least for refs, that something should be done.\nMy delving into the complexities of the code for 'git checkout' got me to\nrefs.c ~#L1603 where the requested path is lstat'd. Perhaps this point is a\nspecial case for the mingw_lstat where the true pathname can be compared to\nthe requested pathname (or at least the refs/heads/name part) to detect this\nmis-checkout case?\n\nThoughts? Is it a rabbit hole others have explored? Is it even worth \npursuing?\n\n--\nPhilip\n\n[1] https://groups.google.com/forum/#!topic/git-users/EryCnwKL4_E\n[2] Script\ngit init casetest\ncd casetest/\n>temp.txt\ngit add -A & git commit -m'first'\ngit status\ngit branch case\ngit branch\n# two branches, * on master.\ngit status\ngit checkout Case\n# successful checkout, uses branch name as given!\ngit branch\n# note that no branch is marked as current, but neither are we detached \nhead..\ngit status\ncat .git/HEAD\n# HEAD records the requested name, not the branch that was actually checked \nout!\n# User left confused...\n\n=== output\nPhilip@PhilipOakley MINGW32 /c\n$ bash -v ./casetest.sh\n\ngit init casetest\nInitialized empty Git repository in C:/casetest/.git/\ncd casetest/\n>temp.txt\ngit add -A & git commit -m'first'\n[master (root-commit) 988c046] first\n1 file changed, 0 insertions(+), 0 deletions(-)\ncreate mode 100644 temp.txt\ngit status\nOn branch master\nnothing to commit, working directory clean\ngit branch case\ngit branch\ncase\n* master\n# two branches, * on master.\ngit status\nOn branch master\nnothing to commit, working directory clean\ngit checkout Case\nSwitched to branch 'Case'\n# successful checkout, uses branch name as given!\ngit branch\ncase\nmaster\n# note that no branch is marked as current, but neither are we detached \nhead..\ngit status\nOn branch Case\nnothing to commit, working directory clean\ncat .git/HEAD\nref: refs/heads/Case\n# HEAD records the requested name, not the branch that was actually checked \nout!\n# User left confused..\n-- \n"},{"id":"274801","messageId":"CACsJy8CEYaf9NA4J_2u1cqsikYvtR7nz=FEiwAxsKMLSREDhCg@mail.gmail.com","threadId":"41051","inReplyTo":"D350A5BC87B74A53B5BE4B10BC658208@PhilipOakley","subject":"Re: [git-for-windows] Case insensitive branch names","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-12-21T12:21:02Z","receivedAt":"2015-12-21T12:21:02Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Dec 21, 2015 at 6:01 PM, Philip Oakley <philipoakley@iee.org> wrote:\n> On the Git User's list, Diego J. reported that:\n>\n> 'When I \"checkout\" a branch using different Upper Case/Lower Case than the\n> original, the branch doesn't show in \"git branch [--list]\"' [1]\n>\n> While case sensitivity for filenames is a common issue on Windows and the\n> like, I haven't seen any discussion regarding ref name sensitivity - any\n> pointers to past discussions?\n\nMultiple ref backend [1] should solve this.It's supposed to help\nhandle a huge number refs. But a side effect from not using file\nsystem for refs is we can handle ref case-sensitivity much easier. And\nI believe David had that in mind he chose lmdb (because of Mac, which\nshares the same problem with Windows)\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/281925\n-- \nDuy\n"},{"id":"274813","messageId":"xmqqa8p3hfej.fsf@gitster.mtv.corp.google.com","threadId":"41051","inReplyTo":"CACsJy8CEYaf9NA4J_2u1cqsikYvtR7nz=FEiwAxsKMLSREDhCg@mail.gmail.com","subject":"Re: [git-for-windows] Case insensitive branch names","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-12-21T17:37:08Z","receivedAt":"2015-12-21T17:37:08Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Duy Nguyen <pclouds@gmail.com> writes:\n\n> On Mon, Dec 21, 2015 at 6:01 PM, Philip Oakley <philipoakley@iee.org> wrote:\n>> On the Git User's list, Diego J. reported that:\n>>\n>> 'When I \"checkout\" a branch using different Upper Case/Lower Case than the\n>> original, the branch doesn't show in \"git branch [--list]\"' [1]\n>>\n>> While case sensitivity for filenames is a common issue on Windows and the\n>> like, I haven't seen any discussion regarding ref name sensitivity - any\n>> pointers to past discussions?\n>\n> Multiple ref backend [1] should solve this.\n\nYup, I had the same reaction.  Instead of restricting the namespace\nof branches even on systems that do not have this problem, use a ref\nbackend that is not limited by the underlying filesystem.  A much\nbetter solution.\n\nIn addition to the LMDB backend, it might not be a bad idea to add\nanother filesystem-based backend that encodes the refnames safely on\ncase insensitive or case destroying filesystem.  That way, those who\ndo not want an extra dependency but do want case sensitive refnames\nwould have an option, and having two non-default backends with quite\ndifferent semantics may be a good way to ensure that the API for\nrefs backend is kept sane.\n"},{"id":"274815","messageId":"5678434B.5040506@web.de","threadId":"41051","inReplyTo":"xmqqa8p3hfej.fsf@gitster.mtv.corp.google.com","subject":"Re: [git-for-windows] Case insensitive branch names","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2015-12-21T18:22:03Z","receivedAt":"2015-12-21T18:22:03Z","isPatch":false,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"\n\nOn 2015-12-21 18.37, Junio C Hamano wrote:\n> Duy Nguyen <pclouds@gmail.com> writes:\n>\n>> On Mon, Dec 21, 2015 at 6:01 PM, Philip Oakley <philipoakley@iee.org> wrote:\n>>> On the Git User's list, Diego J. reported that:\n>>>\n>>> 'When I \"checkout\" a branch using different Upper Case/Lower Case than the\n>>> original, the branch doesn't show in \"git branch [--list]\"' [1]\n>>>\n>>> While case sensitivity for filenames is a common issue on Windows and the\n>>> like, I haven't seen any discussion regarding ref name sensitivity - any\n>>> pointers to past discussions?\n>> Multiple ref backend [1] should solve this.\n> Yup, I had the same reaction.  Instead of restricting the namespace\n> of branches even on systems that do not have this problem, use a ref\n> backend that is not limited by the underlying filesystem.  A much\n> better solution.\n>\n> In addition to the LMDB backend, it might not be a bad idea to add\n> another filesystem-based backend that encodes the refnames safely on\n> case insensitive or case destroying filesystem.  That way, those who\n> do not want an extra dependency but do want case sensitive refnames\n> would have an option, and having two non-default backends with quite\n> different semantics may be a good way to ensure that the API for\n> refs backend is kept sane.\n\nThis has been reported (probably a couple of times),\none copy I have here was under \"Branch Name Case Sensitivity\"\naround Feb/March 2014.\n\nThe lstat() in refs.c can not be fixed, as the underlying OS/FS thinks\nthat lstat(\"nocase\") == lstat(\"NoCase\") and\nopen(\"nocase\") == NoCase\").\n\nThe the \"real name\" will not be detected, unless somebody does\nopendir(), readdir() and closedir().\nThis is expensive (in terms of execution time), and nobody\nhas tried to do something.\n\n\nOne cheap solution would be to run \"git pack-refs\" internally,\neither from C-code inside Git itself, or from a script.\n"},{"id":"274823","messageId":"93EE538CE2634272BABFCEB55C6A091E@PhilipOakley","threadId":"41051","inReplyTo":"5678434B.5040506@web.de","subject":"Re: [git-for-windows] Case insensitive branch names","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2015-12-21T19:58:53Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Torsten Bögershausen\" <tboegi@web.de>\n>\n> On 2015-12-21 18.37, Junio C Hamano wrote:\n>> Duy Nguyen <pclouds@gmail.com> writes:\n>>\n>>> On Mon, Dec 21, 2015 at 6:01 PM, Philip Oakley <philipoakley@iee.org> \n>>> wrote:\n>>>> On the Git User's list, Diego J. reported that:\n>>>>\n>>>> 'When I \"checkout\" a branch using different Upper Case/Lower Case than \n>>>> the\n>>>> original, the branch doesn't show in \"git branch [--list]\"' [1]\n>>>>\n>>>> While case sensitivity for filenames is a common issue on Windows and \n>>>> the\n>>>> like, I haven't seen any discussion regarding ref name sensitivity - \n>>>> any\n>>>> pointers to past discussions?\n>>> Multiple ref backend [1] should solve this.\n>> Yup, I had the same reaction.  Instead of restricting the namespace\n>> of branches even on systems that do not have this problem, use a ref\n>> backend that is not limited by the underlying filesystem.  A much\n>> better solution.\n\nMy thought was more that on a case preserving FS we (that FS Git \nimplementation) might warn if they have ended up not on a valid branch name. \nIt felt wrong that the checkout reported success.\n\n>>\n>> In addition to the LMDB backend, it might not be a bad idea to add\n>> another filesystem-based backend that encodes the refnames safely on\n>> case insensitive or case destroying filesystem.  That way, those who\n>> do not want an extra dependency but do want case sensitive refnames\n>> would have an option, and having two non-default backends with quite\n>> different semantics may be a good way to ensure that the API for\n>> refs backend is kept sane.\n\nA suitable case sensitive, case preserving backend would solve it for those \nusing it, which will be a help. Though those that don't will still need to \nbe careful.\n\n>\n> This has been reported (probably a couple of times),\n> one copy I have here was under \"Branch Name Case Sensitivity\"\n> around Feb/March 2014.\n\nFound the thread \nhttp://thread.gmane.org/gmane.comp.version-control.git/242768/focus=242846\nthough I try to avoid having a 'don't do that' response for some of these \npotentially hazardous cases (though the cost benefit may not justify it;-)\n\n>\n> The lstat() in refs.c can not be fixed, as the underlying OS/FS thinks\n> that lstat(\"nocase\") == lstat(\"NoCase\") and\n> open(\"nocase\") == NoCase\").\n>\n> The the \"real name\" will not be detected, unless somebody does\n> opendir(), readdir() and closedir().\n> This is expensive (in terms of execution time), and nobody\n> has tried to do something.\n\nThat's probably a key bit of info I didn't know - that the true file name \ncan't be known without that overhead. Various stackoverflow Q&As [1] show \nthat others have also had some difficulties...\n\n>\n> One cheap solution would be to run \"git pack-refs\" internally,\n> either from C-code inside Git itself, or from a script.\n>\n\n--\nPhilip\n[1] Windows methods of getting true file name (allegedly)\nhttp://stackoverflow.com/questions/4763117/how-can-i-obtain-the-case-sensitive-path-on-windows/4763137#4763137\nhttp://stackoverflow.com/questions/478826/c-sharp-filepath-recasing/479198#479198\nhttp://stackoverflow.com/questions/74451/getting-actual-file-name-with-proper-casing-on-windows\n"}]}