mercurial/merge.py
changeset 44200 fa9ad1da2e77
parent 44199 7f8bdee0034e
child 44211 fc7175df6359
equal deleted inserted replaced
44199:7f8bdee0034e 44200:fa9ad1da2e77
  1260     [
  1260     [
  1261         x.manifest()
  1261         x.manifest()
  1262         for x in sorted(wctx.parents() + [p2, pa], key=scmutil.intrev)
  1262         for x in sorted(wctx.parents() + [p2, pa], key=scmutil.intrev)
  1263     ]
  1263     ]
  1264 
  1264 
  1265     copy, movewithdir, diverge, renamedelete, dirmove = {}, {}, {}, {}, {}
  1265     branch_copies1 = copies.branch_copies()
       
  1266     branch_copies2 = copies.branch_copies()
       
  1267     diverge = {}
  1266     if followcopies:
  1268     if followcopies:
  1267         branch_copies, diverge = copies.mergecopies(repo, wctx, p2, pa)
  1269         branch_copies1, branch_copies2, diverge = copies.mergecopies(
  1268         copy = branch_copies.copy
  1270             repo, wctx, p2, pa
  1269         renamedelete = branch_copies.renamedelete
  1271         )
  1270         dirmove = branch_copies.dirmove
       
  1271         movewithdir = branch_copies.movewithdir
       
  1272 
  1272 
  1273     boolbm = pycompat.bytestr(bool(branchmerge))
  1273     boolbm = pycompat.bytestr(bool(branchmerge))
  1274     boolf = pycompat.bytestr(bool(force))
  1274     boolf = pycompat.bytestr(bool(force))
  1275     boolm = pycompat.bytestr(bool(matcher))
  1275     boolm = pycompat.bytestr(bool(matcher))
  1276     repo.ui.note(_(b"resolving manifests\n"))
  1276     repo.ui.note(_(b"resolving manifests\n"))
  1278         b" branchmerge: %s, force: %s, partial: %s\n" % (boolbm, boolf, boolm)
  1278         b" branchmerge: %s, force: %s, partial: %s\n" % (boolbm, boolf, boolm)
  1279     )
  1279     )
  1280     repo.ui.debug(b" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
  1280     repo.ui.debug(b" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
  1281 
  1281 
  1282     m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
  1282     m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
  1283     copied = set(copy.values())
  1283     copied1 = set(branch_copies1.copy.values())
  1284     copied.update(movewithdir.values())
  1284     copied1.update(branch_copies1.movewithdir.values())
       
  1285     copied2 = set(branch_copies2.copy.values())
       
  1286     copied2.update(branch_copies2.movewithdir.values())
  1285 
  1287 
  1286     if b'.hgsubstate' in m1 and wctx.rev() is None:
  1288     if b'.hgsubstate' in m1 and wctx.rev() is None:
  1287         # Check whether sub state is modified, and overwrite the manifest
  1289         # Check whether sub state is modified, and overwrite the manifest
  1288         # to flag the change. If wctx is a committed revision, we shouldn't
  1290         # to flag the change. If wctx is a committed revision, we shouldn't
  1289         # care for the dirty state of the working directory.
  1291         # care for the dirty state of the working directory.
  1299         # total m1-vs-m2 diff to just those files. This has significant
  1301         # total m1-vs-m2 diff to just those files. This has significant
  1300         # performance benefits in large repositories.
  1302         # performance benefits in large repositories.
  1301         relevantfiles = set(ma.diff(m2).keys())
  1303         relevantfiles = set(ma.diff(m2).keys())
  1302 
  1304 
  1303         # For copied and moved files, we need to add the source file too.
  1305         # For copied and moved files, we need to add the source file too.
  1304         for copykey, copyvalue in pycompat.iteritems(copy):
  1306         for copykey, copyvalue in pycompat.iteritems(branch_copies1.copy):
  1305             if copyvalue in relevantfiles:
  1307             if copyvalue in relevantfiles:
  1306                 relevantfiles.add(copykey)
  1308                 relevantfiles.add(copykey)
  1307         for movedirkey in movewithdir:
  1309         for movedirkey in branch_copies1.movewithdir:
  1308             relevantfiles.add(movedirkey)
  1310             relevantfiles.add(movedirkey)
  1309         filesmatcher = scmutil.matchfiles(repo, relevantfiles)
  1311         filesmatcher = scmutil.matchfiles(repo, relevantfiles)
  1310         matcher = matchmod.intersectmatchers(matcher, filesmatcher)
  1312         matcher = matchmod.intersectmatchers(matcher, filesmatcher)
  1311 
  1313 
  1312     diff = m1.diff(m2, match=matcher)
  1314     diff = m1.diff(m2, match=matcher)
  1313 
  1315 
  1314     actions = {}
  1316     actions = {}
  1315     for f, ((n1, fl1), (n2, fl2)) in pycompat.iteritems(diff):
  1317     for f, ((n1, fl1), (n2, fl2)) in pycompat.iteritems(diff):
  1316         if n1 and n2:  # file exists on both local and remote side
  1318         if n1 and n2:  # file exists on both local and remote side
  1317             if f not in ma:
  1319             if f not in ma:
  1318                 fa = copy.get(f, None)
  1320                 # TODO: what if they're renamed from different sources?
       
  1321                 fa = branch_copies1.copy.get(
       
  1322                     f, None
       
  1323                 ) or branch_copies2.copy.get(f, None)
  1319                 if fa is not None:
  1324                 if fa is not None:
  1320                     actions[f] = (
  1325                     actions[f] = (
  1321                         ACTION_MERGE,
  1326                         ACTION_MERGE,
  1322                         (f, f, fa, False, pa.node()),
  1327                         (f, f, fa, False, pa.node()),
  1323                         b'both renamed from %s' % fa,
  1328                         b'both renamed from %s' % fa,
  1356                         ACTION_MERGE,
  1361                         ACTION_MERGE,
  1357                         (f, f, f, False, pa.node()),
  1362                         (f, f, f, False, pa.node()),
  1358                         b'versions differ',
  1363                         b'versions differ',
  1359                     )
  1364                     )
  1360         elif n1:  # file exists only on local side
  1365         elif n1:  # file exists only on local side
  1361             if f in copied:
  1366             if f in copied2:
  1362                 pass  # we'll deal with it on m2 side
  1367                 pass  # we'll deal with it on m2 side
  1363             elif f in movewithdir:  # directory rename, move local
  1368             elif (
  1364                 f2 = movewithdir[f]
  1369                 f in branch_copies1.movewithdir
       
  1370             ):  # directory rename, move local
       
  1371                 f2 = branch_copies1.movewithdir[f]
  1365                 if f2 in m2:
  1372                 if f2 in m2:
  1366                     actions[f2] = (
  1373                     actions[f2] = (
  1367                         ACTION_MERGE,
  1374                         ACTION_MERGE,
  1368                         (f, f2, None, True, pa.node()),
  1375                         (f, f2, None, True, pa.node()),
  1369                         b'remote directory rename, both created',
  1376                         b'remote directory rename, both created',
  1372                     actions[f2] = (
  1379                     actions[f2] = (
  1373                         ACTION_DIR_RENAME_MOVE_LOCAL,
  1380                         ACTION_DIR_RENAME_MOVE_LOCAL,
  1374                         (f, fl1),
  1381                         (f, fl1),
  1375                         b'remote directory rename - move from %s' % f,
  1382                         b'remote directory rename - move from %s' % f,
  1376                     )
  1383                     )
  1377             elif f in copy:
  1384             elif f in branch_copies1.copy:
  1378                 f2 = copy[f]
  1385                 f2 = branch_copies1.copy[f]
  1379                 actions[f] = (
  1386                 actions[f] = (
  1380                     ACTION_MERGE,
  1387                     ACTION_MERGE,
  1381                     (f, f2, f2, False, pa.node()),
  1388                     (f, f2, f2, False, pa.node()),
  1382                     b'local copied/moved from %s' % f2,
  1389                     b'local copied/moved from %s' % f2,
  1383                 )
  1390                 )
  1397                     # deleting it.
  1404                     # deleting it.
  1398                     actions[f] = (ACTION_FORGET, None, b'remote deleted')
  1405                     actions[f] = (ACTION_FORGET, None, b'remote deleted')
  1399                 else:
  1406                 else:
  1400                     actions[f] = (ACTION_REMOVE, None, b'other deleted')
  1407                     actions[f] = (ACTION_REMOVE, None, b'other deleted')
  1401         elif n2:  # file exists only on remote side
  1408         elif n2:  # file exists only on remote side
  1402             if f in copied:
  1409             if f in copied1:
  1403                 pass  # we'll deal with it on m1 side
  1410                 pass  # we'll deal with it on m1 side
  1404             elif f in movewithdir:
  1411             elif f in branch_copies2.movewithdir:
  1405                 f2 = movewithdir[f]
  1412                 f2 = branch_copies2.movewithdir[f]
  1406                 if f2 in m1:
  1413                 if f2 in m1:
  1407                     actions[f2] = (
  1414                     actions[f2] = (
  1408                         ACTION_MERGE,
  1415                         ACTION_MERGE,
  1409                         (f2, f, None, False, pa.node()),
  1416                         (f2, f, None, False, pa.node()),
  1410                         b'local directory rename, both created',
  1417                         b'local directory rename, both created',
  1413                     actions[f2] = (
  1420                     actions[f2] = (
  1414                         ACTION_LOCAL_DIR_RENAME_GET,
  1421                         ACTION_LOCAL_DIR_RENAME_GET,
  1415                         (f, fl2),
  1422                         (f, fl2),
  1416                         b'local directory rename - get from %s' % f,
  1423                         b'local directory rename - get from %s' % f,
  1417                     )
  1424                     )
  1418             elif f in copy:
  1425             elif f in branch_copies2.copy:
  1419                 f2 = copy[f]
  1426                 f2 = branch_copies2.copy[f]
  1420                 if f2 in m2:
  1427                 if f2 in m2:
  1421                     actions[f] = (
  1428                     actions[f] = (
  1422                         ACTION_MERGE,
  1429                         ACTION_MERGE,
  1423                         (f2, f, f2, False, pa.node()),
  1430                         (f2, f, f2, False, pa.node()),
  1424                         b'remote copied from %s' % f2,
  1431                         b'remote copied from %s' % f2,
  1451                         (fl2, pa.node()),
  1458                         (fl2, pa.node()),
  1452                         b'remote created, get or merge',
  1459                         b'remote created, get or merge',
  1453                     )
  1460                     )
  1454             elif n2 != ma[f]:
  1461             elif n2 != ma[f]:
  1455                 df = None
  1462                 df = None
  1456                 for d in dirmove:
  1463                 for d in branch_copies1.dirmove:
  1457                     if f.startswith(d):
  1464                     if f.startswith(d):
  1458                         # new file added in a directory that was moved
  1465                         # new file added in a directory that was moved
  1459                         df = dirmove[d] + f[len(d) :]
  1466                         df = branch_copies1.dirmove[d] + f[len(d) :]
  1460                         break
  1467                         break
  1461                 if df is not None and df in m1:
  1468                 if df is not None and df in m1:
  1462                     actions[df] = (
  1469                     actions[df] = (
  1463                         ACTION_MERGE,
  1470                         ACTION_MERGE,
  1464                         (df, f, f, False, pa.node()),
  1471                         (df, f, f, False, pa.node()),
  1480 
  1487 
  1481     narrowmatch = repo.narrowmatch()
  1488     narrowmatch = repo.narrowmatch()
  1482     if not narrowmatch.always():
  1489     if not narrowmatch.always():
  1483         # Updates "actions" in place
  1490         # Updates "actions" in place
  1484         _filternarrowactions(narrowmatch, branchmerge, actions)
  1491         _filternarrowactions(narrowmatch, branchmerge, actions)
       
  1492 
       
  1493     renamedelete = branch_copies1.renamedelete
       
  1494     renamedelete.update(branch_copies2.renamedelete)
  1485 
  1495 
  1486     return actions, diverge, renamedelete
  1496     return actions, diverge, renamedelete
  1487 
  1497 
  1488 
  1498 
  1489 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):
  1499 def _resolvetrivial(repo, wctx, mctx, ancestor, actions):