diff --git a/mercurial/help.py b/mercurial/help.py --- a/mercurial/help.py +++ b/mercurial/help.py @@ -320,6 +320,8 @@ loaddoc('config', subdir='internals')), (['extensions', 'extension'], _('Extension API'), loaddoc('extensions', subdir='internals')), + (['mergestate'], _('Mergestate'), + loaddoc('mergestate', subdir='internals')), (['requirements'], _('Repository Requirements'), loaddoc('requirements', subdir='internals')), (['revlogs'], _('Revision Logs'), diff --git a/mercurial/help/internals/mergestate.txt b/mercurial/help/internals/mergestate.txt new file mode 100644 --- /dev/null +++ b/mercurial/help/internals/mergestate.txt @@ -0,0 +1,80 @@ +The active mergestate is stored in ``.hg/merge`` when a merge is triggered +by commands like ``hg merge``, ``hg rebase``, etc. until the merge is +completed or aborted to track the 3-way merge state of individual files. + +The contents of the directory are: + +Conflicting files +----------------- + +The local version of the conflicting files are stored with their +filenames as the hash of their paths. + +state +----- + +This mergestate file record is used by hg version prior to 2.9.1 +and contains less data than ``state2``. If there is no contradiction +with ``state2``, we can assume that both are written at the same time. +In this case, data from ``state2`` is used. Otherwise, we use ``state``. +We read/write both ``state`` and ``state2`` records to ensure backward +compatibility. + +state2 +------ + +This record stores a superset of data in ``state``, including new kinds +of records in the future. + +Each record can contain arbitrary content and has an associated type. This +`type` should be a letter. If `type` is uppercase, the record is mandatory: +versions of Mercurial that don't support it should abort. If `type` is +lowercase, the record can be safely ignored. + +Currently known records: + +| * L: the node of the "local" part of the merge (hexified version) +| * 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 +| * X: unsupported mandatory record type (used in tests) +| * x: unsupported advisory record type (used in tests) +| * 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 (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. + +This format is a list of arbitrary records of the form: + +[type][length][content] + +`type` is a single character, `length` is a 4 byte integer, and +`content` is an arbitrary byte sequence of length `length`. + +Mercurial versions prior to 3.7 have a bug where if there are +unsupported mandatory merge records, attempting to clear out the merge +state with hg update --clean or similar aborts. The 't' record type +works around that by writing out what those versions treat as an +advisory record, but later versions interpret as special: the first +character is the 'real' record type and everything onwards is the data.