comparison mercurial/merge.py @ 45488:c4f14db3da1d

merge: move initial handling of mergeactions near to later one We build `mergeactions` in the beginning and use it in end. Let's build it just before where it will be used. Helps making code much easier to understand. Differential Revision: https://phab.mercurial-scm.org/D8983
author Pulkit Goyal <7895pulkit@gmail.com>
date Thu, 03 Sep 2020 13:25:29 +0530
parents 6e474eec4be6
children 2c10876bb320
comparison
equal deleted inserted replaced
45487:78f0bb37f52d 45488:c4f14db3da1d
1405 for f, op in pycompat.iteritems(mresult.commitinfo): 1405 for f, op in pycompat.iteritems(mresult.commitinfo):
1406 # the other side of filenode was choosen while merging, store this in 1406 # the other side of filenode was choosen while merging, store this in
1407 # mergestate so that it can be reused on commit 1407 # mergestate so that it can be reused on commit
1408 ms.addcommitinfo(f, op) 1408 ms.addcommitinfo(f, op)
1409 1409
1410 numupdates = mresult.len() - mresult.len(mergeresult.NO_OP_ACTIONS)
1411 progress = repo.ui.makeprogress(
1412 _(b'updating'), unit=_(b'files'), total=numupdates
1413 )
1414
1415 if b'.hgsubstate' in mresult._actionmapping[mergestatemod.ACTION_REMOVE]:
1416 subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1417
1418 # record path conflicts
1419 for f, args, msg in mresult.getactions(
1420 [mergestatemod.ACTION_PATH_CONFLICT], sort=True
1421 ):
1422 f1, fo = args
1423 s = repo.ui.status
1424 s(
1425 _(
1426 b"%s: path conflict - a file or link has the same name as a "
1427 b"directory\n"
1428 )
1429 % f
1430 )
1431 if fo == b'l':
1432 s(_(b"the local file has been renamed to %s\n") % f1)
1433 else:
1434 s(_(b"the remote file has been renamed to %s\n") % f1)
1435 s(_(b"resolve manually then use 'hg resolve --mark %s'\n") % f)
1436 ms.addpathconflict(f, f1, fo)
1437 progress.increment(item=f)
1438
1439 # When merging in-memory, we can't support worker processes, so set the
1440 # per-item cost at 0 in that case.
1441 cost = 0 if wctx.isinmemory() else 0.001
1442
1443 # remove in parallel (must come before resolving path conflicts and getting)
1444 prog = worker.worker(
1445 repo.ui,
1446 cost,
1447 batchremove,
1448 (repo, wctx),
1449 list(mresult.getactions([mergestatemod.ACTION_REMOVE], sort=True)),
1450 )
1451 for i, item in prog:
1452 progress.increment(step=i, item=item)
1453 removed = mresult.len((mergestatemod.ACTION_REMOVE,))
1454
1455 # resolve path conflicts (must come before getting)
1456 for f, args, msg in mresult.getactions(
1457 [mergestatemod.ACTION_PATH_CONFLICT_RESOLVE], sort=True
1458 ):
1459 repo.ui.debug(b" %s: %s -> pr\n" % (f, msg))
1460 (f0, origf0) = args
1461 if wctx[f0].lexists():
1462 repo.ui.note(_(b"moving %s to %s\n") % (f0, f))
1463 wctx[f].audit()
1464 wctx[f].write(wctx.filectx(f0).data(), wctx.filectx(f0).flags())
1465 wctx[f0].remove()
1466 progress.increment(item=f)
1467
1468 # get in parallel.
1469 threadsafe = repo.ui.configbool(
1470 b'experimental', b'worker.wdir-get-thread-safe'
1471 )
1472 prog = worker.worker(
1473 repo.ui,
1474 cost,
1475 batchget,
1476 (repo, mctx, wctx, wantfiledata),
1477 list(mresult.getactions([mergestatemod.ACTION_GET], sort=True)),
1478 threadsafe=threadsafe,
1479 hasretval=True,
1480 )
1481 getfiledata = {}
1482 for final, res in prog:
1483 if final:
1484 getfiledata = res
1485 else:
1486 i, item = res
1487 progress.increment(step=i, item=item)
1488
1489 if b'.hgsubstate' in mresult._actionmapping[mergestatemod.ACTION_GET]:
1490 subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1491
1492 # forget (manifest only, just log it) (must come first)
1493 for f, args, msg in mresult.getactions(
1494 (mergestatemod.ACTION_FORGET,), sort=True
1495 ):
1496 repo.ui.debug(b" %s: %s -> f\n" % (f, msg))
1497 progress.increment(item=f)
1498
1499 # re-add (manifest only, just log it)
1500 for f, args, msg in mresult.getactions(
1501 (mergestatemod.ACTION_ADD,), sort=True
1502 ):
1503 repo.ui.debug(b" %s: %s -> a\n" % (f, msg))
1504 progress.increment(item=f)
1505
1506 # re-add/mark as modified (manifest only, just log it)
1507 for f, args, msg in mresult.getactions(
1508 (mergestatemod.ACTION_ADD_MODIFIED,), sort=True
1509 ):
1510 repo.ui.debug(b" %s: %s -> am\n" % (f, msg))
1511 progress.increment(item=f)
1512
1513 # keep (noop, just log it)
1514 for f, args, msg in mresult.getactions(
1515 (mergestatemod.ACTION_KEEP,), sort=True
1516 ):
1517 repo.ui.debug(b" %s: %s -> k\n" % (f, msg))
1518 # no progress
1519 for f, args, msg in mresult.getactions(
1520 (mergestatemod.ACTION_KEEP_ABSENT,), sort=True
1521 ):
1522 repo.ui.debug(b" %s: %s -> ka\n" % (f, msg))
1523 # no progress
1524
1525 # directory rename, move local
1526 for f, args, msg in mresult.getactions(
1527 (mergestatemod.ACTION_DIR_RENAME_MOVE_LOCAL,), sort=True
1528 ):
1529 repo.ui.debug(b" %s: %s -> dm\n" % (f, msg))
1530 progress.increment(item=f)
1531 f0, flags = args
1532 repo.ui.note(_(b"moving %s to %s\n") % (f0, f))
1533 wctx[f].audit()
1534 wctx[f].write(wctx.filectx(f0).data(), flags)
1535 wctx[f0].remove()
1536
1537 # local directory rename, get
1538 for f, args, msg in mresult.getactions(
1539 (mergestatemod.ACTION_LOCAL_DIR_RENAME_GET,), sort=True
1540 ):
1541 repo.ui.debug(b" %s: %s -> dg\n" % (f, msg))
1542 progress.increment(item=f)
1543 f0, flags = args
1544 repo.ui.note(_(b"getting %s to %s\n") % (f0, f))
1545 wctx[f].write(mctx.filectx(f0).data(), flags)
1546
1547 # exec
1548 for f, args, msg in mresult.getactions(
1549 (mergestatemod.ACTION_EXEC,), sort=True
1550 ):
1551 repo.ui.debug(b" %s: %s -> e\n" % (f, msg))
1552 progress.increment(item=f)
1553 (flags,) = args
1554 wctx[f].audit()
1555 wctx[f].setflags(b'l' in flags, b'x' in flags)
1556
1410 moves = [] 1557 moves = []
1411 1558
1412 # 'cd' and 'dc' actions are treated like other merge conflicts 1559 # 'cd' and 'dc' actions are treated like other merge conflicts
1413 mergeactions = list( 1560 mergeactions = list(
1414 mresult.getactions( 1561 mresult.getactions(
1447 for f in moves: 1594 for f in moves:
1448 if wctx[f].lexists(): 1595 if wctx[f].lexists():
1449 repo.ui.debug(b"removing %s\n" % f) 1596 repo.ui.debug(b"removing %s\n" % f)
1450 wctx[f].audit() 1597 wctx[f].audit()
1451 wctx[f].remove() 1598 wctx[f].remove()
1452
1453 numupdates = mresult.len() - mresult.len(mergeresult.NO_OP_ACTIONS)
1454 progress = repo.ui.makeprogress(
1455 _(b'updating'), unit=_(b'files'), total=numupdates
1456 )
1457
1458 if b'.hgsubstate' in mresult._actionmapping[mergestatemod.ACTION_REMOVE]:
1459 subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1460
1461 # record path conflicts
1462 for f, args, msg in mresult.getactions(
1463 [mergestatemod.ACTION_PATH_CONFLICT], sort=True
1464 ):
1465 f1, fo = args
1466 s = repo.ui.status
1467 s(
1468 _(
1469 b"%s: path conflict - a file or link has the same name as a "
1470 b"directory\n"
1471 )
1472 % f
1473 )
1474 if fo == b'l':
1475 s(_(b"the local file has been renamed to %s\n") % f1)
1476 else:
1477 s(_(b"the remote file has been renamed to %s\n") % f1)
1478 s(_(b"resolve manually then use 'hg resolve --mark %s'\n") % f)
1479 ms.addpathconflict(f, f1, fo)
1480 progress.increment(item=f)
1481
1482 # When merging in-memory, we can't support worker processes, so set the
1483 # per-item cost at 0 in that case.
1484 cost = 0 if wctx.isinmemory() else 0.001
1485
1486 # remove in parallel (must come before resolving path conflicts and getting)
1487 prog = worker.worker(
1488 repo.ui,
1489 cost,
1490 batchremove,
1491 (repo, wctx),
1492 list(mresult.getactions([mergestatemod.ACTION_REMOVE], sort=True)),
1493 )
1494 for i, item in prog:
1495 progress.increment(step=i, item=item)
1496 removed = mresult.len((mergestatemod.ACTION_REMOVE,))
1497
1498 # resolve path conflicts (must come before getting)
1499 for f, args, msg in mresult.getactions(
1500 [mergestatemod.ACTION_PATH_CONFLICT_RESOLVE], sort=True
1501 ):
1502 repo.ui.debug(b" %s: %s -> pr\n" % (f, msg))
1503 (f0, origf0) = args
1504 if wctx[f0].lexists():
1505 repo.ui.note(_(b"moving %s to %s\n") % (f0, f))
1506 wctx[f].audit()
1507 wctx[f].write(wctx.filectx(f0).data(), wctx.filectx(f0).flags())
1508 wctx[f0].remove()
1509 progress.increment(item=f)
1510
1511 # get in parallel.
1512 threadsafe = repo.ui.configbool(
1513 b'experimental', b'worker.wdir-get-thread-safe'
1514 )
1515 prog = worker.worker(
1516 repo.ui,
1517 cost,
1518 batchget,
1519 (repo, mctx, wctx, wantfiledata),
1520 list(mresult.getactions([mergestatemod.ACTION_GET], sort=True)),
1521 threadsafe=threadsafe,
1522 hasretval=True,
1523 )
1524 getfiledata = {}
1525 for final, res in prog:
1526 if final:
1527 getfiledata = res
1528 else:
1529 i, item = res
1530 progress.increment(step=i, item=item)
1531
1532 if b'.hgsubstate' in mresult._actionmapping[mergestatemod.ACTION_GET]:
1533 subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1534
1535 # forget (manifest only, just log it) (must come first)
1536 for f, args, msg in mresult.getactions(
1537 (mergestatemod.ACTION_FORGET,), sort=True
1538 ):
1539 repo.ui.debug(b" %s: %s -> f\n" % (f, msg))
1540 progress.increment(item=f)
1541
1542 # re-add (manifest only, just log it)
1543 for f, args, msg in mresult.getactions(
1544 (mergestatemod.ACTION_ADD,), sort=True
1545 ):
1546 repo.ui.debug(b" %s: %s -> a\n" % (f, msg))
1547 progress.increment(item=f)
1548
1549 # re-add/mark as modified (manifest only, just log it)
1550 for f, args, msg in mresult.getactions(
1551 (mergestatemod.ACTION_ADD_MODIFIED,), sort=True
1552 ):
1553 repo.ui.debug(b" %s: %s -> am\n" % (f, msg))
1554 progress.increment(item=f)
1555
1556 # keep (noop, just log it)
1557 for f, args, msg in mresult.getactions(
1558 (mergestatemod.ACTION_KEEP,), sort=True
1559 ):
1560 repo.ui.debug(b" %s: %s -> k\n" % (f, msg))
1561 # no progress
1562 for f, args, msg in mresult.getactions(
1563 (mergestatemod.ACTION_KEEP_ABSENT,), sort=True
1564 ):
1565 repo.ui.debug(b" %s: %s -> ka\n" % (f, msg))
1566 # no progress
1567
1568 # directory rename, move local
1569 for f, args, msg in mresult.getactions(
1570 (mergestatemod.ACTION_DIR_RENAME_MOVE_LOCAL,), sort=True
1571 ):
1572 repo.ui.debug(b" %s: %s -> dm\n" % (f, msg))
1573 progress.increment(item=f)
1574 f0, flags = args
1575 repo.ui.note(_(b"moving %s to %s\n") % (f0, f))
1576 wctx[f].audit()
1577 wctx[f].write(wctx.filectx(f0).data(), flags)
1578 wctx[f0].remove()
1579
1580 # local directory rename, get
1581 for f, args, msg in mresult.getactions(
1582 (mergestatemod.ACTION_LOCAL_DIR_RENAME_GET,), sort=True
1583 ):
1584 repo.ui.debug(b" %s: %s -> dg\n" % (f, msg))
1585 progress.increment(item=f)
1586 f0, flags = args
1587 repo.ui.note(_(b"getting %s to %s\n") % (f0, f))
1588 wctx[f].write(mctx.filectx(f0).data(), flags)
1589
1590 # exec
1591 for f, args, msg in mresult.getactions(
1592 (mergestatemod.ACTION_EXEC,), sort=True
1593 ):
1594 repo.ui.debug(b" %s: %s -> e\n" % (f, msg))
1595 progress.increment(item=f)
1596 (flags,) = args
1597 wctx[f].audit()
1598 wctx[f].setflags(b'l' in flags, b'x' in flags)
1599 1599
1600 # these actions updates the file 1600 # these actions updates the file
1601 updated = mresult.len( 1601 updated = mresult.len(
1602 ( 1602 (
1603 mergestatemod.ACTION_GET, 1603 mergestatemod.ACTION_GET,