mercurial/copies.py
changeset 30202 a005c33d0bd7
parent 30201 856ead835f56
child 30203 b94b92f0c683
equal deleted inserted replaced
30201:856ead835f56 30202:a005c33d0bd7
   287         fctx._ancestrycontext = ac
   287         fctx._ancestrycontext = ac
   288         fctx._descendantrev = rev
   288         fctx._descendantrev = rev
   289         return fctx
   289         return fctx
   290     return util.lrucachefunc(makectx)
   290     return util.lrucachefunc(makectx)
   291 
   291 
       
   292 def _combinecopies(copyfrom, copyto, finalcopy, diverge, incompletediverge):
       
   293     """combine partial copy paths"""
       
   294     remainder = {}
       
   295     for f in copyfrom:
       
   296         if f in copyto:
       
   297             finalcopy[copyto[f]] = copyfrom[f]
       
   298             del copyto[f]
       
   299     for f in incompletediverge:
       
   300         assert f not in diverge
       
   301         ic = incompletediverge[f]
       
   302         if ic[0] in copyto:
       
   303             diverge[f] = [copyto[ic[0]], ic[1]]
       
   304         else:
       
   305             remainder[f] = ic
       
   306     return remainder
       
   307 
   292 def mergecopies(repo, c1, c2, base):
   308 def mergecopies(repo, c1, c2, base):
   293     """
   309     """
   294     Find moves and copies between context c1 and c2 that are relevant
   310     Find moves and copies between context c1 and c2 that are relevant
   295     for merging. 'base' will be used as the merge base.
   311     for merging. 'base' will be used as the merge base.
   296 
   312 
   358 
   374 
   359     # gather data from _checkcopies:
   375     # gather data from _checkcopies:
   360     # - diverge = record all diverges in this dict
   376     # - diverge = record all diverges in this dict
   361     # - copy = record all non-divergent copies in this dict
   377     # - copy = record all non-divergent copies in this dict
   362     # - fullcopy = record all copies in this dict
   378     # - fullcopy = record all copies in this dict
       
   379     # - incomplete = record non-divergent partial copies here
       
   380     # - incompletediverge = record divergent partial copies here
   363     diverge = {} # divergence data is shared
   381     diverge = {} # divergence data is shared
       
   382     incompletediverge  = {}
   364     data1 = {'copy': {},
   383     data1 = {'copy': {},
   365              'fullcopy': {},
   384              'fullcopy': {},
       
   385              'incomplete': {},
   366              'diverge': diverge,
   386              'diverge': diverge,
       
   387              'incompletediverge': incompletediverge,
   367             }
   388             }
   368     data2 = {'copy': {},
   389     data2 = {'copy': {},
   369              'fullcopy': {},
   390              'fullcopy': {},
       
   391              'incomplete': {},
   370              'diverge': diverge,
   392              'diverge': diverge,
       
   393              'incompletediverge': incompletediverge,
   371             }
   394             }
   372 
   395 
   373     # find interesting file sets from manifests
   396     # find interesting file sets from manifests
   374     addedinm1 = m1.filesnotin(mb)
   397     addedinm1 = m1.filesnotin(mb)
   375     addedinm2 = m2.filesnotin(mb)
   398     addedinm2 = m2.filesnotin(mb)
   396         _checkcopies(c2, f, m2, m1, base, tca, limit, data2)
   419         _checkcopies(c2, f, m2, m1, base, tca, limit, data2)
   397 
   420 
   398     copy = dict(data1['copy'].items() + data2['copy'].items())
   421     copy = dict(data1['copy'].items() + data2['copy'].items())
   399     fullcopy = dict(data1['fullcopy'].items() + data2['fullcopy'].items())
   422     fullcopy = dict(data1['fullcopy'].items() + data2['fullcopy'].items())
   400 
   423 
       
   424     if dirtyc1:
       
   425         _combinecopies(data2['incomplete'], data1['incomplete'], copy, diverge,
       
   426                        incompletediverge)
       
   427     else:
       
   428         _combinecopies(data1['incomplete'], data2['incomplete'], copy, diverge,
       
   429                        incompletediverge)
       
   430 
   401     renamedelete = {}
   431     renamedelete = {}
   402     renamedeleteset = set()
   432     renamedeleteset = set()
   403     divergeset = set()
   433     divergeset = set()
   404     for of, fl in diverge.items():
   434     for of, fl in diverge.items():
   405         if len(fl) == 1 or of in c1 or of in c2:
   435         if len(fl) == 1 or of in c1 or of in c2:
   414 
   444 
   415     if bothnew:
   445     if bothnew:
   416         repo.ui.debug("  unmatched files new in both:\n   %s\n"
   446         repo.ui.debug("  unmatched files new in both:\n   %s\n"
   417                       % "\n   ".join(bothnew))
   447                       % "\n   ".join(bothnew))
   418     bothdiverge = {}
   448     bothdiverge = {}
   419     bothdata = {'copy': {},
   449     bothincompletediverge = {}
   420                 'fullcopy': {},
   450     both1 = {'copy': {},
   421                 'diverge': bothdiverge,
   451              'fullcopy': {},
   422                }
   452              'incomplete': {},
       
   453              'diverge': bothdiverge,
       
   454              'incompletediverge': bothincompletediverge
       
   455             }
       
   456     both2 = {'copy': {},
       
   457              'fullcopy': {},
       
   458              'incomplete': {},
       
   459              'diverge': bothdiverge,
       
   460              'incompletediverge': bothincompletediverge
       
   461             }
   423     for f in bothnew:
   462     for f in bothnew:
   424         _checkcopies(c1, f, m1, m2, base, tca, limit, bothdata)
   463         _checkcopies(c1, f, m1, m2, base, tca, limit, both1)
   425         _checkcopies(c2, f, m2, m1, base, tca, limit, bothdata)
   464         _checkcopies(c2, f, m2, m1, base, tca, limit, both2)
       
   465     if dirtyc1:
       
   466         assert both2['incomplete'] == {}
       
   467         remainder = _combinecopies({}, both1['incomplete'], copy, bothdiverge,
       
   468                                    bothincompletediverge)
       
   469     else:
       
   470         assert both1['incomplete'] == {}
       
   471         remainder = _combinecopies({}, both2['incomplete'], copy, bothdiverge,
       
   472                                    bothincompletediverge)
       
   473     for f in remainder:
       
   474         assert f not in bothdiverge
       
   475         ic = remainder[f]
       
   476         if ic[0] in (m1 if dirtyc1 else m2):
       
   477             # backed-out rename on one side, but watch out for deleted files
       
   478             bothdiverge[f] = ic
   426     for of, fl in bothdiverge.items():
   479     for of, fl in bothdiverge.items():
   427         if len(fl) == 2 and fl[0] == fl[1]:
   480         if len(fl) == 2 and fl[0] == fl[1]:
   428             copy[fl[0]] = of # not actually divergent, just matching renames
   481             copy[fl[0]] = of # not actually divergent, just matching renames
   429 
   482 
   430     if fullcopy and repo.ui.debugflag:
   483     if fullcopy and repo.ui.debugflag: