diff -r 2a68a5ec8dd0 -r 32ce4cbaec4b mercurial/mergestate.py --- a/mercurial/mergestate.py Sun Sep 06 10:33:12 2020 +0200 +++ b/mercurial/mergestate.py Thu Sep 17 22:34:36 2020 -0700 @@ -48,8 +48,6 @@ RECORD_OTHER = b'O' # record merge labels RECORD_LABELS = b'l' -# store info about merge driver used and it's state -RECORD_MERGE_DRIVER_STATE = b'm' ##### # record extra information about files, with one entry containing info about one @@ -65,7 +63,6 @@ ##### RECORD_MERGED = b'F' RECORD_CHANGEDELETE_CONFLICT = b'C' -RECORD_MERGE_DRIVER_MERGE = b'D' # the path was dir on one side of merge and file on another RECORD_PATH_CONFLICT = b'P' @@ -77,7 +74,6 @@ MERGE_RECORD_RESOLVED = b'r' MERGE_RECORD_UNRESOLVED_PATH = b'pu' MERGE_RECORD_RESOLVED_PATH = b'pr' -MERGE_RECORD_DRIVER_RESOLVED = b'd' # represents that the file was automatically merged in favor # of other version. This info is used on commit. # This is now deprecated and commit related information is now @@ -91,18 +87,16 @@ RECORD_OVERRIDE = b't' ##### -# possible states which a merge driver can have. These are stored inside a -# RECORD_MERGE_DRIVER_STATE entry -##### -MERGE_DRIVER_STATE_UNMARKED = b'u' -MERGE_DRIVER_STATE_MARKED = b'm' -MERGE_DRIVER_STATE_SUCCESS = b's' - -##### # legacy records which are no longer used but kept to prevent breaking BC ##### # This record was release in 5.4 and usage was removed in 5.5 LEGACY_RECORD_RESOLVED_OTHER = b'R' +# This record was release in 3.7 and usage was removed in 5.6 +LEGACY_RECORD_DRIVER_RESOLVED = b'd' +# This record was release in 3.7 and usage was removed in 5.6 +LEGACY_MERGE_DRIVER_STATE = b'm' +# This record was release in 3.7 and usage was removed in 5.6 +LEGACY_MERGE_DRIVER_MERGE = b'D' ACTION_FORGET = b'f' @@ -147,26 +141,15 @@ O: the node of the "other" part of the merge (hexified version) F: a file to be merged entry C: a change/delete or delete/change conflict - D: a file that the external merge driver will merge internally - (experimental) P: a path conflict (file vs directory) - m: the external merge driver defined for this merge plus its run state - (experimental) f: a (filename, dictionary) tuple of optional values for a given file l: the labels for the parts of the merge. - Merge driver run states (experimental): - u: driver-resolved files unmarked -- needs to be run next time we're about - to resolve or commit - m: driver-resolved files marked -- only needs to be run before commit - s: success/skipped -- does not need to be run any more - Merge record states (stored in self._state, indexed by filename): u: unresolved conflict r: resolved conflict pu: unresolved path conflict (file conflicts with directory) pr: resolved path conflict - d: driver-resolved conflict The resolve command transitions between 'u' and 'r' for conflicts and 'pu' and 'pr' for path conflicts. @@ -182,8 +165,6 @@ self._local = None self._other = None self._labels = None - self._readmergedriver = None - self._mdstate = MERGE_DRIVER_STATE_UNMARKED # contains a mapping of form: # {filename : (merge_return_value, action_to_be_performed} # these are results of re-running merge process @@ -199,32 +180,6 @@ self._local = node self._other = other self._labels = labels - if self.mergedriver: - self._mdstate = MERGE_DRIVER_STATE_SUCCESS - - @util.propertycache - def mergedriver(self): - # protect against the following: - # - A configures a malicious merge driver in their hgrc, then - # pauses the merge - # - A edits their hgrc to remove references to the merge driver - # - A gives a copy of their entire repo, including .hg, to B - # - B inspects .hgrc and finds it to be clean - # - B then continues the merge and the malicious merge driver - # gets invoked - configmergedriver = self._repo.ui.config( - b'experimental', b'mergedriver' - ) - if ( - self._readmergedriver is not None - and self._readmergedriver != configmergedriver - ): - raise error.ConfigError( - _(b"merge driver changed since merge started"), - hint=_(b"revert merge driver change or abort merge"), - ) - - return configmergedriver @util.propertycache def local(self): @@ -330,9 +285,6 @@ self._state[dfile][0] = state self._dirty = True - def mdstate(self): - return self._mdstate - def unresolved(self): """Obtain the paths of unresolved files.""" @@ -343,13 +295,6 @@ ): yield f - def driverresolved(self): - """Obtain the paths of driver-resolved files.""" - - for f, entry in self._state.items(): - if entry[0] == MERGE_RECORD_DRIVER_RESOLVED: - yield f - def extras(self, filename): return self._stateextras[filename] @@ -358,7 +303,10 @@ Returns whether the merge was completed and the return value of merge obtained from filemerge._filemerge(). """ - if self[dfile] in (MERGE_RECORD_RESOLVED, MERGE_RECORD_DRIVER_RESOLVED): + if self[dfile] in ( + MERGE_RECORD_RESOLVED, + LEGACY_RECORD_DRIVER_RESOLVED, + ): return True, 0 stateentry = self._state[dfile] state, localkey, lfile, afile, anode, ofile, onode, flags = stateentry @@ -490,24 +438,6 @@ actions[action].append((f, None, b"merge result")) return actions - def queueremove(self, f): - """queues a file to be removed from the dirstate - - Meant for use by custom merge drivers.""" - self._results[f] = 0, ACTION_REMOVE - - def queueadd(self, f): - """queues a file to be added to the dirstate - - Meant for use by custom merge drivers.""" - self._results[f] = 0, ACTION_ADD - - def queueget(self, f): - """queues a file to be marked modified in the dirstate - - Meant for use by custom merge drivers.""" - self._results[f] = 0, ACTION_GET - class mergestate(_mergestate_base): @@ -535,7 +465,6 @@ This function process "record" entry produced by the de-serialization of on disk file. """ - self._mdstate = MERGE_DRIVER_STATE_SUCCESS unsupported = set() records = self._readrecords() for rtype, record in records: @@ -543,24 +472,13 @@ self._local = bin(record) elif rtype == RECORD_OTHER: self._other = bin(record) - elif rtype == RECORD_MERGE_DRIVER_STATE: - bits = record.split(b'\0', 1) - mdstate = bits[1] - if len(mdstate) != 1 or mdstate not in ( - MERGE_DRIVER_STATE_UNMARKED, - MERGE_DRIVER_STATE_MARKED, - MERGE_DRIVER_STATE_SUCCESS, - ): - # the merge driver should be idempotent, so just rerun it - mdstate = MERGE_DRIVER_STATE_UNMARKED - - self._readmergedriver = bits[0] - self._mdstate = mdstate + elif rtype == LEGACY_MERGE_DRIVER_STATE: + pass elif rtype in ( RECORD_MERGED, RECORD_CHANGEDELETE_CONFLICT, RECORD_PATH_CONFLICT, - RECORD_MERGE_DRIVER_MERGE, + LEGACY_MERGE_DRIVER_MERGE, LEGACY_RECORD_RESOLVED_OTHER, ): bits = record.split(b'\0') @@ -710,25 +628,13 @@ records = [] records.append((RECORD_LOCAL, hex(self._local))) records.append((RECORD_OTHER, hex(self._other))) - if self.mergedriver: - records.append( - ( - RECORD_MERGE_DRIVER_STATE, - b'\0'.join([self.mergedriver, self._mdstate]), - ) - ) # Write out state items. In all cases, the value of the state map entry # is written as the contents of the record. The record type depends on # the type of state that is stored, and capital-letter records are used # to prevent older versions of Mercurial that do not support the feature # from loading them. for filename, v in pycompat.iteritems(self._state): - if v[0] == MERGE_RECORD_DRIVER_RESOLVED: - # Driver-resolved merge. These are stored in 'D' records. - records.append( - (RECORD_MERGE_DRIVER_MERGE, b'\0'.join([filename] + v)) - ) - elif v[0] in ( + if v[0] in ( MERGE_RECORD_UNRESOLVED_PATH, MERGE_RECORD_RESOLVED_PATH, ): @@ -814,17 +720,6 @@ def _restore_backup(self, fctx, localkey, flags): fctx.write(self._backups[localkey], flags) - @util.propertycache - def mergedriver(self): - configmergedriver = self._repo.ui.config( - b'experimental', b'mergedriver' - ) - if configmergedriver: - raise error.InMemoryMergeConflictsError( - b"in-memory merge does not support mergedriver" - ) - return None - def recordupdates(repo, actions, branchmerge, getfiledata): """record merge actions to the dirstate"""