On Wed, Oct 12, 2022 at 11:49 PM Tao Klerks <tao@xxxxxxxxxx> wrote: > [...] > I understand that case-folding is a complex topic, and doing it > correctly in some universal sense is undoubtedly beyond me - but "my" > context certainly does not require a high standard of correctness: > There's a repo shared by some 1000 engineers, 200k files, lots of > activity, three different OSes of which two default to > case-insensitive filesystems, and every once in a while a user on > linux creates a case-insensitive-duplicate file with differing > content, which causes git on case-insensitive filesystems to lose the > plot (you end up with one file's content looking like changes to the > other file's content - "ghost changes" that appear as soon as you > check out, that prevent you from doing a simple "pull", and that you > just can't reset). I've felt that same pain. > I don't imagine I can make a perfectly correct and universal fix to > this, but with case-insensitive matching on ls-tree in an update hook > I believe I could reduce the frequency of this already-infrequent > issue by at least 1000X, which would suit my purposes just fine. In my > case filenames are mostly ansi-based, and I don't expect we've ever > had Turkish filenames (turkish "i" being the most famous case-folding > gotcha I think?). How exactly would case-insensitive matching in ls-tree help you here? Can't you write a hook without such capability that rejects such collisions? > I don't see this being something I can take on in my spare time, so > for now I suspect I'll have to do a full-tree duplicate-file-search on > every ref update, and simply accept the 1-second update hook > processing time/delay per pushed ref :( I don't see why you need to do full-tree with existing options, nor why the ls-tree option you want would somehow make it easier to avoid. I think you can avoid the full-tree search with something like: git diff --diff-filter=A --no-renames --name-only $OLDHASH $NEWHASH | sed -e s%/[^/]*$%/% | uniq | xargs git ls-tree --name-only $NEWHASH | \ sort | uniq -i -d The final "sort | uniq -i -d" is taken from Torsten's suggestion. The git diff ... xargs git ls-tree section on the first line will provide a list of all files (& subdirs) in the same directory as any added file. (Although, it has a blind spot for paths in the toplevel directory.)