Patchwork [1,of,3] merge: add state extras merge state data

login
register
mail settings
Submitter Durham Goode
Date Jan. 7, 2016, 1:40 a.m.
Message ID <dc35478efbae806fcee1.1452130806@dev8486.prn1.facebook.com>
Download mbox | patch
Permalink /patch/12585/
State Superseded
Commit 4a25e91fa55d66b0fcef586d36e54772878cd3cc
Delegated to: Martin von Zweigbergk
Headers show

Comments

Durham Goode - Jan. 7, 2016, 1:40 a.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1452130474 28800
#      Wed Jan 06 17:34:34 2016 -0800
# Node ID dc35478efbae806fcee1449f27b1b92d00d14853
# Parent  b8405d739149cdd6d8d9bd5e3dd2ad8487b1f09a
merge: add state extras merge state data

In future commits we will want to store more data related to each file in the
merge state. This patch adds an optional record for storing a dictionary of
extras for each file.
Siddharth Agarwal - Jan. 12, 2016, 8:57 p.m.
On 1/6/16 17:40, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham@fb.com>
> # Date 1452130474 28800
> #      Wed Jan 06 17:34:34 2016 -0800
> # Node ID dc35478efbae806fcee1449f27b1b92d00d14853
> # Parent  b8405d739149cdd6d8d9bd5e3dd2ad8487b1f09a
> merge: add state extras merge state data
>
> In future commits we will want to store more data related to each file in the
> merge state. This patch adds an optional record for storing a dictionary of
> extras for each file.
>
> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -64,6 +64,7 @@ class mergestate(object):
>          (experimental)
>       m: the external merge driver defined for this merge plus its run state
>          (experimental)
> +    f: a (filename, dictonary) tuple of optional values for a given file
>       X: unsupported mandatory record type (used in tests)
>       x: unsupported advisory record type (used in tests)
>   
> @@ -101,6 +102,7 @@ class mergestate(object):
>   
>       def reset(self, node=None, other=None):
>           self._state = {}
> +        self._stateextras = {}
>           self._local = None
>           self._other = None
>           for var in ('localctx', 'otherctx'):
> @@ -125,6 +127,7 @@ class mergestate(object):
>           of on disk file.
>           """
>           self._state = {}
> +        self._stateextras = {}
>           self._local = None
>           self._other = None
>           for var in ('localctx', 'otherctx'):
> @@ -151,6 +154,16 @@ class mergestate(object):
>               elif rtype in 'FDC':
>                   bits = record.split('\0')
>                   self._state[bits[0]] = bits[1:]
> +            elif rtype == 'f':
> +                filename, rawextras = record.split('\0', 1)
> +                extraparts = rawextras.split('\0')
> +                extras = {}
> +                i = 0
> +                while i < len(extraparts):
> +                    extras[extraparts[i]] = extraparts[i + 1]
> +                    i += 2
> +
> +                self._stateextras[filename] = extras
>               elif not rtype.islower():
>                   unsupported.add(rtype)
>           self._results = {}
> @@ -335,6 +348,10 @@ class mergestate(object):
>                   records.append(('C', '\0'.join([d] + v)))
>               else:
>                   records.append(('F', '\0'.join([d] + v)))
> +        for filename, extras in self._stateextras.iteritems():
> +            rawextras = '\0'.join('%s\0%s' % (k, v) for k, v in
> +                                  extras.iteritems())

Please please please sort this.

> +            records.append(('f', '%s\0%s' % (filename, rawextras)))
>           return records
>   
>       def _writerecords(self, records):
> @@ -422,6 +439,9 @@ class mergestate(object):
>               if entry[0] == 'd':
>                   yield f
>   
> +    def extras(self, filename):
> +        return self._stateextras.setdefault(filename, {})
> +
>       def _resolve(self, preresolve, dfile, wctx, labels=None):
>           """rerun merge process for file path `dfile`"""
>           if self[dfile] in 'rd':
> @@ -461,6 +481,7 @@ class mergestate(object):
>           if r is None:
>               # no real conflict
>               del self._state[dfile]
> +            self._stateextras.pop(dfile, None)
>               self._dirty = True
>           elif not r:
>               self.mark(dfile, 'r')
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -64,6 +64,7 @@  class mergestate(object):
        (experimental)
     m: the external merge driver defined for this merge plus its run state
        (experimental)
+    f: a (filename, dictonary) tuple of optional values for a given file
     X: unsupported mandatory record type (used in tests)
     x: unsupported advisory record type (used in tests)
 
@@ -101,6 +102,7 @@  class mergestate(object):
 
     def reset(self, node=None, other=None):
         self._state = {}
+        self._stateextras = {}
         self._local = None
         self._other = None
         for var in ('localctx', 'otherctx'):
@@ -125,6 +127,7 @@  class mergestate(object):
         of on disk file.
         """
         self._state = {}
+        self._stateextras = {}
         self._local = None
         self._other = None
         for var in ('localctx', 'otherctx'):
@@ -151,6 +154,16 @@  class mergestate(object):
             elif rtype in 'FDC':
                 bits = record.split('\0')
                 self._state[bits[0]] = bits[1:]
+            elif rtype == 'f':
+                filename, rawextras = record.split('\0', 1)
+                extraparts = rawextras.split('\0')
+                extras = {}
+                i = 0
+                while i < len(extraparts):
+                    extras[extraparts[i]] = extraparts[i + 1]
+                    i += 2
+
+                self._stateextras[filename] = extras
             elif not rtype.islower():
                 unsupported.add(rtype)
         self._results = {}
@@ -335,6 +348,10 @@  class mergestate(object):
                 records.append(('C', '\0'.join([d] + v)))
             else:
                 records.append(('F', '\0'.join([d] + v)))
+        for filename, extras in self._stateextras.iteritems():
+            rawextras = '\0'.join('%s\0%s' % (k, v) for k, v in
+                                  extras.iteritems())
+            records.append(('f', '%s\0%s' % (filename, rawextras)))
         return records
 
     def _writerecords(self, records):
@@ -422,6 +439,9 @@  class mergestate(object):
             if entry[0] == 'd':
                 yield f
 
+    def extras(self, filename):
+        return self._stateextras.setdefault(filename, {})
+
     def _resolve(self, preresolve, dfile, wctx, labels=None):
         """rerun merge process for file path `dfile`"""
         if self[dfile] in 'rd':
@@ -461,6 +481,7 @@  class mergestate(object):
         if r is None:
             # no real conflict
             del self._state[dfile]
+            self._stateextras.pop(dfile, None)
             self._dirty = True
         elif not r:
             self.mark(dfile, 'r')