hgext/fix.py
changeset 45074 54009f8c3e25
parent 44915 b7808443ed6a
child 45075 797ef6f8295e
equal deleted inserted replaced
45073:a56ba57c837d 45074:54009f8c3e25
   266         revstofix = getrevstofix(ui, repo, opts)
   266         revstofix = getrevstofix(ui, repo, opts)
   267         basectxs = getbasectxs(repo, opts, revstofix)
   267         basectxs = getbasectxs(repo, opts, revstofix)
   268         workqueue, numitems = getworkqueue(
   268         workqueue, numitems = getworkqueue(
   269             ui, repo, pats, opts, revstofix, basectxs
   269             ui, repo, pats, opts, revstofix, basectxs
   270         )
   270         )
       
   271         basepaths = getbasepaths(repo, opts, workqueue, basectxs)
   271         fixers = getfixers(ui)
   272         fixers = getfixers(ui)
   272 
   273 
   273         # There are no data dependencies between the workers fixing each file
   274         # There are no data dependencies between the workers fixing each file
   274         # revision, so we can use all available parallelism.
   275         # revision, so we can use all available parallelism.
   275         def getfixes(items):
   276         def getfixes(items):
   276             for rev, path in items:
   277             for rev, path in items:
   277                 ctx = repo[rev]
   278                 ctx = repo[rev]
   278                 olddata = ctx[path].data()
   279                 olddata = ctx[path].data()
   279                 metadata, newdata = fixfile(
   280                 metadata, newdata = fixfile(
   280                     ui, repo, opts, fixers, ctx, path, basectxs[rev]
   281                     ui, repo, opts, fixers, ctx, path, basepaths, basectxs[rev]
   281                 )
   282                 )
   282                 # Don't waste memory/time passing unchanged content back, but
   283                 # Don't waste memory/time passing unchanged content back, but
   283                 # produce one result per item either way.
   284                 # produce one result per item either way.
   284                 yield (
   285                 yield (
   285                     rev,
   286                     rev,
   471             )
   472             )
   472         )
   473         )
   473     return files
   474     return files
   474 
   475 
   475 
   476 
   476 def lineranges(opts, path, basectxs, fixctx, content2):
   477 def lineranges(opts, path, basepaths, basectxs, fixctx, content2):
   477     """Returns the set of line ranges that should be fixed in a file
   478     """Returns the set of line ranges that should be fixed in a file
   478 
   479 
   479     Of the form [(10, 20), (30, 40)].
   480     Of the form [(10, 20), (30, 40)].
   480 
   481 
   481     This depends on the given base contexts; we must consider lines that have
   482     This depends on the given base contexts; we must consider lines that have
   490         # idea of how many lines are in the file, instead of reimplementing it.
   491         # idea of how many lines are in the file, instead of reimplementing it.
   491         return difflineranges(b'', content2)
   492         return difflineranges(b'', content2)
   492 
   493 
   493     rangeslist = []
   494     rangeslist = []
   494     for basectx in basectxs:
   495     for basectx in basectxs:
   495         basepath = copies.pathcopies(basectx, fixctx).get(path, path)
   496         basepath = basepaths.get((basectx.rev(), fixctx.rev(), path), path)
       
   497 
   496         if basepath in basectx:
   498         if basepath in basectx:
   497             content1 = basectx[basepath].data()
   499             content1 = basectx[basepath].data()
   498         else:
   500         else:
   499             content1 = b''
   501             content1 = b''
   500         rangeslist.extend(difflineranges(content1, content2))
   502         rangeslist.extend(difflineranges(content1, content2))
   501     return unionranges(rangeslist)
   503     return unionranges(rangeslist)
       
   504 
       
   505 
       
   506 def getbasepaths(repo, opts, workqueue, basectxs):
       
   507     if opts.get(b'whole'):
       
   508         # Base paths will never be fetched for line range determination.
       
   509         return {}
       
   510 
       
   511     basepaths = {}
       
   512     for rev, path in workqueue:
       
   513         fixctx = repo[rev]
       
   514         for basectx in basectxs[rev]:
       
   515             basepath = copies.pathcopies(basectx, fixctx).get(path, path)
       
   516             if basepath in basectx:
       
   517                 basepaths[(basectx.rev(), fixctx.rev(), path)] = basepath
       
   518     return basepaths
   502 
   519 
   503 
   520 
   504 def unionranges(rangeslist):
   521 def unionranges(rangeslist):
   505     """Return the union of some closed intervals
   522     """Return the union of some closed intervals
   506 
   523 
   611             else:
   628             else:
   612                 basectxs[rev].add(pctx)
   629                 basectxs[rev].add(pctx)
   613     return basectxs
   630     return basectxs
   614 
   631 
   615 
   632 
   616 def fixfile(ui, repo, opts, fixers, fixctx, path, basectxs):
   633 def fixfile(ui, repo, opts, fixers, fixctx, path, basepaths, basectxs):
   617     """Run any configured fixers that should affect the file in this context
   634     """Run any configured fixers that should affect the file in this context
   618 
   635 
   619     Returns the file content that results from applying the fixers in some order
   636     Returns the file content that results from applying the fixers in some order
   620     starting with the file's content in the fixctx. Fixers that support line
   637     starting with the file's content in the fixctx. Fixers that support line
   621     ranges will affect lines that have changed relative to any of the basectxs
   638     ranges will affect lines that have changed relative to any of the basectxs
   627     """
   644     """
   628     metadata = {}
   645     metadata = {}
   629     newdata = fixctx[path].data()
   646     newdata = fixctx[path].data()
   630     for fixername, fixer in pycompat.iteritems(fixers):
   647     for fixername, fixer in pycompat.iteritems(fixers):
   631         if fixer.affects(opts, fixctx, path):
   648         if fixer.affects(opts, fixctx, path):
   632             ranges = lineranges(opts, path, basectxs, fixctx, newdata)
   649             ranges = lineranges(
       
   650                 opts, path, basepaths, basectxs, fixctx, newdata
       
   651             )
   633             command = fixer.command(ui, path, ranges)
   652             command = fixer.command(ui, path, ranges)
   634             if command is None:
   653             if command is None:
   635                 continue
   654                 continue
   636             ui.debug(b'subprocess: %s\n' % (command,))
   655             ui.debug(b'subprocess: %s\n' % (command,))
   637             proc = subprocess.Popen(
   656             proc = subprocess.Popen(