hgext/absorb.py
changeset 40188 2c5316796f45
parent 40187 dcda50856843
child 40190 31dfa7dac4c9
equal deleted inserted replaced
40187:dcda50856843 40188:2c5316796f45
    19     add-noise = 1
    19     add-noise = 1
    20     # make `amend --correlated` a shortcut to the main command
    20     # make `amend --correlated` a shortcut to the main command
    21     amend-flag = correlated
    21     amend-flag = correlated
    22 
    22 
    23     [color]
    23     [color]
       
    24     absorb.description = yellow
    24     absorb.node = blue bold
    25     absorb.node = blue bold
    25     absorb.path = bold
    26     absorb.path = bold
    26 """
    27 """
    27 
    28 
    28 # TODO:
    29 # TODO:
    72 configitem('absorb', 'add-noise', default=True)
    73 configitem('absorb', 'add-noise', default=True)
    73 configitem('absorb', 'amend-flag', default=None)
    74 configitem('absorb', 'amend-flag', default=None)
    74 configitem('absorb', 'max-stack-size', default=50)
    75 configitem('absorb', 'max-stack-size', default=50)
    75 
    76 
    76 colortable = {
    77 colortable = {
       
    78     'absorb.description': 'yellow',
    77     'absorb.node': 'blue bold',
    79     'absorb.node': 'blue bold',
    78     'absorb.path': 'bold',
    80     'absorb.path': 'bold',
    79 }
    81 }
    80 
    82 
    81 defaultdict = collections.defaultdict
    83 defaultdict = collections.defaultdict
   295         # following fields will be filled later
   297         # following fields will be filled later
   296         self.chunkstats = [0, 0] # [adopted, total : int]
   298         self.chunkstats = [0, 0] # [adopted, total : int]
   297         self.targetlines = [] # [str]
   299         self.targetlines = [] # [str]
   298         self.fixups = [] # [(linelog rev, a1, a2, b1, b2)]
   300         self.fixups = [] # [(linelog rev, a1, a2, b1, b2)]
   299         self.finalcontents = [] # [str]
   301         self.finalcontents = [] # [str]
       
   302         self.ctxaffected = set()
   300 
   303 
   301     def diffwith(self, targetfctx, fm=None):
   304     def diffwith(self, targetfctx, fm=None):
   302         """calculate fixups needed by examining the differences between
   305         """calculate fixups needed by examining the differences between
   303         self.fctxs[-1] and targetfctx, chunk by chunk.
   306         self.fctxs[-1] and targetfctx, chunk by chunk.
   304 
   307 
   575             node = ''
   578             node = ''
   576             if idx:
   579             if idx:
   577                 ctx = self.fctxs[idx]
   580                 ctx = self.fctxs[idx]
   578                 fm.context(fctx=ctx)
   581                 fm.context(fctx=ctx)
   579                 node = ctx.hex()
   582                 node = ctx.hex()
       
   583                 self.ctxaffected.add(ctx.changectx())
   580             fm.write('node', '%-7.7s ', node, label='absorb.node')
   584             fm.write('node', '%-7.7s ', node, label='absorb.node')
   581             fm.write('diffchar ' + linetype, '%s%s\n', diffchar, line,
   585             fm.write('diffchar ' + linetype, '%s%s\n', diffchar, line,
   582                      label=linelabel)
   586                      label=linelabel)
   583             fm.data(path=self.path, linetype=linetype)
   587             fm.data(path=self.path, linetype=linetype)
   584 
   588 
   619         self.status = None # ctx.status output
   623         self.status = None # ctx.status output
   620         self.fctxmap = {} # {path: {ctx: fctx}}
   624         self.fctxmap = {} # {path: {ctx: fctx}}
   621         self.fixupmap = {} # {path: filefixupstate}
   625         self.fixupmap = {} # {path: filefixupstate}
   622         self.replacemap = {} # {oldnode: newnode or None}
   626         self.replacemap = {} # {oldnode: newnode or None}
   623         self.finalnode = None # head after all fixups
   627         self.finalnode = None # head after all fixups
       
   628         self.ctxaffected = set() # ctx that will be absorbed into
   624 
   629 
   625     def diffwith(self, targetctx, match=None, fm=None):
   630     def diffwith(self, targetctx, match=None, fm=None):
   626         """diff and prepare fixups. update self.fixupmap, self.paths"""
   631         """diff and prepare fixups. update self.fixupmap, self.paths"""
   627         # only care about modified files
   632         # only care about modified files
   628         self.status = self.stack[-1].status(targetctx, match)
   633         self.status = self.stack[-1].status(targetctx, match)
   658                 fm.write('path', '%s\n', path, label='absorb.path')
   663                 fm.write('path', '%s\n', path, label='absorb.path')
   659                 fm.data(linetype='path')
   664                 fm.data(linetype='path')
   660             fstate.diffwith(targetfctx, fm)
   665             fstate.diffwith(targetfctx, fm)
   661             self.fixupmap[path] = fstate
   666             self.fixupmap[path] = fstate
   662             self.paths.append(path)
   667             self.paths.append(path)
       
   668             self.ctxaffected.update(fstate.ctxaffected)
   663 
   669 
   664     def apply(self):
   670     def apply(self):
   665         """apply fixups to individual filefixupstates"""
   671         """apply fixups to individual filefixupstates"""
   666         for path, state in self.fixupmap.iteritems():
   672         for path, state in self.fixupmap.iteritems():
   667             if self.ui.debugflag:
   673             if self.ui.debugflag:
   948     fm = None
   954     fm = None
   949     if opts.get('print_changes'):
   955     if opts.get('print_changes'):
   950         fm = ui.formatter('absorb', opts)
   956         fm = ui.formatter('absorb', opts)
   951     state.diffwith(targetctx, matcher, fm)
   957     state.diffwith(targetctx, matcher, fm)
   952     if fm is not None:
   958     if fm is not None:
       
   959         fm.startitem()
       
   960         fm.write("count", "\n%d changesets affected\n", len(state.ctxaffected))
       
   961         fm.data(linetype='summary')
       
   962         for ctx in reversed(stack):
       
   963             if ctx not in state.ctxaffected:
       
   964                 continue
       
   965             fm.startitem()
       
   966             fm.context(ctx=ctx)
       
   967             fm.data(linetype='changeset')
       
   968             fm.write('node', '%-7.7s ', ctx.hex(), label='absorb.node')
       
   969             descfirstline = ctx.description().splitlines()[0]
       
   970             fm.write('descfirstline', '%s\n', descfirstline,
       
   971                      label='absorb.description')
   953         fm.end()
   972         fm.end()
   954     if not opts.get('dry_run'):
   973     if not opts.get('dry_run'):
   955         state.apply()
   974         state.apply()
   956         if state.commit():
   975         if state.commit():
   957             state.printchunkstats()
   976             state.printchunkstats()