The FAQ answer is weazeling on several accounts:
a) No, git only cares about files, or rather git tracks content and
empty directories have no content.
In the same manner as empty regular files have no contents, and git
tracks those. Existence and permissions are important.
b) The problem is not just that empty directories don't get added into
the repository. They also don't get removed again when switching to a
different checkout. When git-diff returns zero, I expect a subsequent
checkout to not leave complete empty hierarchies around because git
can't delete any empty leaves which it chose not to track.
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:43:22
Hi,
On Wed, 18 Jul 2007, David Kastrup wrote:
The FAQ answer is weazeling on several accounts:
a) No, git only cares about files, or rather git tracks content and
empty directories have no content.
In the same manner as empty regular files have no contents, and git
tracks those. Existence and permissions are important.
We do not track permissions of directories at all. This is because Git is
primarily meant to track source code, and most "permissions" (i.e.
restrictions) do not make any sense there.
b) The problem is not just that empty directories don't get added into
the repository. They also don't get removed again when switching to a
different checkout. When git-diff returns zero, I expect a subsequent
checkout to not leave complete empty hierarchies around because git
can't delete any empty leaves which it chose not to track.
I _like_ the behaviour that Git does not remove a directory it added, when
I put some untracked file into it. And switching back to that branch, Git
has no problems, because it sees that the directory is already there. In
case of a file, it would complain, and rightfully so.
See the fundamental difference between a file and a directory now? I
think it boils down to "an empty directory has _no_ contents, but an empty
file has an _empty_ content".
Ciao,
Dscho
In the same manner as empty regular files have no contents, and git
tracks those. Existence and permissions are important.
Yes, but directories really are different.
First off, git wouldn't track the permissions anyway (git tracks execute
bits, but for directories that _has_ to be set or git couldn't use them
itself, so that's not going to happen).
Second, and much more important, the directories will exist or not
*regardless* of what git does.
b) The problem is not just that empty directories don't get added into
the repository. They also don't get removed again when switching to a
different checkout.
Bzzt. Wrong.
We *do* remove directories when all files under them go away.
HOWEVER (and this is where one of the reasons for not tracking them comes
in):
** YOU CANNOT REMOVE A DIRECTORY IF IT HAS SOME UNTRACKED CONTENTS **
Think about that for five seconds, then think about it some more. Ponder
it.
So the fact is, git *already* does ass good of a job as it could possibly
do wrt directories that go away: it tries to remove them if all the files
that are tracked in it have gone away.
But that leaves a very common case, namely switching to another branch
without those files, and the directory still having stale object files etc
build crud in it.
A SCM *must*not* just remove that directory. It would be horrible. The
fact that it has untracked files in it does not make those untracked files
"unimportant". Maybe you feel that way about object files, but what about
tracking some important parts of your home directory - does the fact that
you don't necessarily track *all* of it mean that the rest is totally
unimportant adn that git should just remove it? HELL NO!
So directories really _are_ problematic. You cannot (and should not) track
them the same way as you track a file.
And the difference is very fundamental indeed: when you track a regular
file, you track *all* of its content. But when you track a directory,
you don't track it's content *at*all*.
Think about that, and then think about the fact that git is defined as a
"content tracker", and it's not "weasely" at all to say that you don't
track directories.
So your argument is totally bogus. When you track an empty file, you very
much track the *content* of that file, and "empty" just happens to be a
very valid content.
But when you track a "directory", you don't actually track its content at
all, you track it's *existence*, which is a very very very different
thing. I hope you understand from the above what is so different.
(A true "directory content" tracker by definition would have to track
every single file under that directory. You can claim that for the case of
an empty directory the "existence tracking" is 100% equivalent with
"content tracking", but that's simply not true. It becomes non-true the
moment there are any files at all inside that directory, and be honest
now: the only _point_ of an empty directory is that you expect it to
potentially get files under it).
So "existence" != "content". Git very much does not track "existence" of
files, it tracks the total content of them too.
Linus
So "existence" != "content". Git very much does not track "existence" of
files, it tracks the total content of them too.
Btw, don't get me wrong: I think that in order to be better at tracking
other SCM's idiotic choices, we could (and I foresee that we eventually
have to) try to track empty directories as a special case too.
So I'm not _against_ the notion of tracking empty directories, and I would
welcome patches that do so. As I mentioned in some earlier thread when
this came up a few weeks ago, I actually suspect that the "subproject"
support probably ended up making it easier, because in many ways an "empty
directory" is very close to a "anonymous subproject" from a low-level
plumbing standpoint (even if it is *not* so from a high-level standpoint).
So I suspect that adding support for empty directories ends up being about
just slightly extending the places that now have subproject support to
know about a new situation.
But I do want to point out that "tracking a directory" is not at all the
same thing as "tracking a file", no matter how much you try to argue
otherwise. The semantics are totally different, and it all boils down to
the fact that when you track a file, you are always talking about the
*full* content of the file, while tracking a directory is always about
tracking just a *subset* of the contents of the directory.
Of course, with directories, there's the trivial case where the subset
happens to be everything, but that is neither the common nor the
interesting case. All the interesting and complex cases happen exactly
when the directory has untracked files in it, and at that point
- you really aren't tracking "contents" any more
- you can no longer recreate the directory from the data you have (so you
cannot remove it on branch switches etc)
- ergo: you're not a content tracker any more, you're a "container"
tracker.
And really, the "nontracked files in a directory" is the *default* thing,
not some really unusual thing that we could disallow.
But I'm not against adding support for "container tracking". I just want
people to understand that it's something totally different from what we do
now. It's much more like subproject support than tracking files.
Linus