A simpler approach to tracking directories (was: The philosophy behind my directory proposal in a nutshell)

3 messages, 3 authors, 2016-06-15 · open the first message on its own page

A simpler approach to tracking directories (was: The philosophy behind my directory proposal in a nutshell)

From: David Kastrup <hidden>
Date: 2016-06-15 22:43:23

Ok, I've gotten enough flak for my first proposal that it is clear
that it is rather irrelevant whether it would work (of which I remain
convinced) or not.  Now I also have been of the opinion that it was
perfectly easy to understand and embrace, and the amount, content and
tone of responses have made very obvious that I have been quite wrong
about _that_ at least.

The good thing is that among all the flamage there have been actually
some people who went to the pain of actually reviewing the proposed
changes and give feedback about their relative feasibility in the
current code base.  This has helped more than the reflections on my
sanity, I am glad to say.

So here we go:

I think there has been some vague consensus with the notion that it
does not make sense to track whether or not a directory _is_ empty at
the time of checkin (when checking in files below it, it _can't_ be),
but rather whether it should be automatically added and removed by git
based on the files in it alone.

The current state of affairs with git is that directories are
exclusively a mechanism for accommodating hierarchical filenames.
Consequently, the index does not need to know about them.

Anyway, here is the basic idea: git is already capable of tracking
file permissions (though at the current point of time, this is
somewhat artificially limited to the u+x bit), so there are basic
mechanisms in place for passing the respective bits through.

Now my proposal basically boils down to using the u+x bit on
directory/tree entries for tracking "keep around when empty".

I think we are on the safe side to assume a directory with access
permissions zero (a-rwx) is something we never want to be able to
track with git.  So this special value, which I think is the current
default, can express "delete when empty".  Personally I believe that
git can be made without problems to track more permissions (possibly
by configuring an appropriate mask for the project) than it currently
does, but that's not relevant for now: it is sufficient to use
permissions a-rwx for an automatically managed (=evaporate when empty)
tree/directory, and 755 for a manually managed (=stay around)
tree/directory without actually calling lstat for now.

Apart from needing to accommodate directories in the index (since they
are now associated with 1 instead of 0 bits of information), this will
work with the current data structures and protocols.  Patches and
diffs can encode the change between tracked and untracked directories
as a change in the permissions of the directory.

So this obliterates the need to distinguish trees from directories
using actually separate and separately listed repository entries,
hopefully removing the main stumbling block.

It also addresses the concern of a tree's SHA1 changing when its
evaporate-when-empty-ness changes.  It also will not lead to dangerous
situations on systems attempting to replace or delete "." as a regular
file.

So it has several technical advantages over my previous proposal, and
I _think_ it may be easier to understand and lead to less
contraintuitive behavior.

Now for deciding about _when_ to track a directory or not, I think
that the following part of the previous proposal was workable:

A directory's permission should be tracked in the same situations that
a file's permissions get tracked: that is if either the directory has
_explicitly_ been added to a commit, or it is _implicitly_ part of a
complete tree added into a commit.  For implicitly indicated _files_,
whether or not they become tracked depends on the gitignore mechanism.
I think asking the gitignore mechanism whether the pattern "." in a
given directory is worth tracking is a good way of deciding implicit
inclusion, falling back onto a "core.dirtrack" or similar variable
that has some vague analogy to the "core.filemode" variable.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

Re: A simpler approach to tracking directories (was: The philosophy behind my directory proposal in a nutshell)

From: Theodore Tso <tytso@mit.edu>
Date: 2016-06-15 22:43:23

On Sun, Jul 22, 2007 at 05:39:06PM +0200, David Kastrup wrote:
Now my proposal basically boils down to using the u+x bit on
directory/tree entries for tracking "keep around when empty".

I think we are on the safe side to assume a directory with access
permissions zero (a-rwx) is something we never want to be able to
track with git.
Ok, so I think you are still missing the fundamental issue about why
Linus is upset with your proposals.  One of the fundamental things
which falls out of the "Git Tracks Contents" mantra is that
information which you expect to be pushed forward future revisions (as
opposed to metadata which is specific to a commit, such as the Author
and Committer of a patch, the Commit log, etc.) *MUST* be information
which is realized in the working tree.

That way, if you diff between working trees, one of which has either
your "." entry or your "u+x" bit, and of which doesn't, they need to
be *different* when run "git diff" on the two working trees.

Another way of putting is this single bit of information meaning "keep
this directory around when empty" is something that ***must*** be
representable in three different places: in a git tree object, in the
index, *AND* in the working tree.  The problem with "." is that since
all directories contain the "." entry, you can't represent the bit of
information you want to record in the working tree in that way.

There is a same problem with using the u+x permission, for the same
reason.  Unless you want to make directories you want to keep around
with access permissions of zero in the working tree, you're *still*
not able to record presence or absence of the "keep around when empty
bit" in the working tree.

That's why the ".gitignore" entry is acceptable, where as your
proposals are not.  The absence or presence of the ".gitignore" entry
in the working tree is a natural way of representing the "keep around
when empty".  So would a ".do_not_erase" file in the directory ---
sort of like the "Do Not Erase" that professors would write on
whiteboards in order to request janitors to not erase them.  It seems
that you are objecting to having something tangible written on the
whiteboard --- or, in the directory, to indicate the "do not erase"
note.   

But the problem is that Linus very much wants the "do not erase" bit
to be visible in the working directory, since to do otherwise would
violate fundamental design assumptions all over the git source files.
Metadata such as the executable bit is actually stored in the working
directory.  But we can't store the "do not erase bit" by leaving the
executable permission off, since that will prevent the directory from
being useful.

So your new proposal suffers from the same fundamental flaw as your
previous one.  

Maybe you disagree with Linus's design constraint, but you've never
addressed his specific concern on-point, which is that since Git
Tracks Content, if you want something to be tracked across revisions,
it must be visible in the working tree.  That is, metadata in the
sense of data which is not visible in the working tree, is not allowed
to exist inside Git and carried across revisions.  So fundamentally,
Git does not currently today support "svn propset" in terms of setting
metadata on a particular file which isn't visible in the working tree.

With SVN, today you can use svn propset to what you could think of as
extended attributes.  So one proposal that you *could* try proposing
is using extended attributes to represent arbitrary properties,
including the one which you want, which is the "do not erase"
property.  And one of the arguments might be that this way we could
better preserve arbitrary properties currently set inside SVN, so that
such repository could be faithfully translated into a Git repository.  

The problem with such a proposal is that it now requires that the
filesystem used to store the working directory MUST support extended
attributes, and some filesystems, such as FAT filesystems, do not.
And Git already has been accused of not being Windows friendly enough,
and this would make things worse.

It's also a lot of hair for two very marginal features, namely being
able to support arbitrary SVN property values, and the "do not erase
when empty" directory bit.  Personally, I don't htink it's worth it,
but at least using filesystem xattrs to store that one bit of
information would at least be faithful to the fundamental git design
principal.

Regards,

						- Ted

Re: A simpler approach to tracking directories (was: The philosophy behind my directory proposal in a nutshell)

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:43:23

Theodore Tso wrote:
Another way of putting is this single bit of information meaning "keep
this directory around when empty" is something that ***must*** be
representable in three different places: in a git tree object, in the
index, *AND* in the working tree.  The problem with "." is that since
all directories contain the "." entry, you can't represent the bit of
information you want to record in the working tree in that way.
I don't think the "do not delete when empty" bit must be somehow represented
in the working directory. It is enough to have this bit in index to deal
with working directory, and in the repository to have it persistent.

Compare with submodules, and with unmerged entries (which sometimes do not
have worktree representation).

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help