[PATCH STABLE] icasefs: abort update, if added/removed files in working causes case folding collision

Matt Mackall mpm at selenic.com
Mon Apr 9 15:49:02 CDT 2012


On Mon, 2012-04-09 at 21:06 +0900, FUJIWARA Katsunori wrote:
> At Thu, 05 Apr 2012 14:26:21 -0500,
> Matt Mackall wrote:
> 
> > > > diff -r 1d8eab6dfe65 mercurial/merge.py
> > > > --- a/mercurial/merge.py	Tue Apr 03 22:02:04 2012 +0200
> > > > +++ b/mercurial/merge.py	Wed Apr 04 11:45:59 2012 -0500
> > > > @@ -568,7 +568,7 @@
> > > >          action = []
> > > >          folding = not util.checkcase(repo.path)
> > > >          if folding:
> > > > -            _checkcollision(p2, branchmerge and p1)
> > > > +            _checkcollision(p2, wc)
> > > >          if not force:
> > > >              _checkunknown(repo, wc, p2)
> > > >          action += _forgetremoved(wc, p2, branchmerge)
> 
> > Unfortunately, what doesn't work with my patch is that if I rename 'a'
> > to 'A', commit, then try to go backwards, it fails. So it seems we need
> > some rename-awareness in _checkcollision. On the other hand, without my
> > patch, it will clobber newly-added files that collide with old files
> > when going backwards.
> 
> Hi, Matt.
> 
> I want some suggestions about my work.
> 
> At first, I added below logic to collision detection:
> 
>   - check rename/copy if collision is detected BETWEEN working and
>     target context
> 
>     if colliding file in target context is copy of collided file in
>     working context, collision can be ignored: colliding file maybe
>     rename of collided one, because collision is not detected IN
>     target context and it ensures that collided file does not exist in
>     it.
> 
>     this is achieved by result copies.pathcopies(), 
> 
> 
> Then, it is assumed that there are two revisions in linear history
> tree:
> 
>     #1: has 'a' and 'b'
>     #2: has 'A' renamed from 'b', and 'C' renamed from 'a'
>
> On updating from #1 to #2, collision between 'a'@#1 and 'A'@#2 is
> recognized as not ignorable collision, because 'A'@#2 is not copy of
> 'a'@#1, even though it can be renamed to 'C'@#2 safely.

Ok, so your test is this:
        
        hg init a
        cd a
        echo a1 > a
        echo b1 > b
        hg ci -Am0
        hg mv a C
        hg mv b A
        hg ci -Am1
        hg up 0
        echo a2 > a
        echo b2 > b
        hg up

On a case-sensitive system, Mercurial does:

        merging a and C to C
        merging b and A to A
        
..and gives us 'b2' in A and 'a2' in C. Anyone who does this sort of
nonsense is asking for trouble, but we manage to handle it correctly in
this case.

But I'm not sure I really care how we handle this on case-insensitive
systems, as it's a mish-mash of "we changed case" and "we changed file
identities in ways that are hard to untangle". We definitely don't/won't
honor criss-crossing renames in merges, so when we do criss-crossing
+case-changing renames, 

I'm mostly concerned about the a -> A case, and I'm frankly fine with
having other things be collisions.

> Should I check whether files copied from 'a'@#1 exist in #2 or not ?
> 
> 
> In another case, it is also assumed that there are two revisions:
> 
>     #1: has 'a' and 'b'
>     #2: has 'A' renamed from 'b', but no 'a' which was removed
> 
> On updating from #1 to #2, there is no file copied from 'a'@#1 in #2,
> so this will be recognized as not ignorable collision, even though 'a'
> is clean in working context.

..meaning it can be safely deleted, and thus not conflict. Hmm.

> If 'a' is modified in working context in above case, aborting by
> collision seems to be reasonable. But should I abort updating after
> confirmation like below ?
> 
>     local changed 'a' which remote deleted
>     use (c)hanged version or (d)elete?
> 
> # abort updating if 'changed' is chosen

That seems annoying, as I may have carefully answered several other
prompts before getting to this point.

> Perhaps, should I examine case-folding collision not at current point,
> but after manifest merging ? It seems to figure out renaming, coping,
> collision between modifying and removing, and so on: all about what we
> want to know for collision detection.

Perhaps. But it's significantly trickier, I think.

Also note that we want to ignore all these issues on update -C:
colliding files should always win and end up with the target case.

-- 
Mathematics is the supreme nostalgia of our time.




More information about the Mercurial-devel mailing list