hgext/evolve.py
changeset 1047 d830377bf186
parent 1046 296d48e1f55a
child 1052 ac47c2f774a8
equal deleted inserted replaced
1046:296d48e1f55a 1047:d830377bf186
  1149         ui.write('        mean length:        %9i\n' % mean)
  1149         ui.write('        mean length:        %9i\n' % mean)
  1150 
  1150 
  1151 @command('^evolve|stabilize|solve',
  1151 @command('^evolve|stabilize|solve',
  1152     [('n', 'dry-run', False,
  1152     [('n', 'dry-run', False,
  1153         'do not perform actions, just print what would be done'),
  1153         'do not perform actions, just print what would be done'),
       
  1154      ('', 'confirm', False,
       
  1155         'ask for confirmation before performing the action'),
  1154     ('A', 'any', False, 'also consider troubled changesets unrelated to current working directory'),
  1156     ('A', 'any', False, 'also consider troubled changesets unrelated to current working directory'),
  1155     ('a', 'all', False, 'evolve all troubled changesets in the repo '
  1157     ('a', 'all', False, 'evolve all troubled changesets in the repo '
  1156                         '(implies any)'),
  1158                         '(implies any)'),
  1157     ('c', 'continue', False, 'continue an interrupted evolution'),
  1159     ('c', 'continue', False, 'continue an interrupted evolution'),
  1158     ] + mergetoolopts,
  1160     ] + mergetoolopts,
  1184 
  1186 
  1185     contopt = opts['continue']
  1187     contopt = opts['continue']
  1186     anyopt = opts['any']
  1188     anyopt = opts['any']
  1187     allopt = opts['all']
  1189     allopt = opts['all']
  1188     dryrunopt = opts['dry_run']
  1190     dryrunopt = opts['dry_run']
       
  1191     confirmopt = opts['confirm']
  1189     ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'evolve')
  1192     ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'evolve')
  1190 
  1193 
  1191     if contopt:
  1194     if contopt:
  1192         if anyopt:
  1195         if anyopt:
  1193             raise util.Abort('cannot specify both "--any" and "--continue"')
  1196             raise util.Abort('cannot specify both "--any" and "--continue"')
  1254         wlock = lock = tr = None
  1257         wlock = lock = tr = None
  1255         try:
  1258         try:
  1256             wlock = repo.wlock()
  1259             wlock = repo.wlock()
  1257             lock = repo.lock()
  1260             lock = repo.lock()
  1258             tr = repo.transaction("evolve")
  1261             tr = repo.transaction("evolve")
  1259             result = _evolveany(ui, repo, tro, dryrunopt,
  1262             result = _evolveany(ui, repo, tro, dryrunopt, confirmopt,
  1260                                 progresscb=progresscb)
  1263                                 progresscb=progresscb)
  1261             tr.close()
  1264             tr.close()
  1262         finally:
  1265         finally:
  1263             lockmod.release(tr, lock, wlock)
  1266             lockmod.release(tr, lock, wlock)
  1264         progresscb()
  1267         progresscb()
  1270 
  1273 
  1271     if allopt:
  1274     if allopt:
  1272         ui.progress('evolve', None)
  1275         ui.progress('evolve', None)
  1273 
  1276 
  1274 
  1277 
  1275 def _evolveany(ui, repo, tro, dryrunopt, progresscb):
  1278 def _evolveany(ui, repo, tro, dryrunopt, confirmopt, progresscb):
  1276     repo = repo.unfiltered()
  1279     repo = repo.unfiltered()
  1277     tro = repo[tro.rev()]
  1280     tro = repo[tro.rev()]
  1278     cmdutil.bailifchanged(repo)
  1281     cmdutil.bailifchanged(repo)
  1279     troubles = tro.troubles()
  1282     troubles = tro.troubles()
  1280     if 'unstable' in troubles:
  1283     if 'unstable' in troubles:
  1281         return _solveunstable(ui, repo, tro, dryrunopt, progresscb)
  1284         return _solveunstable(ui, repo, tro, dryrunopt, confirmopt, progresscb)
  1282     elif 'bumped' in troubles:
  1285     elif 'bumped' in troubles:
  1283         return _solvebumped(ui, repo, tro, dryrunopt, progresscb)
  1286         return _solvebumped(ui, repo, tro, dryrunopt, confirmopt, progresscb)
  1284     elif 'divergent' in troubles:
  1287     elif 'divergent' in troubles:
  1285         repo = repo.unfiltered()
  1288         repo = repo.unfiltered()
  1286         tro = repo[tro.rev()]
  1289         tro = repo[tro.rev()]
  1287         return _solvedivergent(ui, repo, tro, dryrunopt, progresscb)
  1290         return _solvedivergent(ui, repo, tro, dryrunopt, confirmopt,
       
  1291                                progresscb)
  1288     else:
  1292     else:
  1289         assert False  # WHAT? unknown troubles
  1293         assert False  # WHAT? unknown troubles
  1290 
  1294 
  1291 def _counttroubled(ui, repo):
  1295 def _counttroubled(ui, repo):
  1292     """Count the amount of troubled changesets"""
  1296     """Count the amount of troubled changesets"""
  1335         for child in ctx.children():
  1339         for child in ctx.children():
  1336             if child.unstable():
  1340             if child.unstable():
  1337                 return child
  1341                 return child
  1338     return None
  1342     return None
  1339 
  1343 
  1340 def _solveunstable(ui, repo, orig, dryrun=False, progresscb=None):
  1344 def _solveunstable(ui, repo, orig, dryrun=False, confirm=False,
       
  1345                    progresscb=None):
  1341     """Stabilize a unstable changeset"""
  1346     """Stabilize a unstable changeset"""
  1342     obs = orig.parents()[0]
  1347     obs = orig.parents()[0]
  1343     if not obs.obsolete():
  1348     if not obs.obsolete():
  1344         print obs.rev(), orig.parents()
  1349         print obs.rev(), orig.parents()
  1345         print orig.rev()
  1350         print orig.rev()
  1360         raise util.Abort(_("does not handle split parents yet\n"))
  1365         raise util.Abort(_("does not handle split parents yet\n"))
  1361         return 2
  1366         return 2
  1362     target = targets[0]
  1367     target = targets[0]
  1363     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
  1368     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
  1364     target = repo[target]
  1369     target = repo[target]
  1365     if not ui.quiet:
  1370     if not ui.quiet or confirm:
  1366         repo.ui.write(_('move:'))
  1371         repo.ui.write(_('move:'))
  1367         displayer.show(orig)
  1372         displayer.show(orig)
  1368         repo.ui.write(_('atop:'))
  1373         repo.ui.write(_('atop:'))
  1369         displayer.show(target)
  1374         displayer.show(target)
       
  1375     if confirm and ui.prompt('perform evolve? [Ny]') != 'y':
       
  1376             raise util.Abort(_('evolve aborted by user'))
  1370     if progresscb: progresscb()
  1377     if progresscb: progresscb()
  1371     todo = 'hg rebase -r %s -d %s\n' % (orig, target)
  1378     todo = 'hg rebase -r %s -d %s\n' % (orig, target)
  1372     if dryrun:
  1379     if dryrun:
  1373         repo.ui.write(todo)
  1380         repo.ui.write(todo)
  1374     else:
  1381     else:
  1381             repo.ui.write_err(_('evolve failed!\n'))
  1388             repo.ui.write_err(_('evolve failed!\n'))
  1382             repo.ui.write_err(
  1389             repo.ui.write_err(
  1383                 _('fix conflict and run "hg evolve --continue"\n'))
  1390                 _('fix conflict and run "hg evolve --continue"\n'))
  1384             raise
  1391             raise
  1385 
  1392 
  1386 def _solvebumped(ui, repo, bumped, dryrun=False, progresscb=None):
  1393 def _solvebumped(ui, repo, bumped, dryrun=False, confirm=False,
       
  1394                  progresscb=None):
  1387     """Stabilize a bumped changeset"""
  1395     """Stabilize a bumped changeset"""
  1388     # For now we deny bumped merge
  1396     # For now we deny bumped merge
  1389     if len(bumped.parents()) > 1:
  1397     if len(bumped.parents()) > 1:
  1390         raise util.Abort('late comer stabilization is confused by bumped'
  1398         raise util.Abort('late comer stabilization is confused by bumped'
  1391                          ' %s being a merge' % bumped)
  1399                          ' %s being a merge' % bumped)
  1394     if len(prec.parents()) > 1:
  1402     if len(prec.parents()) > 1:
  1395         raise util.Abort('late comer evolution is confused by precursors'
  1403         raise util.Abort('late comer evolution is confused by precursors'
  1396                          ' %s being a merge' % prec)
  1404                          ' %s being a merge' % prec)
  1397 
  1405 
  1398     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
  1406     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
  1399     if not ui.quiet:
  1407     if not ui.quiet or confirm:
  1400         repo.ui.write(_('recreate:'))
  1408         repo.ui.write(_('recreate:'))
  1401         displayer.show(bumped)
  1409         displayer.show(bumped)
  1402         repo.ui.write(_('atop:'))
  1410         repo.ui.write(_('atop:'))
  1403         displayer.show(prec)
  1411         displayer.show(prec)
       
  1412     if confirm and ui.prompt('perform evolve? [Ny]') != 'y':
       
  1413         raise util.Abort(_('evolve aborted by user'))
  1404     if dryrun:
  1414     if dryrun:
  1405         todo = 'hg rebase --rev %s --dest %s;\n' % (bumped, prec.p1())
  1415         todo = 'hg rebase --rev %s --dest %s;\n' % (bumped, prec.p1())
  1406         repo.ui.write(todo)
  1416         repo.ui.write(todo)
  1407         repo.ui.write('hg update %s;\n' % prec)
  1417         repo.ui.write('hg update %s;\n' % prec)
  1408         repo.ui.write('hg revert --all --rev %s;\n' % bumped)
  1418         repo.ui.write('hg revert --all --rev %s;\n' % bumped)
  1477     finally:
  1487     finally:
  1478         tr.release()
  1488         tr.release()
  1479     # reroute the working copy parent to the new changeset
  1489     # reroute the working copy parent to the new changeset
  1480     repo.dirstate.setparents(newid, node.nullid)
  1490     repo.dirstate.setparents(newid, node.nullid)
  1481 
  1491 
  1482 def _solvedivergent(ui, repo, divergent, dryrun=False, progresscb=None):
  1492 def _solvedivergent(ui, repo, divergent, dryrun=False, confirm=False,
       
  1493                     progresscb=None):
  1483     base, others = divergentdata(divergent)
  1494     base, others = divergentdata(divergent)
  1484     if len(others) > 1:
  1495     if len(others) > 1:
  1485         othersstr = "[%s]" % (','.join([str(i) for i in others]))
  1496         othersstr = "[%s]" % (','.join([str(i) for i in others]))
  1486         hint = ("changeset %d is divergent with a changeset that got splitted "
  1497         hint = ("changeset %d is divergent with a changeset that got splitted "
  1487                 "| into multiple ones:\n[%s]\n"
  1498                 "| into multiple ones:\n[%s]\n"
  1514                          "| - either: hg rebase -dest 'p1(%(d)s)' -r %(o)s"
  1525                          "| - either: hg rebase -dest 'p1(%(d)s)' -r %(o)s"
  1515                          "| - or:     hg rebase -dest 'p1(%(d)s)' -r %(o)s"
  1526                          "| - or:     hg rebase -dest 'p1(%(d)s)' -r %(o)s"
  1516                               % {'d': divergent, 'o': other})
  1527                               % {'d': divergent, 'o': other})
  1517 
  1528 
  1518     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
  1529     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
  1519     if not ui.quiet:
  1530     if not ui.quiet or confirm:
  1520         ui.write(_('merge:'))
  1531         ui.write(_('merge:'))
  1521         displayer.show(divergent)
  1532         displayer.show(divergent)
  1522         ui.write(_('with: '))
  1533         ui.write(_('with: '))
  1523         displayer.show(other)
  1534         displayer.show(other)
  1524         ui.write(_('base: '))
  1535         ui.write(_('base: '))
  1525         displayer.show(base)
  1536         displayer.show(base)
       
  1537     if confirm and ui.prompt('perform evolve? [Ny]') != 'y':
       
  1538         raise util.Abort(_('evolve aborted by user'))
  1526     if dryrun:
  1539     if dryrun:
  1527         ui.write('hg update -c %s &&\n' % divergent)
  1540         ui.write('hg update -c %s &&\n' % divergent)
  1528         ui.write('hg merge %s &&\n' % other)
  1541         ui.write('hg merge %s &&\n' % other)
  1529         ui.write('hg commit -m "auto merge resolving conflict between '
  1542         ui.write('hg commit -m "auto merge resolving conflict between '
  1530                  '%s and %s"&&\n' % (divergent, other))
  1543                  '%s and %s"&&\n' % (divergent, other))