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