Patchwork D6966: shelve: add method for storing mergestate in changeset extras

login
register
mail settings
Submitter phabricator
Date Oct. 4, 2019, 8:44 p.m.
Message ID <differential-rev-PHID-DREV-jbbwooryfjdqvzpbdkai-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/41959/
State New
Headers show

Comments

phabricator - Oct. 4, 2019, 8:44 p.m.
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/D6966

AFFECTED FILES
  mercurial/shelve.py

CHANGE DETAILS




To: navaneeth.suresh, #hg-reviewers
Cc: mercurial-devel
phabricator - Oct. 5, 2019, 4:14 a.m.
martinvonz added inline comments.

INLINE COMMENTS

> shelve.py:61
> +_pack = struct.pack
> +_unpack = struct.unpack
> +

Seems unused

> shelve.py:73-112
> +# 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'

Most of these seem unused. I would prefer if they were added in a later patch where they are used

> shelve.py:475
> +            key, data = RECORD_OVERRIDE, '%s%s' % (key, data)
> +        format = '>sI%is' % len(data)
> +        mergedata = ''.join([mergedata, _pack(format, key, len(data), data)])

need a `r''` prefix here for py3?

> shelve.py:476
> +        format = '>sI%is' % len(data)
> +        mergedata = ''.join([mergedata, _pack(format, key, len(data), data)])
> +    extra['mergerecords'] = mergedata

`''.join(a,b)` can be written more simply as `a + b`

> shelve.py:478
> +    extra['mergerecords'] = mergedata
> +    ms.reset()
> +

This seems surprising in this method. Consider moving it out.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6966/new/

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

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

Patch

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@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)