diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -478,6 +478,17 @@ def _checkcollision(repo, wmf, actions): % (f, foldmap[fold])) foldmap[fold] = f + # check case-folding of directories + foldprefix = unfoldprefix = lastfull = '' + for fold, f in sorted(foldmap.items()): + if fold.startswith(foldprefix) and not f.startswith(unfoldprefix): + # the folded prefix matches but actual casing is different + raise error.Abort(_("case-folding collision between " + "%s and directory of %s") % (lastfull, f)) + foldprefix = fold + '/' + unfoldprefix = f + '/' + lastfull = f + def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial, acceptremote, followcopies): """ diff --git a/tests/test-casecollision-merge.t b/tests/test-casecollision-merge.t --- a/tests/test-casecollision-merge.t +++ b/tests/test-casecollision-merge.t @@ -212,7 +212,7 @@ Directory/file case-folding collision: $ hg ci -Aqm1 $ hg merge 0 - abort: Not a directory: '$TESTTMP/directory-casing/aA/a' + abort: case-folding collision between Aa and directory of aA/a [255] (note: no collision between 0 and 00 or 000/f)