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)) |