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

Pierre-Yves David pierre-yves.david at ens-lyon.org
Mon Aug 8 18:53:49 EDT 2016



On 08/08/2016 08:47 PM, Mateusz Kwapich wrote:
> # HG changeset patch
> # User Mateusz Kwapich <mitrandir at fb.com>
> # Date 1470681797 25200
> #      Mon Aug 08 11:43:17 2016 -0700
> # Node ID e7d2b86e2ee35fcb7b4e6ef6a4d0c6f696331f42
> # 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.
>
> 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._parentchangecallbacks = []

Usually we make the calldate a dictionary. This allow reentrant code or 
extension to overwrite a callbacks when needed. This also allow to use 
the key to determine the run order.

You can look at transaction.addpostclose for example.

We might consider using '_plchangecallbacks' as '_pl' is commonly used 
in this class. This would keep the variable name on check.

> +        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."""
> @@ -721,7 +726,16 @@ class dirstate(object):
>          st = self._opener(filename, "w", atomictemp=True, checkambig=True)
>          self._writedirstate(st)
>
> +    def addparentchangecallback(self, callback):
> +        self._parentchangecallbacks.append(callback)
> +
>      def _writedirstate(self, st):
> +        # notify callbacks about parents change
> +        if self._origpl is not None:
> +            if self._origpl != self._pl:
The two 'if' should be grouped into a single one.

> +                for callback in self._parentchangecallbacks:
> +                    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

Cheers,

-- 
Pierre-Yves David


More information about the Mercurial-devel mailing list