D6967: shelve: add method for storing mergestate in changeset extras

navaneeth.suresh (Navaneeth Suresh) phabricator at mercurial-scm.org
Fri Oct 4 20:47:05 UTC 2019


navaneeth.suresh created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  We store mergestate records in `.hg/merge`. This patch adds a method
  of storage in changeset extras. This will help in the exchange of
  mergestate records to other repos. Also, this can be used by
  `shelve --unresolved` to store the mergestate records.
  
  It uses the storage format supported for hg versions 3.7 or later. For the
  time being, I have omitted the storage of the content of the local version
  of unresolved files.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D6967

AFFECTED FILES
  mercurial/shelve.py

CHANGE DETAILS

diff --git a/mercurial/shelve.py b/mercurial/shelve.py
--- a/mercurial/shelve.py
+++ b/mercurial/shelve.py
@@ -26,6 +26,7 @@
 import errno
 import itertools
 import stat
+import struct
 
 from .i18n import _
 from . import (
@@ -56,6 +57,9 @@
     stringutil,
 )
 
+_pack = struct.pack
+_unpack = struct.unpack
+
 backupdir = 'shelve-backup'
 shelvedir = 'shelved'
 shelvefileextensions = ['hg', 'patch', 'shelve']
@@ -66,6 +70,47 @@
 # generic user for all shelve operations
 shelveuser = 'shelve at localhost'
 
+# Merge state record types. See ``mergestate`` docs for more.
+RECORD_LOCAL = b'L'
+RECORD_OTHER = b'O'
+RECORD_MERGED = b'F'
+RECORD_CHANGEDELETE_CONFLICT = b'C'
+RECORD_MERGE_DRIVER_MERGE = b'D'
+RECORD_PATH_CONFLICT = b'P'
+RECORD_MERGE_DRIVER_STATE = b'm'
+RECORD_FILE_VALUES = b'f'
+RECORD_LABELS = b'l'
+RECORD_OVERRIDE = b't'
+RECORD_UNSUPPORTED_MANDATORY = b'X'
+RECORD_UNSUPPORTED_ADVISORY = b'x'
+
+MERGE_DRIVER_STATE_UNMARKED = b'u'
+MERGE_DRIVER_STATE_MARKED = b'm'
+MERGE_DRIVER_STATE_SUCCESS = b's'
+
+MERGE_RECORD_UNRESOLVED = b'u'
+MERGE_RECORD_RESOLVED = b'r'
+MERGE_RECORD_UNRESOLVED_PATH = b'pu'
+MERGE_RECORD_RESOLVED_PATH = b'pr'
+MERGE_RECORD_DRIVER_RESOLVED = b'd'
+
+ACTION_FORGET = b'f'
+ACTION_REMOVE = b'r'
+ACTION_ADD = b'a'
+ACTION_GET = b'g'
+ACTION_PATH_CONFLICT = b'p'
+ACTION_PATH_CONFLICT_RESOLVE = b'pr'
+ACTION_ADD_MODIFIED = b'am'
+ACTION_CREATED = b'c'
+ACTION_DELETED_CHANGED = b'dc'
+ACTION_CHANGED_DELETED = b'cd'
+ACTION_MERGE = b'm'
+ACTION_LOCAL_DIR_RENAME_GET = b'dg'
+ACTION_DIR_RENAME_MOVE_LOCAL = b'dm'
+ACTION_KEEP = b'k'
+ACTION_EXEC = b'e'
+ACTION_CREATED_MERGE = b'cm'
+
 class shelvedfile(object):
     """Helper for the file storing a single shelve
 
@@ -413,6 +458,25 @@
         cmdutil.exportfile(repo, [node], fp, opts=mdiff.diffopts(git=True),
                            match=match)
 
+def _storeunresolvedmerge(ui, repo, name=None, extra=None):
+    """Store the mergestate information in changeset extra
+
+    This will clear the mergestate and also stores the mergestate
+    information for later restoration.
+    """
+    ms = merge.mergestate.read(repo)
+    records = ms._readrecords()
+    allowlist = (RECORD_LOCAL, RECORD_OTHER, RECORD_MERGED)
+    mergedata = ''
+    for key, data in records:
+        assert len(key) == 1
+        if key not in allowlist:
+            key, data = RECORD_OVERRIDE, '%s%s' % (key, data)
+        format = '>sI%is' % len(data)
+        mergedata = ''.join([mergedata, _pack(format, key, len(data), data)])
+    extra['mergerecords'] = mergedata
+    ms.reset()
+
 def _includeunknownfiles(repo, pats, opts, extra):
     s = repo.status(match=scmutil.match(repo[None], pats, opts),
                     unknown=True)



To: navaneeth.suresh, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list