Mercurial > public > mercurial-scm > hg-stable
diff mercurial/mergestate.py @ 45526:32ce4cbaec4b
mergedriver: delete it
The merge driver code was added in late 2015. I think
'406a654b::6f045b56 & user("sid0")' is a reasonable revset for finding
the relevant commits, including preparation for it. The code is very
poorly tested, which makes it very hard to maintain. It seems it's
only used by FB and they don't use this code base anymore, so let's
remove the code to make it easier for us to maintain our product.
Differential Revision: https://phab.mercurial-scm.org/D9041
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Thu, 17 Sep 2020 22:34:36 -0700 |
parents | 0e75c088f0dc |
children | 6877b0ee5f9d |
line wrap: on
line diff
--- 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"""