comparison mercurial/merge.py @ 43106:d783f945a701

py3: finish porting iteritems() to pycompat and remove source transformer This commit finishes porting .iteritems() to pycompat.iteritems() for the mercurial package. The translation of .iteritems() to .items() was the last conversion performed by the source transformer. With the porting to pycompat complete, we no longer have a need for the source transformer. So the source transformer has been removed. Good riddance! The code base is now compatible with Python 2 and Python 3. For the record, as the person who introduced the source transformer, it brings me joy to delete it. It accomplished its goal to facilitate a port to Python 3 without overly burdening people on some painful low-level differences between Python 2 and 3. It is unfortunate we still have to wallpaper over many differences with the pycompat shim. But it is what it is. Differential Revision: https://phab.mercurial-scm.org/D7015
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 07 Oct 2019 00:04:04 -0400
parents 74802979dd9d
children 8ff1ecfadcd1
comparison
equal deleted inserted replaced
43105:649d3ac37a12 43106:d783f945a701
434 # Write out state items. In all cases, the value of the state map entry 434 # Write out state items. In all cases, the value of the state map entry
435 # is written as the contents of the record. The record type depends on 435 # is written as the contents of the record. The record type depends on
436 # the type of state that is stored, and capital-letter records are used 436 # the type of state that is stored, and capital-letter records are used
437 # to prevent older versions of Mercurial that do not support the feature 437 # to prevent older versions of Mercurial that do not support the feature
438 # from loading them. 438 # from loading them.
439 for filename, v in self._state.iteritems(): 439 for filename, v in pycompat.iteritems(self._state):
440 if v[0] == MERGE_RECORD_DRIVER_RESOLVED: 440 if v[0] == MERGE_RECORD_DRIVER_RESOLVED:
441 # Driver-resolved merge. These are stored in 'D' records. 441 # Driver-resolved merge. These are stored in 'D' records.
442 records.append( 442 records.append(
443 (RECORD_MERGE_DRIVER_MERGE, b'\0'.join([filename] + v)) 443 (RECORD_MERGE_DRIVER_MERGE, b'\0'.join([filename] + v))
444 ) 444 )
460 (RECORD_CHANGEDELETE_CONFLICT, b'\0'.join([filename] + v)) 460 (RECORD_CHANGEDELETE_CONFLICT, b'\0'.join([filename] + v))
461 ) 461 )
462 else: 462 else:
463 # Normal files. These are stored in 'F' records. 463 # Normal files. These are stored in 'F' records.
464 records.append((RECORD_MERGED, b'\0'.join([filename] + v))) 464 records.append((RECORD_MERGED, b'\0'.join([filename] + v)))
465 for filename, extras in sorted(self._stateextras.iteritems()): 465 for filename, extras in sorted(pycompat.iteritems(self._stateextras)):
466 rawextras = b'\0'.join( 466 rawextras = b'\0'.join(
467 b'%s\0%s' % (k, v) for k, v in extras.iteritems() 467 b'%s\0%s' % (k, v) for k, v in pycompat.iteritems(extras)
468 ) 468 )
469 records.append( 469 records.append(
470 (RECORD_FILE_VALUES, b'%s\0%s' % (filename, rawextras)) 470 (RECORD_FILE_VALUES, b'%s\0%s' % (filename, rawextras))
471 ) 471 )
472 if self._labels is not None: 472 if self._labels is not None:
569 return self._mdstate 569 return self._mdstate
570 570
571 def unresolved(self): 571 def unresolved(self):
572 """Obtain the paths of unresolved files.""" 572 """Obtain the paths of unresolved files."""
573 573
574 for f, entry in self._state.iteritems(): 574 for f, entry in pycompat.iteritems(self._state):
575 if entry[0] in ( 575 if entry[0] in (
576 MERGE_RECORD_UNRESOLVED, 576 MERGE_RECORD_UNRESOLVED,
577 MERGE_RECORD_UNRESOLVED_PATH, 577 MERGE_RECORD_UNRESOLVED_PATH,
578 ): 578 ):
579 yield f 579 yield f
723 ACTION_FORGET: [], 723 ACTION_FORGET: [],
724 ACTION_ADD: [], 724 ACTION_ADD: [],
725 ACTION_ADD_MODIFIED: [], 725 ACTION_ADD_MODIFIED: [],
726 ACTION_GET: [], 726 ACTION_GET: [],
727 } 727 }
728 for f, (r, action) in self._results.iteritems(): 728 for f, (r, action) in pycompat.iteritems(self._results):
729 if action is not None: 729 if action is not None:
730 actions[action].append((f, None, b"merge result")) 730 actions[action].append((f, None, b"merge result"))
731 return actions 731 return actions
732 732
733 def recordactions(self): 733 def recordactions(self):
863 abortconflicts.update(conflicts) 863 abortconflicts.update(conflicts)
864 elif config == b'warn': 864 elif config == b'warn':
865 warnconflicts.update(conflicts) 865 warnconflicts.update(conflicts)
866 866
867 checkunknowndirs = _unknowndirschecker() 867 checkunknowndirs = _unknowndirschecker()
868 for f, (m, args, msg) in actions.iteritems(): 868 for f, (m, args, msg) in pycompat.iteritems(actions):
869 if m in (ACTION_CREATED, ACTION_DELETED_CHANGED): 869 if m in (ACTION_CREATED, ACTION_DELETED_CHANGED):
870 if _checkunknownfile(repo, wctx, mctx, f): 870 if _checkunknownfile(repo, wctx, mctx, f):
871 fileconflicts.add(f) 871 fileconflicts.add(f)
872 elif pathconfig and f not in wctx: 872 elif pathconfig and f not in wctx:
873 path = checkunknowndirs(repo, wctx, f) 873 path = checkunknowndirs(repo, wctx, f)
881 ignoredconflicts = {c for c in allconflicts if repo.dirstate._ignore(c)} 881 ignoredconflicts = {c for c in allconflicts if repo.dirstate._ignore(c)}
882 unknownconflicts = allconflicts - ignoredconflicts 882 unknownconflicts = allconflicts - ignoredconflicts
883 collectconflicts(ignoredconflicts, ignoredconfig) 883 collectconflicts(ignoredconflicts, ignoredconfig)
884 collectconflicts(unknownconflicts, unknownconfig) 884 collectconflicts(unknownconflicts, unknownconfig)
885 else: 885 else:
886 for f, (m, args, msg) in actions.iteritems(): 886 for f, (m, args, msg) in pycompat.iteritems(actions):
887 if m == ACTION_CREATED_MERGE: 887 if m == ACTION_CREATED_MERGE:
888 fl2, anc = args 888 fl2, anc = args
889 different = _checkunknownfile(repo, wctx, mctx, f) 889 different = _checkunknownfile(repo, wctx, mctx, f)
890 if repo.dirstate._ignore(f): 890 if repo.dirstate._ignore(f):
891 config = ignoredconfig 891 config = ignoredconfig
940 if repo.wvfs.isfileorlink(f): 940 if repo.wvfs.isfileorlink(f):
941 repo.ui.warn(_(b"%s: replacing untracked file\n") % f) 941 repo.ui.warn(_(b"%s: replacing untracked file\n") % f)
942 else: 942 else:
943 repo.ui.warn(_(b"%s: replacing untracked files in directory\n") % f) 943 repo.ui.warn(_(b"%s: replacing untracked files in directory\n") % f)
944 944
945 for f, (m, args, msg) in actions.iteritems(): 945 for f, (m, args, msg) in pycompat.iteritems(actions):
946 if m == ACTION_CREATED: 946 if m == ACTION_CREATED:
947 backup = ( 947 backup = (
948 f in fileconflicts 948 f in fileconflicts
949 or f in pathconflicts 949 or f in pathconflicts
950 or any(p in pathconflicts for p in util.finddirs(f)) 950 or any(p in pathconflicts for p in util.finddirs(f))
993 narrowmatch = repo.narrowmatch() 993 narrowmatch = repo.narrowmatch()
994 if not narrowmatch.always(): 994 if not narrowmatch.always():
995 wmf = wmf.matches(narrowmatch) 995 wmf = wmf.matches(narrowmatch)
996 if actions: 996 if actions:
997 narrowactions = {} 997 narrowactions = {}
998 for m, actionsfortype in actions.iteritems(): 998 for m, actionsfortype in pycompat.iteritems(actions):
999 narrowactions[m] = [] 999 narrowactions[m] = []
1000 for (f, args, msg) in actionsfortype: 1000 for (f, args, msg) in actionsfortype:
1001 if narrowmatch(f): 1001 if narrowmatch(f):
1002 narrowactions[m].append((f, args, msg)) 1002 narrowactions[m].append((f, args, msg))
1003 actions = narrowactions 1003 actions = narrowactions
1296 # total m1-vs-m2 diff to just those files. This has significant 1296 # total m1-vs-m2 diff to just those files. This has significant
1297 # performance benefits in large repositories. 1297 # performance benefits in large repositories.
1298 relevantfiles = set(ma.diff(m2).keys()) 1298 relevantfiles = set(ma.diff(m2).keys())
1299 1299
1300 # For copied and moved files, we need to add the source file too. 1300 # For copied and moved files, we need to add the source file too.
1301 for copykey, copyvalue in copy.iteritems(): 1301 for copykey, copyvalue in pycompat.iteritems(copy):
1302 if copyvalue in relevantfiles: 1302 if copyvalue in relevantfiles:
1303 relevantfiles.add(copykey) 1303 relevantfiles.add(copykey)
1304 for movedirkey in movewithdir: 1304 for movedirkey in movewithdir:
1305 relevantfiles.add(movedirkey) 1305 relevantfiles.add(movedirkey)
1306 filesmatcher = scmutil.matchfiles(repo, relevantfiles) 1306 filesmatcher = scmutil.matchfiles(repo, relevantfiles)
1307 matcher = matchmod.intersectmatchers(matcher, filesmatcher) 1307 matcher = matchmod.intersectmatchers(matcher, filesmatcher)
1308 1308
1309 diff = m1.diff(m2, match=matcher) 1309 diff = m1.diff(m2, match=matcher)
1310 1310
1311 actions = {} 1311 actions = {}
1312 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems(): 1312 for f, ((n1, fl1), (n2, fl2)) in pycompat.iteritems(diff):
1313 if n1 and n2: # file exists on both local and remote side 1313 if n1 and n2: # file exists on both local and remote side
1314 if f not in ma: 1314 if f not in ma:
1315 fa = copy.get(f, None) 1315 fa = copy.get(f, None)
1316 if fa is not None: 1316 if fa is not None:
1317 actions[f] = ( 1317 actions[f] = (
1571 if diverge is None or len(diverge1) < len(diverge): 1571 if diverge is None or len(diverge1) < len(diverge):
1572 diverge = diverge1 1572 diverge = diverge1
1573 if renamedelete is None or len(renamedelete) < len(renamedelete1): 1573 if renamedelete is None or len(renamedelete) < len(renamedelete1):
1574 renamedelete = renamedelete1 1574 renamedelete = renamedelete1
1575 1575
1576 for f, a in sorted(actions.iteritems()): 1576 for f, a in sorted(pycompat.iteritems(actions)):
1577 m, args, msg = a 1577 m, args, msg = a
1578 repo.ui.debug(b' %s: %s -> %s\n' % (f, msg, m)) 1578 repo.ui.debug(b' %s: %s -> %s\n' % (f, msg, m))
1579 if f in fbids: 1579 if f in fbids:
1580 d = fbids[f] 1580 d = fbids[f]
1581 if m in d: 1581 if m in d:
2056 removed += msremoved 2056 removed += msremoved
2057 2057
2058 extraactions = ms.actions() 2058 extraactions = ms.actions()
2059 if extraactions: 2059 if extraactions:
2060 mfiles = set(a[0] for a in actions[ACTION_MERGE]) 2060 mfiles = set(a[0] for a in actions[ACTION_MERGE])
2061 for k, acts in extraactions.iteritems(): 2061 for k, acts in pycompat.iteritems(extraactions):
2062 actions[k].extend(acts) 2062 actions[k].extend(acts)
2063 if k == ACTION_GET and wantfiledata: 2063 if k == ACTION_GET and wantfiledata:
2064 # no filedata until mergestate is updated to provide it 2064 # no filedata until mergestate is updated to provide it
2065 for a in acts: 2065 for a in acts:
2066 getfiledata[a[0]] = None 2066 getfiledata[a[0]] = None
2399 matcher=matcher, 2399 matcher=matcher,
2400 mergeforce=mergeforce, 2400 mergeforce=mergeforce,
2401 ) 2401 )
2402 2402
2403 if updatecheck == UPDATECHECK_NO_CONFLICT: 2403 if updatecheck == UPDATECHECK_NO_CONFLICT:
2404 for f, (m, args, msg) in actionbyfile.iteritems(): 2404 for f, (m, args, msg) in pycompat.iteritems(actionbyfile):
2405 if m not in ( 2405 if m not in (
2406 ACTION_GET, 2406 ACTION_GET,
2407 ACTION_KEEP, 2407 ACTION_KEEP,
2408 ACTION_EXEC, 2408 ACTION_EXEC,
2409 ACTION_REMOVE, 2409 ACTION_REMOVE,
2463 else: 2463 else:
2464 del actionbyfile[f] 2464 del actionbyfile[f]
2465 2465
2466 # Convert to dictionary-of-lists format 2466 # Convert to dictionary-of-lists format
2467 actions = emptyactions() 2467 actions = emptyactions()
2468 for f, (m, args, msg) in actionbyfile.iteritems(): 2468 for f, (m, args, msg) in pycompat.iteritems(actionbyfile):
2469 if m not in actions: 2469 if m not in actions:
2470 actions[m] = [] 2470 actions[m] = []
2471 actions[m].append((f, args, msg)) 2471 actions[m].append((f, args, msg))
2472 2472
2473 if not util.fscasesensitive(repo.path): 2473 if not util.fscasesensitive(repo.path):
2478 _checkcollision(repo, p2.manifest(), None) 2478 _checkcollision(repo, p2.manifest(), None)
2479 else: 2479 else:
2480 _checkcollision(repo, wc.manifest(), actions) 2480 _checkcollision(repo, wc.manifest(), actions)
2481 2481
2482 # divergent renames 2482 # divergent renames
2483 for f, fl in sorted(diverge.iteritems()): 2483 for f, fl in sorted(pycompat.iteritems(diverge)):
2484 repo.ui.warn( 2484 repo.ui.warn(
2485 _( 2485 _(
2486 b"note: possible conflict - %s was renamed " 2486 b"note: possible conflict - %s was renamed "
2487 b"multiple times to:\n" 2487 b"multiple times to:\n"
2488 ) 2488 )
2490 ) 2490 )
2491 for nf in sorted(fl): 2491 for nf in sorted(fl):
2492 repo.ui.warn(b" %s\n" % nf) 2492 repo.ui.warn(b" %s\n" % nf)
2493 2493
2494 # rename and delete 2494 # rename and delete
2495 for f, fl in sorted(renamedelete.iteritems()): 2495 for f, fl in sorted(pycompat.iteritems(renamedelete)):
2496 repo.ui.warn( 2496 repo.ui.warn(
2497 _( 2497 _(
2498 b"note: possible conflict - %s was deleted " 2498 b"note: possible conflict - %s was deleted "
2499 b"and renamed to:\n" 2499 b"and renamed to:\n"
2500 ) 2500 )