Subject: Re: Efficiently detecting paths that differ from each other only in case

From: Jonathan Nieder <[email-masked]>
Date: Fri, 8 Oct 2010 14:56:58 -0500

Dun Peal wrote:

> git ls-files thus takes a long time, almost a second. Since this is a
> commit-heavy repo, I'd rather avoid that overhead.
> 
> Incidentally, there's an SVN hook that does the exact same thing that
> I want to do:
> 
> http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/case-insensitive.py

Well, can't you do the same thing that hook does?

1. Decide on the desired semantics.

Should a broken push of multiple branches be entirely rejected, or
just the broken branches?  The answer determines whether you should
be using a pre-receive or an update hook; see githooks(5).

2. Get a list of added files with git-diff-tree(1) --diff-filter.
3. Break file names into directory + basename.
4. For each directory with new files or subdirectories:
    - List its children in the new version with git-ls-tree(1)
    - Canonicalize path names
    - Find clashes

If this should be general-purpose, take care to handle:

 - new branches (<old-value> = 00000000...)
 - new subdirectory whose name clashes with an existing file
 - filename clash within a new subdirectory

Good luck,
Jonathan