Mercurial > hg
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 ) |