Git itself thinks that all uppercase letters are always distinct from all lowercase letters. Hence a file or branch named NAME
is always different from one named name
. A file named INCLUDE/IP.H
is different from one named include/ip.h
. Note that these two names have a slash in them. There is no folder named INCLUDE
or include
here, there are just files named INCLUDE/IP.H
and include/ip.h
. The same holds for branch names: FEATURE/NAME
and feature/name
do not have any folders; they're just two different branch names.
At various times, however, Git is forced, by your computer, to place these file or branch names into your computer's file and/or folder names.1 If the file system provided by your computer requires that slashes imply folders, Git will create a folder for you at this time, so as to hold the full name. If the file system provided by your computer conflates uppercase and lowercase, so that NAME
and name
are considered "the same file" and INCLUDE
and include
are "the same folder", the various files and folders that Git is trying to create and use here will get mixed together.
What Git does with these problematic cases is to make you, the user, miserable. The people who write and support Git code have put in various attempts to make the experience less horrible, but none of them have really solved the problem, because there is no single satisfactory solution. Your best bet is to avoid this situation entirely, if you can. If not, you must live with the weirdness until you manage to rename everything to get out of this bad situation.
Make sure that you are consistent in when or whether you use uppercase or lowercase. One relatively easy way to deal with all of this is to obtain a Linux system (or a Linux VM with a private file system), or create a case-sensitive file system on your computer, so that when Git goes to create a folder or file named NAME
and another different folder or file named name
, it winds up with two different folders / files. Using Git on this system will work fine and will give you the opportunity to get rid of files and/or branches that use the "wrong" case.
Remember that in Git, history is commits. Commits contain files (never any folders, just files, even if their names have slashes in them) and those files have names, and uppercase letters are always different from lowercase ones here. Old commits cannot be changed so if you have files that differ only in case in these old commits, they will continue to be that way in the old commits. Just make new commits in which the problem no longer exists, and avoid using the old commits on computers / file-systems where they are a problem. If necessary, you can even "rewrite history" by copying the old problematic commits to new-and-improved ones that avoid the problem, then making your branch and tag and other names remember only the new commits. Remember that any Git repository that has the old commits will re-introduce them to your fixed-up Git repository, so if you do rewrite history, everyone with a clone of the bad history must get rid of the bad history somehow—typically by abandoning the old clone entirely.
Fortunately, in your case, the issue is just branch names. Unfortunately, branch names also get copied by cloning. Fortunately, they're merely copied to remote-tracking names. So once you've fixed up the original source of the misery, you can, on each clone, just delete all remote-tracking names and then re-obtain them all, perhaps using:
git remote remove origin
followed by:
git remote add origin <url>
git fetch origin
with the appropriate URL (you can save it before doing the git remote remove
operation).
1Since Git is eventually going to put information about a branch named feature/name
into a folder named feature
containing a file named name
, Git won't let you create a branch named feature
if you have a branch named feature/name
. That accommodates the fact that even on a Linux system with case-sensitive file names, Git can't create both a file named feature
and a file named feature/name
. If Git always stored all branch information in encoded names, rather than just using the branch's name as a path-name, this particular problem would go away—as would the case-folding issues. In my opinion, this is the right way to solve all the branch case-folding problems. It does nothing for any file name case-folding problems, though.