Patchwork [1,of,2,V3] dirstate: add callback to notify extensions about wd parent change

login
register
mail settings
Submitter Mateusz Kwapich
Date Aug. 11, 2016, 3:02 p.m.
Message ID <ab4af8f1ddcae13159ed.1470927734@dev3277.prn1.facebook.com>
Download mbox | patch
Permalink /patch/16251/
State Accepted
Headers show

Comments

Mateusz Kwapich - Aug. 11, 2016, 3:02 p.m.
# HG changeset patch
# User Mateusz Kwapich <mitrandir@fb.com>
# Date 1470927641 25200
#      Thu Aug 11 08:00:41 2016 -0700
# Node ID ab4af8f1ddcae13159edf3eeea9fa4358c93babf
# Parent  5e2365698d448c2a1d75f6a58e11ec65f66a0266
dirstate: add callback to notify extensions about wd parent change

The journal extension had to touch the dirstate internals to be notified about
wd parent change. To make that detection cleaner and reusable let's move it core.
Now the extension can register to be notified about parent changes.
Yuya Nishihara - Aug. 12, 2016, 12:11 a.m.
On Thu, 11 Aug 2016 08:02:14 -0700, Mateusz Kwapich wrote:
> # HG changeset patch
> # User Mateusz Kwapich <mitrandir@fb.com>
> # Date 1470927641 25200
> #      Thu Aug 11 08:00:41 2016 -0700
> # Node ID ab4af8f1ddcae13159edf3eeea9fa4358c93babf
> # Parent  5e2365698d448c2a1d75f6a58e11ec65f66a0266
> dirstate: add callback to notify extensions about wd parent change

Queued the series, thanks.

>      def _writedirstate(self, st):
> +        # notify callbacks about parents change
> +        if self._origpl is not None and self._origpl != self._pl:
> +                for c, callback in sorted(self._plchangecallbacks.iteritems()):
> +                    callback(self, self._origpl, self._pl)
> +                self._origpl = None

Fixed excessive indent.

Patch

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -101,6 +101,8 @@  class dirstate(object):
         self._parentwriters = 0
         self._filename = 'dirstate'
         self._pendingfilename = '%s.pending' % self._filename
+        self._plchangecallbacks = {}
+        self._origpl = None
 
         # for consistent view between _pl() and _read() invocations
         self._pendingmode = None
@@ -347,6 +349,8 @@  class dirstate(object):
 
         self._dirty = self._dirtypl = True
         oldp2 = self._pl[1]
+        if self._origpl is None:
+            self._origpl = self._pl
         self._pl = p1, p2
         copies = {}
         if oldp2 != nullid and p2 == nullid:
@@ -442,6 +446,7 @@  class dirstate(object):
         self._lastnormaltime = 0
         self._dirty = False
         self._parentwriters = 0
+        self._origpl = None
 
     def copy(self, source, dest):
         """Mark dest as a copy of source. Unmark dest if source is None."""
@@ -687,6 +692,8 @@  class dirstate(object):
                 if f in self._nonnormalset:
                     self._nonnormalset.remove(f)
 
+        if self._origpl is None:
+            self._origpl = self._pl
         self._pl = (parent, nullid)
         self._dirty = True
 
@@ -721,7 +728,23 @@  class dirstate(object):
         st = self._opener(filename, "w", atomictemp=True, checkambig=True)
         self._writedirstate(st)
 
+    def addparentchangecallback(self, category, callback):
+        """add a callback to be called when the wd parents are changed
+
+        Callback will be called with the following arguments:
+            dirstate, (oldp1, oldp2), (newp1, newp2)
+
+        Category is a unique identifier to allow overwriting an old callback
+        with a newer callback.
+        """
+        self._plchangecallbacks[category] = callback
+
     def _writedirstate(self, st):
+        # notify callbacks about parents change
+        if self._origpl is not None and self._origpl != self._pl:
+                for c, callback in sorted(self._plchangecallbacks.iteritems()):
+                    callback(self, self._origpl, self._pl)
+                self._origpl = None
         # use the modification time of the newly created temporary file as the
         # filesystem's notion of 'now'
         now = util.fstat(st).st_mtime & _rangemask