mercurial/merge.py
changeset 45337 5ce63ee1fe3d
parent 45336 27c6518b7287
child 45338 72b8c082676b
equal deleted inserted replaced
45336:27c6518b7287 45337:5ce63ee1fe3d
  1350     (updated, merged, removed, unresolved) that describes how many
  1350     (updated, merged, removed, unresolved) that describes how many
  1351     files were affected by the update, and filedata is as described in
  1351     files were affected by the update, and filedata is as described in
  1352     batchget.
  1352     batchget.
  1353     """
  1353     """
  1354 
  1354 
  1355     actions = mresult.actionsdict
       
  1356     _prefetchfiles(repo, mctx, mresult)
  1355     _prefetchfiles(repo, mctx, mresult)
  1357 
  1356 
  1358     updated, merged, removed = 0, 0, 0
  1357     updated, merged, removed = 0, 0, 0
  1359     ms = mergestatemod.mergestate.clean(
  1358     ms = mergestatemod.mergestate.clean(
  1360         repo, wctx.p1().node(), mctx.node(), labels
  1359         repo, wctx.p1().node(), mctx.node(), labels
  1368         # mergestate so that it can be reused on commit
  1367         # mergestate so that it can be reused on commit
  1369         if op == b'other':
  1368         if op == b'other':
  1370             ms.addmergedother(f)
  1369             ms.addmergedother(f)
  1371 
  1370 
  1372     moves = []
  1371     moves = []
  1373     for m, l in actions.items():
       
  1374         l.sort()
       
  1375 
  1372 
  1376     # 'cd' and 'dc' actions are treated like other merge conflicts
  1373     # 'cd' and 'dc' actions are treated like other merge conflicts
  1377     mergeactions = sorted(actions[mergestatemod.ACTION_CHANGED_DELETED])
  1374     mergeactions = mresult.getactions(
  1378     mergeactions.extend(sorted(actions[mergestatemod.ACTION_DELETED_CHANGED]))
  1375         [
  1379     mergeactions.extend(actions[mergestatemod.ACTION_MERGE])
  1376             mergestatemod.ACTION_CHANGED_DELETED,
       
  1377             mergestatemod.ACTION_DELETED_CHANGED,
       
  1378             mergestatemod.ACTION_MERGE,
       
  1379         ],
       
  1380         sort=True,
       
  1381     )
  1380     for f, args, msg in mergeactions:
  1382     for f, args, msg in mergeactions:
  1381         f1, f2, fa, move, anc = args
  1383         f1, f2, fa, move, anc = args
  1382         if f == b'.hgsubstate':  # merged internally
  1384         if f == b'.hgsubstate':  # merged internally
  1383             continue
  1385             continue
  1384         if f1 is None:
  1386         if f1 is None:
  1405         if wctx[f].lexists():
  1407         if wctx[f].lexists():
  1406             repo.ui.debug(b"removing %s\n" % f)
  1408             repo.ui.debug(b"removing %s\n" % f)
  1407             wctx[f].audit()
  1409             wctx[f].audit()
  1408             wctx[f].remove()
  1410             wctx[f].remove()
  1409 
  1411 
  1410     numupdates = sum(
  1412     numupdates = len(mresult.actions) - len(
  1411         len(l) for m, l in actions.items() if m != mergestatemod.ACTION_KEEP
  1413         mresult._actionmapping[mergestatemod.ACTION_KEEP]
  1412     )
  1414     )
  1413     progress = repo.ui.makeprogress(
  1415     progress = repo.ui.makeprogress(
  1414         _(b'updating'), unit=_(b'files'), total=numupdates
  1416         _(b'updating'), unit=_(b'files'), total=numupdates
  1415     )
  1417     )
  1416 
  1418 
  1417     if [
  1419     if b'.hgsubstate' in mresult._actionmapping[mergestatemod.ACTION_REMOVE]:
  1418         a
       
  1419         for a in actions[mergestatemod.ACTION_REMOVE]
       
  1420         if a[0] == b'.hgsubstate'
       
  1421     ]:
       
  1422         subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
  1420         subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
  1423 
  1421 
  1424     # record path conflicts
  1422     # record path conflicts
  1425     for f, args, msg in actions[mergestatemod.ACTION_PATH_CONFLICT]:
  1423     for f, args, msg in mresult.getactions(
       
  1424         [mergestatemod.ACTION_PATH_CONFLICT], sort=True
       
  1425     ):
  1426         f1, fo = args
  1426         f1, fo = args
  1427         s = repo.ui.status
  1427         s = repo.ui.status
  1428         s(
  1428         s(
  1429             _(
  1429             _(
  1430                 b"%s: path conflict - a file or link has the same name as a "
  1430                 b"%s: path conflict - a file or link has the same name as a "
  1448     prog = worker.worker(
  1448     prog = worker.worker(
  1449         repo.ui,
  1449         repo.ui,
  1450         cost,
  1450         cost,
  1451         batchremove,
  1451         batchremove,
  1452         (repo, wctx),
  1452         (repo, wctx),
  1453         actions[mergestatemod.ACTION_REMOVE],
  1453         mresult.getactions([mergestatemod.ACTION_REMOVE], sort=True),
  1454     )
  1454     )
  1455     for i, item in prog:
  1455     for i, item in prog:
  1456         progress.increment(step=i, item=item)
  1456         progress.increment(step=i, item=item)
  1457     removed = len(actions[mergestatemod.ACTION_REMOVE])
  1457     removed = len(mresult._actionmapping[mergestatemod.ACTION_REMOVE])
  1458 
  1458 
  1459     # resolve path conflicts (must come before getting)
  1459     # resolve path conflicts (must come before getting)
  1460     for f, args, msg in actions[mergestatemod.ACTION_PATH_CONFLICT_RESOLVE]:
  1460     for f, args, msg in mresult.getactions(
       
  1461         [mergestatemod.ACTION_PATH_CONFLICT_RESOLVE], sort=True
       
  1462     ):
  1461         repo.ui.debug(b" %s: %s -> pr\n" % (f, msg))
  1463         repo.ui.debug(b" %s: %s -> pr\n" % (f, msg))
  1462         (f0, origf0) = args
  1464         (f0, origf0) = args
  1463         if wctx[f0].lexists():
  1465         if wctx[f0].lexists():
  1464             repo.ui.note(_(b"moving %s to %s\n") % (f0, f))
  1466             repo.ui.note(_(b"moving %s to %s\n") % (f0, f))
  1465             wctx[f].audit()
  1467             wctx[f].audit()
  1474     prog = worker.worker(
  1476     prog = worker.worker(
  1475         repo.ui,
  1477         repo.ui,
  1476         cost,
  1478         cost,
  1477         batchget,
  1479         batchget,
  1478         (repo, mctx, wctx, wantfiledata),
  1480         (repo, mctx, wctx, wantfiledata),
  1479         actions[mergestatemod.ACTION_GET],
  1481         mresult.getactions([mergestatemod.ACTION_GET], sort=True),
  1480         threadsafe=threadsafe,
  1482         threadsafe=threadsafe,
  1481         hasretval=True,
  1483         hasretval=True,
  1482     )
  1484     )
  1483     getfiledata = {}
  1485     getfiledata = {}
  1484     for final, res in prog:
  1486     for final, res in prog:
  1485         if final:
  1487         if final:
  1486             getfiledata = res
  1488             getfiledata = res
  1487         else:
  1489         else:
  1488             i, item = res
  1490             i, item = res
  1489             progress.increment(step=i, item=item)
  1491             progress.increment(step=i, item=item)
  1490     updated = len(actions[mergestatemod.ACTION_GET])
  1492     updated = len(mresult._actionmapping[mergestatemod.ACTION_GET])
  1491 
  1493 
  1492     if [a for a in actions[mergestatemod.ACTION_GET] if a[0] == b'.hgsubstate']:
  1494     if b'.hgsubstate' in mresult._actionmapping[mergestatemod.ACTION_GET]:
  1493         subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
  1495         subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
  1494 
  1496 
  1495     # forget (manifest only, just log it) (must come first)
  1497     # forget (manifest only, just log it) (must come first)
  1496     for f, args, msg in actions[mergestatemod.ACTION_FORGET]:
  1498     for f, args, msg in mresult.getactions(
       
  1499         (mergestatemod.ACTION_FORGET,), sort=True
       
  1500     ):
  1497         repo.ui.debug(b" %s: %s -> f\n" % (f, msg))
  1501         repo.ui.debug(b" %s: %s -> f\n" % (f, msg))
  1498         progress.increment(item=f)
  1502         progress.increment(item=f)
  1499 
  1503 
  1500     # re-add (manifest only, just log it)
  1504     # re-add (manifest only, just log it)
  1501     for f, args, msg in actions[mergestatemod.ACTION_ADD]:
  1505     for f, args, msg in mresult.getactions(
       
  1506         (mergestatemod.ACTION_ADD,), sort=True
       
  1507     ):
  1502         repo.ui.debug(b" %s: %s -> a\n" % (f, msg))
  1508         repo.ui.debug(b" %s: %s -> a\n" % (f, msg))
  1503         progress.increment(item=f)
  1509         progress.increment(item=f)
  1504 
  1510 
  1505     # re-add/mark as modified (manifest only, just log it)
  1511     # re-add/mark as modified (manifest only, just log it)
  1506     for f, args, msg in actions[mergestatemod.ACTION_ADD_MODIFIED]:
  1512     for f, args, msg in mresult.getactions(
       
  1513         (mergestatemod.ACTION_ADD_MODIFIED,), sort=True
       
  1514     ):
  1507         repo.ui.debug(b" %s: %s -> am\n" % (f, msg))
  1515         repo.ui.debug(b" %s: %s -> am\n" % (f, msg))
  1508         progress.increment(item=f)
  1516         progress.increment(item=f)
  1509 
  1517 
  1510     # keep (noop, just log it)
  1518     # keep (noop, just log it)
  1511     for f, args, msg in actions[mergestatemod.ACTION_KEEP]:
  1519     for f, args, msg in mresult.getactions(
       
  1520         (mergestatemod.ACTION_KEEP,), sort=True
       
  1521     ):
  1512         repo.ui.debug(b" %s: %s -> k\n" % (f, msg))
  1522         repo.ui.debug(b" %s: %s -> k\n" % (f, msg))
  1513         # no progress
  1523         # no progress
  1514 
  1524 
  1515     # directory rename, move local
  1525     # directory rename, move local
  1516     for f, args, msg in actions[mergestatemod.ACTION_DIR_RENAME_MOVE_LOCAL]:
  1526     for f, args, msg in mresult.getactions(
       
  1527         (mergestatemod.ACTION_DIR_RENAME_MOVE_LOCAL,), sort=True
       
  1528     ):
  1517         repo.ui.debug(b" %s: %s -> dm\n" % (f, msg))
  1529         repo.ui.debug(b" %s: %s -> dm\n" % (f, msg))
  1518         progress.increment(item=f)
  1530         progress.increment(item=f)
  1519         f0, flags = args
  1531         f0, flags = args
  1520         repo.ui.note(_(b"moving %s to %s\n") % (f0, f))
  1532         repo.ui.note(_(b"moving %s to %s\n") % (f0, f))
  1521         wctx[f].audit()
  1533         wctx[f].audit()
  1522         wctx[f].write(wctx.filectx(f0).data(), flags)
  1534         wctx[f].write(wctx.filectx(f0).data(), flags)
  1523         wctx[f0].remove()
  1535         wctx[f0].remove()
  1524         updated += 1
  1536         updated += 1
  1525 
  1537 
  1526     # local directory rename, get
  1538     # local directory rename, get
  1527     for f, args, msg in actions[mergestatemod.ACTION_LOCAL_DIR_RENAME_GET]:
  1539     for f, args, msg in mresult.getactions(
       
  1540         (mergestatemod.ACTION_LOCAL_DIR_RENAME_GET,), sort=True
       
  1541     ):
  1528         repo.ui.debug(b" %s: %s -> dg\n" % (f, msg))
  1542         repo.ui.debug(b" %s: %s -> dg\n" % (f, msg))
  1529         progress.increment(item=f)
  1543         progress.increment(item=f)
  1530         f0, flags = args
  1544         f0, flags = args
  1531         repo.ui.note(_(b"getting %s to %s\n") % (f0, f))
  1545         repo.ui.note(_(b"getting %s to %s\n") % (f0, f))
  1532         wctx[f].write(mctx.filectx(f0).data(), flags)
  1546         wctx[f].write(mctx.filectx(f0).data(), flags)
  1533         updated += 1
  1547         updated += 1
  1534 
  1548 
  1535     # exec
  1549     # exec
  1536     for f, args, msg in actions[mergestatemod.ACTION_EXEC]:
  1550     for f, args, msg in mresult.getactions(
       
  1551         (mergestatemod.ACTION_EXEC,), sort=True
       
  1552     ):
  1537         repo.ui.debug(b" %s: %s -> e\n" % (f, msg))
  1553         repo.ui.debug(b" %s: %s -> e\n" % (f, msg))
  1538         progress.increment(item=f)
  1554         progress.increment(item=f)
  1539         (flags,) = args
  1555         (flags,) = args
  1540         wctx[f].audit()
  1556         wctx[f].audit()
  1541         wctx[f].setflags(b'l' in flags, b'x' in flags)
  1557         wctx[f].setflags(b'l' in flags, b'x' in flags)
  1612     merged += msmerged
  1628     merged += msmerged
  1613     removed += msremoved
  1629     removed += msremoved
  1614 
  1630 
  1615     extraactions = ms.actions()
  1631     extraactions = ms.actions()
  1616     if extraactions:
  1632     if extraactions:
  1617         mfiles = {a[0] for a in actions[mergestatemod.ACTION_MERGE]}
  1633         mfiles = {
       
  1634             a[0] for a in mresult.getactions((mergestatemod.ACTION_MERGE,))
       
  1635         }
  1618         for k, acts in pycompat.iteritems(extraactions):
  1636         for k, acts in pycompat.iteritems(extraactions):
  1619             actions[k].extend(acts)
       
  1620             for a in acts:
  1637             for a in acts:
  1621                 mresult.addfile(a[0], k, *a[1:])
  1638                 mresult.addfile(a[0], k, *a[1:])
  1622             if k == mergestatemod.ACTION_GET and wantfiledata:
  1639             if k == mergestatemod.ACTION_GET and wantfiledata:
  1623                 # no filedata until mergestate is updated to provide it
  1640                 # no filedata until mergestate is updated to provide it
  1624                 for a in acts:
  1641                 for a in acts:
  1639             #
  1656             #
  1640             # We don't need to do the same operation for 'dc' and 'cd' because
  1657             # We don't need to do the same operation for 'dc' and 'cd' because
  1641             # those lists aren't consulted again.
  1658             # those lists aren't consulted again.
  1642             mfiles.difference_update(a[0] for a in acts)
  1659             mfiles.difference_update(a[0] for a in acts)
  1643 
  1660 
  1644         actions[mergestatemod.ACTION_MERGE] = [
       
  1645             a for a in actions[mergestatemod.ACTION_MERGE] if a[0] in mfiles
       
  1646         ]
       
  1647         for a in mresult.getactions([mergestatemod.ACTION_MERGE]):
  1661         for a in mresult.getactions([mergestatemod.ACTION_MERGE]):
  1648             if a[0] not in mfiles:
  1662             if a[0] not in mfiles:
  1649                 mresult.removefile(a[0])
  1663                 mresult.removefile(a[0])
  1650 
  1664 
  1651     progress.complete()
  1665     progress.complete()
  1652     assert len(getfiledata) == (
  1666     assert len(getfiledata) == (
  1653         len(actions[mergestatemod.ACTION_GET]) if wantfiledata else 0
  1667         len(mresult._actionmapping[mergestatemod.ACTION_GET])
       
  1668         if wantfiledata
       
  1669         else 0
  1654     )
  1670     )
  1655     return updateresult(updated, merged, removed, unresolved), getfiledata
  1671     return updateresult(updated, merged, removed, unresolved), getfiledata
  1656 
  1672 
  1657 
  1673 
  1658 def _advertisefsmonitor(repo, num_gets, p1node):
  1674 def _advertisefsmonitor(repo, num_gets, p1node):