Branch Name Case Sensitivity

263 views
Skip to first unread message

lee...@gmail.com

unread,
Feb 21, 2014, 3:37:02 PM2/21/14
to msy...@googlegroups.com
So I ran across an interesting problem with branch name case, I looked around the GitHub issue list and the mailing list a little bit and could not find anything similar. 

So the situation is: I have a shared, bare, repository on a windows file share that is pushed to and pulled from via file protocol and someone managed to push a branch to it that had the same name as an existing branch in the repo, except the case differed. The repo looked like it had lost its mind and some minor fire fighting ensued. I believe the problem arose when a push resulted in a git gc being run on the shared repo. I know the vast majority of the time git gc does not get run, but it is the only explanation I could come up with.

I managed to reliably reproduce the scenario (using msysgit 1.8.3 on Windows 8.1):

> mkdir repo
> mkdir devs
> cd devs
> mkdir dev1
> mkdir dev2
> cd ..\repo
> git init --bare .
> cd ..\devs\dev1
> git init .
...create a file and edit it...
> git add --all
> git commit -a -m "init commit"
> git remote add origin C:\path\to\repo
> git push origin master
> cd ..\dev2
> git clone C:\path\to\repo .
> git checkout -b foo
> cd ..\dev1
> git checkout -b Foo
...make some changes...
> git add --all
> git commit -a -m "commit message"
> git push origin Foo
...now simulate a git gc...
> cd ..\..\repo
> git gc
...this will remove all branch pointers in refs\heads and pack them into the packed-refs file...
> cd ..\devs\dev2
> git branch
*foo
master
> git push origin foo
...git allows this because there is no foo file in refs\heads and the branch name in packed-refs is Foo...

If you now try to look at the logs for the remote repo, both Foo and foo have identical logs and seemingly point to the same SHA1. If dev1 attempts to push or pull to either Foo or foo, errors are generated. I understand why this happens, but I'm not sure how to prevent it. If you do not run git gc on the remote repo and dev 2 tries to do git push origin foo, it is not allowed (which is to be expected). 

My particular case had an extra wrinkle in it that I can't explain: we had a branch named Dev in the central repo and the pointer in the packed-refs file for the Dev branch was 2 weeks old. I assume at one point there was a more up to date pointer in refs/heads/Dev. However, when someone pushed a branch called dev to the repo, the pointer refs/heads/Dev was overwritten or deleted. I have been assured that no one deleted or edited the pointer manually, so the only explanation I can come up with is when the push was executed, a git gc was also performed. The git gc cleaned up refs/heads and then the push created a pointer at refs/heads/dev. The dev branch was accidentally pushed, it was an old local branch (2 months out of date), so now the central repo looked like it was 2 months old and could not differentiate between the Dev and dev branches. 

I renamed the dev branch to dev-bad like so:
> git branch -m dev dev-bad

This brought the Dev branch back to life, but since the packed-refs pointer was 2 weeks old we were still missing some commits. These were recreated by someone pushing their local (up to date) Dev branch back to the central repo. In the end we did not lose any commits, but it did create some minor panic and some head scratching. 

The part I am confused about is if a git gc was performed, the packed-refs file should have had an up to date SHA1 reference for the Dev branch so simply renaming the dev branch should have brought the Dev branch back to life with an up to date history. In fact, if you followed my little mini scenario above, you could run git branch -m foo foo-bad and the Foo branch comes back to life with an updated history. Can anyone shed some light on this? Is there any other automated git internal process that could have deleted/overwritten the refs/head/Dev pointer?

So, how can the above scenario be prevented? Is this a known issue? Should a GitHub issue be opened?

Thanks!
-Lee


Johannes Schindelin

unread,
Feb 23, 2014, 5:22:43 PM2/23/14
to lee...@gmail.com, msy...@googlegroups.com
Hi,

On Fri, 21 Feb 2014, lee...@gmail.com wrote:

> So, how can the above scenario be prevented? Is this a known issue? Should
> a GitHub issue be opened?

This is a known issue: it stems from the fact that refs are stored as
plain files except when they are packed into packed-refs. Therefore, as
long as the file system has problems with discerning names that differ
only in name, Git will do a bad job.

This is, however, not a Windows-specific problem but affects all setups
with such file systems (MacOSX' default file system is also
case-insensitive). It would therefore be appropriate to bring this to the
Git developers' attention at g...@vger.kernel.org.

Ciao,
Johannes
Reply all
Reply to author
Forward
0 new messages