[PATCH 1 of 3 RFC] scmutil: introduce the flagstate class to suppliment missing flag support
Matt Mackall
mpm at selenic.com
Fri Jul 8 15:44:43 EDT 2016
On Wed, 2016-07-06 at 22:58 -0400, Matt Harbison wrote:
> On Wed, 06 Jul 2016 13:35:44 -0400, Matt Mackall <mpm at selenic.com> wrote:
>
> >
> > On Sun, 2016-07-03 at 17:44 -0400, Matt Harbison wrote:
> > >
> > > # HG changeset patch
> > > # User Matt Harbison <matt_harbison at yahoo.com>
> > > # Date 1467571904 14400
> > > # Sun Jul 03 14:51:44 2016 -0400
> > > # Node ID e9fce4275ce6b26b941f47044744015e90367e7b
> > > # Parent de4a80a2b45c6fcae0948ac12872dd8a61ced26a
> > > scmutil: introduce the flagstate class to suppliment missing flag
> > > support
> > >
> > > This will allow manipulation of the executable bit when filesystems
> > > don't
> > > track
> > > it natively. This file isn't tracked in any form, and will likely be
> > > small
> > > since it can be purged completely when wdir is cleaned- the manifest
> > > tracks
> > > the
> > > flags in permanent history. It is intended only for platforms that
> > > don't have
> > > native flag support, and will noop on platforms that do for simplicity.
> > > Obviously a tree copy in either direction between filesystems with and
> > > without
> > > flag support will lose the flag state, but that seems like an edge case
> > > that
> > > isn't worth having two sources of data that can get out of sync on Unix.
> > >
> > > We could in theory also support designating a file as a symlink, so I
> > > kept
> > > this
> > > generic. Since the file isn't tracked, and the flags are stored
> > > symbolically,
> > > it should be extensible without changing the file format. So I didn't
> > > bother
> > > with a version identifier. I have no idea if there would be any
> > > encoding
> > > concerns (I saw references to encode/decode in the fncache class when I
> > > was
> > > trying to find a suitable bit of code to model), but I wouldn't think
> > > so.
> > No, filenames are not (re-)encoded.
> >
> > >
> > >
> > > I couldn't find an existing suitable file format, and I really wanted
> > > to just
> > > munge the flags on dirstate to get `commit`, `update -C` and `revert`
> > > handling
> > > for free. But dirstate doesn't know about the flag building function
> > > used in
> > > context.py,
> > That's intentional, because context is at a higher abstraction level.
> > Dirstate
> > doesn't even know that Mercurial only recognizes two mode bits and
> > stores 32.
> >
> > >
> > > and seems to be populated by what the OS reports, though I couldn't
> > > figure out where exactly.
> > Here: https://www.selenic.com/hg/file/tip/mercurial/dirstate.py#l493
> >
> > Note the call to stat and how the results are passed on to _addpath.
> Thanks. I saw the former, but missed that _addpath was setting _dirty, so
> the changes weren't being written. That made me think something somewhere
> else was also setting this mode.
>
> >
> > Note also the trick we do with the _rangemask to deal with weird sizes
> > and
> > times. We could use a similar trick on the mode field to get some
> > protected bits
> > for storing our virtual mode bits.
> >
> > >
> > > I wasn't looking to do a dirstate transaction with this, but the tests
> > > were
> > > totally unstable from run to run without the normallookup() call. I'm
> > > not
> > > sure
> > > if we need to backup the file, but that's what the fncache code was
> > > doing.
> > Whether or not this is part of the dirstate file, it's logically a
> > dirstate
> > transaction. Getting it into the dirstate proper will avoid a number of
> > headaches.
> Agreed. One of the headaches with dirstate (or any tracking file), is how
> to handle {util,vfs}.setflags(). It seems wrong that either would know
> about dirstate (or another file). In my functioning dirstate based WIP, I
> changed localrepo.wwrite() so that `update -C` and `revert` end up with
> the proper bits:
>
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -988,6 +988,7 @@
> self.wvfs.write(filename, data,
> backgroundclose=backgroundclose)
> if 'x' in flags:
> self.wvfs.setflags(filename, False, True)
> + self.dirstate.setflags(filename, False, 'x' in flags)
> return len(data)
>
> def wwritedata(self, filename, data):
>
> But it also seems wrong that setflags has to be called on two different
> things side by side.
This isn't so horrible. This is a pretty good bottleneck for callers of setflags
and it's at the right level.
It also wouldn't be horrible to conditionally use a derived class of the vfs
that knew about dirstate for wvfs. This would reduce overhead for non-Windows
machines.
We're going to eventually need such a class for https://www.mercurial-scm.org/wi
ki/WindowsUTF8Plan anyway.
> OTOH, there are places where dirstate will never be
> available (like convert's svn sink). Thoughts?
> >
> > --Mathematics is the supreme nostalgia of our time.
--
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel
mailing list