comparison mercurial/merge.py @ 35172:a92b9f8e11ba stable 4.4.2

merge: check created file dirs for path conflicts only once (issue5716) In large repositories, updates involving the creation of many files check the same directories repeatedly in the wctx manifest. Move these checks out to a separate loop to avoid repeated checks hitting the manifest. Differential Revision: https://phab.mercurial-scm.org/D1226
author Mark Thomas <mbthomas@fb.com>
date Fri, 24 Nov 2017 12:53:58 -0800
parents b85962350bb3
children 46510597d266
comparison
equal deleted inserted replaced
35171:b85962350bb3 35172:a92b9f8e11ba
913 # The set of directories that appear as both a file and a directory in the 913 # The set of directories that appear as both a file and a directory in the
914 # remote manifest. These indicate an invalid remote manifest, which 914 # remote manifest. These indicate an invalid remote manifest, which
915 # can't be updated to cleanly. 915 # can't be updated to cleanly.
916 invalidconflicts = set() 916 invalidconflicts = set()
917 917
918 # The set of directories that contain files that are being created.
919 createdfiledirs = set()
920
918 # The set of files deleted by all the actions. 921 # The set of files deleted by all the actions.
919 deletedfiles = set() 922 deletedfiles = set()
920 923
921 for f, (m, args, msg) in actions.items(): 924 for f, (m, args, msg) in actions.items():
922 if m in ('c', 'dc', 'm', 'cm'): 925 if m in ('c', 'dc', 'm', 'cm'):
923 # This action may create a new local file. 926 # This action may create a new local file.
927 createdfiledirs.update(util.finddirs(f))
924 if mf.hasdir(f): 928 if mf.hasdir(f):
925 # The file aliases a local directory. This might be ok if all 929 # The file aliases a local directory. This might be ok if all
926 # the files in the local directory are being deleted. This 930 # the files in the local directory are being deleted. This
927 # will be checked once we know what all the deleted files are. 931 # will be checked once we know what all the deleted files are.
928 remoteconflicts.add(f) 932 remoteconflicts.add(f)
929 for p in util.finddirs(f):
930 if p in mf:
931 if p in mctx:
932 # The file is in a directory which aliases both a local
933 # and a remote file. This is an internal inconsistency
934 # within the remote manifest.
935 invalidconflicts.add(p)
936 else:
937 # The file is in a directory which aliases a local file.
938 # We will need to rename the local file.
939 localconflicts.add(p)
940 if p in actions and actions[p][0] in ('c', 'dc', 'm', 'cm'):
941 # The file is in a directory which aliases a remote file.
942 # This is an internal inconsistency within the remote
943 # manifest.
944 invalidconflicts.add(p)
945
946 # Track the names of all deleted files. 933 # Track the names of all deleted files.
947 if m == 'r': 934 if m == 'r':
948 deletedfiles.add(f) 935 deletedfiles.add(f)
949 if m == 'm': 936 if m == 'm':
950 f1, f2, fa, move, anc = args 937 f1, f2, fa, move, anc = args
951 if move: 938 if move:
952 deletedfiles.add(f1) 939 deletedfiles.add(f1)
953 if m == 'dm': 940 if m == 'dm':
954 f2, flags = args 941 f2, flags = args
955 deletedfiles.add(f2) 942 deletedfiles.add(f2)
943
944 # Check all directories that contain created files for path conflicts.
945 for p in createdfiledirs:
946 if p in mf:
947 if p in mctx:
948 # A file is in a directory which aliases both a local
949 # and a remote file. This is an internal inconsistency
950 # within the remote manifest.
951 invalidconflicts.add(p)
952 else:
953 # A file is in a directory which aliases a local file.
954 # We will need to rename the local file.
955 localconflicts.add(p)
956 if p in actions and actions[p][0] in ('c', 'dc', 'm', 'cm'):
957 # The file is in a directory which aliases a remote file.
958 # This is an internal inconsistency within the remote
959 # manifest.
960 invalidconflicts.add(p)
956 961
957 # Rename all local conflicting files that have not been deleted. 962 # Rename all local conflicting files that have not been deleted.
958 for p in localconflicts: 963 for p in localconflicts:
959 if p not in deletedfiles: 964 if p not in deletedfiles:
960 ctxname = str(wctx).rstrip('+') 965 ctxname = str(wctx).rstrip('+')