Reputation: 7197
something is wrong in my git repository. I get different case for the branch folder name. git branch -r
gives me US/blabla git ls-remote
gives me us/blabla thats true for all the remote us/
why is this happening, how can I make both command return the lowercase version?
command:
git branch -r | grep US/blabla
returns:
origin/US/99867_blabla
command:
git ls-remote origin US/99867_blabla
returns nothing
command:
git ls-remote origin us/99867_blabla
returns
`12312362b8f4e6dc0e1c34880f96d525d2d19d30 refs/heads/us/blabla`
command:
git branch
returns
* master
Upvotes: 1
Views: 1208
Reputation: 487865
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.
Upvotes: 6
Reputation: 30858
origin/US/99867_blabla
is a remote-tracking branch that exists in the local repository, and refs/heads/us/blabla
returned by git ls-remote
is a branch that exists in the remote repository.
From the output of the 3 commands, we can guess that US/99867_blabla
does not exist in the remote repository any longer. It may have been renamed or deleted. If so, the local origin/US/99867_blabla
is negligible and useless.
Try git fetch --prune
, which is expected to create origin/us/blabla
and delete origin/US/99867_blabla
.
Upvotes: 0