{"thread":{"id":"9129","subject":"The philosophy behind my directory proposal in a nutshell","startedAt":"2007-07-21T22:22:18Z","lastAt":"2007-07-22T21:45:40Z","messageCount":7,"participants":["David Kastrup","Theodore Tso","Jakub Narebski","J. Bruce Fields"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"48063","messageId":"85fy3hqtwl.fsf@lola.goethe.zz","threadId":"9129","inReplyTo":null,"subject":"The philosophy behind my directory proposal in a nutshell","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-07-21T22:22:18Z","receivedAt":"2007-07-21T22:22:18Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"\nOk, a big nut.\n\nMany people have lost track since I developed the idea over dozens of\npostings and so I have been explaining only details instead of the\nactual picture.\n\nLet us assume we habe the following files in the work tree (there is a\nreason for starting off with / always in this discussion):\n\n/i/never/saw/this\n/i/never/should/have\n/i/would/have\n\nNow it is obvious that we _also_ have the directories (which I'll call\nby their proposed git name):\n\n/i/never/saw/.\n/i/never/should/.\n/i/never/.\n/i/would/.\n/i/.\n/.\n\nGit does right now not track any of them.  It _induces_ their\nexistence through trees in the repository.  Let us call the _trees_ in\nthe following way:\n\n/i/never/saw/\n/i/never/should/\n/i/never/\n/i/would/\n/i/\n/\n\n[The last line here is the reason we prepended / everywhere: it makes\nthe root tree more apparent].\n\nAll those _trees_ are just string prefixes of file names, and those\nprefixes are without a physical existence.  But if we check out the\nfiles, we need to create directories to accommodate them.  And for\nefficiency reasons, we call every prefix occuring in the flat file\nlist ending in / a \"tree\" and give it an SHA1 value.\n\nNow when do we remove a directory that is in the work filesystem?\nWhen the corresponding tree (=prefix) in the repository becomes empty,\nnamely the prefix becomes unused, the tree evaporates.  At that\nmoment, git has lost the necessity for keeping the directory around,\nand attempts to remove it.  If the attempt does not succeed, something\noutside of git is using the directory.  At this point removing the\ndirectory becomes somebody else's problem: git will not try again.\nThe tree is gone from the repository, so there is nothing that makes\ngit even _think_ about that directory.\n\nSo far, so well.  Quite consistent, in some cases quite convenient,\nbut not in all.  There are situations where empty directories matter.\n\nSo we want git to be able to track them.  Let us take a simple example\nfirst:\n\nmkdir a\nmkdir a/b\ntouch a/b/c\ngit add a/b/c\ngit commit\ngit rm a/b/c\ngit commit\n\nThe naive expectation would be that the directories made by the user\nwill not get touched by git.  Trying to implement anything like a \"git\nremoves only directories it created itself\" would be insane, and here\nis why: the user actually has no _chance_ not to create those\ndirectories before checking the files in.  And there is no way to\ndeduce whether he did it on behalf of git or because of some other\nreason.  Also it is not important _how_ the directory got created: git\ntracks states, not responsibilities.\n\nSo this case _must_ behave the same: after the first commit, we have\n/a/b/c in the repository as the only file, and it induces the\nexistence of the trees\n\n/a/b\n/a\n/\n\nSo when we remove /a/b first /a collapses and evaporates (if a tree\nfalls in the repository and there is nobody to hear it...), then /\ncollapses but is kept alive because we can't remove our current work\ndirectory, not even if the repository is kept elsewhere (and actually,\n/ _is_ special after all).\n\nThis behavior _must_ stay the same, regardless of what settings we\nuse.  Now let us assume that git can be told to track directories, and\nthat the user wants to keep a around even if empty, but not\nnecessarily b.  How can he achieve this?\nmkdir a\ngit-add a\nmkdir a/b\ntouch a/b/c\ngit-add a/b/c\ngit-commit\ngit-rm a/b/c\ngit-commit\n\nNow directories come into play.  After the first git-add, the\nrepository contains the following non-volatile stuff:\n\n/a/.\n\nand in consequence it contains the trees\n\n/a/\n/\n\nas well.  The second add adds /a/b/c but nothing else, so we have\n\n/a/.\n/a/b/c\n\nand the trees\n\n/a/b/\n/a/\n/\n\nOk, so now do the git-rm and following commit.  The tree then contains\n\n/a/.\n\nand /a/b/ collapses while /a/ and / are held up by /a/. perfectly\nwell.  The collapse of /a/b/ leads to the deletion of the\ncorresponding directory in the work tree (so the collapse of a tree in\nthe repository _does_ make a sound in the work directory as long as\nsomebody is there to hear it).\n\n    [As a note aside: working directories get removed when their\n    corresponding tree collapses and disappears from the\n    repository.  I should think it only consistent if the same\n    happened with git-rm: let the file by default disappear at\n    the moment when it gets removed from the repository,\n    implying --cached.  Namely, let\n\n    git-rm some-file\n    git-add some-file\n\n    be a noop, regardless whether the file was registered\n    previously.  This also implies that git-rm will always leave\n    unregistered files alone.]\n\nSo when directory tracking is on, basically whenever adding\na directory explicitly by naming it or a parent directory in\nthe add or commit, the corresponding entry ending in \"/.\"\ngets added and keeps the tree alive even if no other file\ndoes.  And while the tree is alive, git does not touch the\ndirectory in the work tree.\n\nSo that are the basics for more or less manually adding and\nremoving directories when they are being tracked.  How do we\nlet git decide whether or not to track directories?  It\nnever tracks them if our git-add commands only mention\nfiles: in that case, the behavior is indistinguishable from\npreviously.  But if we use git-add to add directories, then\nnot just files, but also directories make it to the index\nand repository.\n\nOf course, we can have a configuration variable to set\nthis.  But this is not enough.  Fortunately, all directories\ncarry a name ending with \"/.\" in the repository, and thus we\ncan use the gitignore mechanism to make git ignore\ndirectories.\n\nSome commands accept \"ignore this\" or \"don't ignore this\" on\nthe command line, this takes highest priority.\n\nThen .gitignore files come to play in the directory\nhierarchy: those make it easy to exclude or include any\nsubtree in directory tracking by specifying the pattern \".\"\nor \"!.\".  Then $GIT_DIR/info/exclude takes effect in a\nsimilar way, another level lower core.excludesfile is\nconsulted, and at the very lowest level, if nobody else\ncares (unlikely that a project would not set forth a policy\nin $GIT_DIR/info/exclude), the users preference variable\ncore.trackdirs takes effect, defaulting to false for\ncompatibility until all projects wanting to keep directories\nout of their repository have made their wish explicit in\ntheir configuration.\n\nI hope the concept now is somewhat clearer.\n\nNow how does git _exactly_ deal with ignored files?  Ignored\nfiles basically means that git skips them when they get\nadded (unless you use -f).  However, it _does_ notice when\nthey get deleted and updates the repository correspondingly.\n\nWhat does this mean for interoperability of users with\ndifferent preferences of directory tracking?  First assume\nthat both have git versions capable of tracking directories.\nOne ignores \".\", the other doesn't.  \".\" entries will in\nthis case be removed when the non-tracker commits a\ndirectory with -a where the physical directory has\ndisappeared (and thus also all files beneath that).  That's\nreasonably harmless.  \".\" entries will be added for a\ndirectory and its subdirectories when the tracking person\ncommits a directory.\n\nNo problems here, little cause for violence.  Now what\nhappens with a \"legacy\" git?  The legacy git _never_ sees\nanything corresponding to the weird directory entries in the\nfile system.  So with every commit of a tree with -a, the\ntree gets \"corrected\" by removing the \"strange\" entries.\nThey will get added again when somebody else commits, but in\nthe mean time, empty directories might disappear.  If that\nis a problem, you should not have given a person using an\nold git commit access.  Could be worse.\n\nSo that basically wraps this up.\n\n-- \nDavid Kastrup, Kriemhildstr. 15, 44793 Bochum\n"},{"id":"48069","messageId":"85bqe5qqag.fsf@lola.goethe.zz","threadId":"9129","inReplyTo":"85fy3hqtwl.fsf@lola.goethe.zz","subject":"git-rm semantics (was: The philosophy behind my directory proposal in a nutshell)","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-07-21T23:40:23Z","receivedAt":"2007-07-21T23:40:23Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"\nFollowing up on the git-rm note:\n\n>     [As a note aside: working directories get removed when their\n>     corresponding tree collapses and disappears from the\n>     repository.  I should think it only consistent if the same\n>     happened with git-rm: let the file by default disappear at\n>     the moment when it gets removed from the repository,\n>     implying --cached.  Namely, let\n>\n>     git-rm some-file\n>     git-add some-file\n>\n>     be a noop, regardless whether the file was registered\n>     previously.  This also implies that git-rm will always leave\n>     unregistered files alone.]\n\nOk, this is somewhat incorrect: if we call git-rm and the file still\nexists, this is strictly speaking the same situation as calling\ngit-add when a file does not exist.\n\nAnd that gives:\nfatal: pathspec 'geo' did not match any files\nwhether or not the repository has an idea about the file.\n\nSo in analogy, git-rm on an existing file could possibly made to barf.\n\nAnyway, the following appears inconsistent to me:\n\ntouch geo\ngit-add geo\ngit-commit -m xxx -a\ngit-rm geo\n[Now geo is gone]\ngit-add geo\n[geo is complained about as unknown]\ngit-checkout geo\n[geo is complained about as unknown!]\n\nNow the last complaint clearly is quite a nuisance, because\ngit-checkout .\n_will_ resurrect geo.\n\nSo for consistency's sake, it would appear that git-rm should really\nonly schedule a removal, and pull through only at the moment where the\nfile is actually removed from the repository.  There is a slight\ndiscordance with git-add in that git-add requires the existence of the\nfile at the time of the add.  That is inevitable since git records the\n_contents_ of the file at the time of the add.  git-rm does not need\nany such information.\n\nNow what if a file disappears before we commit, namely\ntouch woozle\ngit add woozle\nrm woozle\n?\n\nWoozle will in that case get committed if and only if the commit is\ndone without the -a option.\n\nMakes sense.  So in a nutshell: git-rm should not look at the working\ndirectory.  That's the business of the commit.  When the repository\ncopy gets removed, this is the right time to remove the corresponding\nfile, and this is perfectly equivalent with the case for trees.\n\nWhat _is_ strange is that a git-rmed file can't be restored by naming\nit for a checkout.\n\n-- \nDavid Kastrup, Kriemhildstr. 15, 44793 Bochum\n"},{"id":"48146","messageId":"85abtola79.fsf@lola.goethe.zz","threadId":"9129","inReplyTo":"85fy3hqtwl.fsf@lola.goethe.zz","subject":"A simpler approach to tracking directories (was: The philosophy behind my directory proposal in a nutshell)","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-07-22T15:39:06Z","receivedAt":"2007-07-22T15:39:06Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"\nOk, I've gotten enough flak for my first proposal that it is clear\nthat it is rather irrelevant whether it would work (of which I remain\nconvinced) or not.  Now I also have been of the opinion that it was\nperfectly easy to understand and embrace, and the amount, content and\ntone of responses have made very obvious that I have been quite wrong\nabout _that_ at least.\n\nThe good thing is that among all the flamage there have been actually\nsome people who went to the pain of actually reviewing the proposed\nchanges and give feedback about their relative feasibility in the\ncurrent code base.  This has helped more than the reflections on my\nsanity, I am glad to say.\n\nSo here we go:\n\nI think there has been some vague consensus with the notion that it\ndoes not make sense to track whether or not a directory _is_ empty at\nthe time of checkin (when checking in files below it, it _can't_ be),\nbut rather whether it should be automatically added and removed by git\nbased on the files in it alone.\n\nThe current state of affairs with git is that directories are\nexclusively a mechanism for accommodating hierarchical filenames.\nConsequently, the index does not need to know about them.\n\nAnyway, here is the basic idea: git is already capable of tracking\nfile permissions (though at the current point of time, this is\nsomewhat artificially limited to the u+x bit), so there are basic\nmechanisms in place for passing the respective bits through.\n\nNow my proposal basically boils down to using the u+x bit on\ndirectory/tree entries for tracking \"keep around when empty\".\n\nI think we are on the safe side to assume a directory with access\npermissions zero (a-rwx) is something we never want to be able to\ntrack with git.  So this special value, which I think is the current\ndefault, can express \"delete when empty\".  Personally I believe that\ngit can be made without problems to track more permissions (possibly\nby configuring an appropriate mask for the project) than it currently\ndoes, but that's not relevant for now: it is sufficient to use\npermissions a-rwx for an automatically managed (=evaporate when empty)\ntree/directory, and 755 for a manually managed (=stay around)\ntree/directory without actually calling lstat for now.\n\nApart from needing to accommodate directories in the index (since they\nare now associated with 1 instead of 0 bits of information), this will\nwork with the current data structures and protocols.  Patches and\ndiffs can encode the change between tracked and untracked directories\nas a change in the permissions of the directory.\n\nSo this obliterates the need to distinguish trees from directories\nusing actually separate and separately listed repository entries,\nhopefully removing the main stumbling block.\n\nIt also addresses the concern of a tree's SHA1 changing when its\nevaporate-when-empty-ness changes.  It also will not lead to dangerous\nsituations on systems attempting to replace or delete \".\" as a regular\nfile.\n\nSo it has several technical advantages over my previous proposal, and\nI _think_ it may be easier to understand and lead to less\ncontraintuitive behavior.\n\nNow for deciding about _when_ to track a directory or not, I think\nthat the following part of the previous proposal was workable:\n\nA directory's permission should be tracked in the same situations that\na file's permissions get tracked: that is if either the directory has\n_explicitly_ been added to a commit, or it is _implicitly_ part of a\ncomplete tree added into a commit.  For implicitly indicated _files_,\nwhether or not they become tracked depends on the gitignore mechanism.\nI think asking the gitignore mechanism whether the pattern \".\" in a\ngiven directory is worth tracking is a good way of deciding implicit\ninclusion, falling back onto a \"core.dirtrack\" or similar variable\nthat has some vague analogy to the \"core.filemode\" variable.\n\n-- \nDavid Kastrup, Kriemhildstr. 15, 44793 Bochum\n"},{"id":"48153","messageId":"20070722175731.GA16658@thunk.org","threadId":"9129","inReplyTo":"85abtola79.fsf@lola.goethe.zz","subject":"Re: A simpler approach to tracking directories (was: The philosophy behind my directory proposal in a nutshell)","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-07-22T17:57:31Z","receivedAt":"2007-07-22T17:57:31Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Sun, Jul 22, 2007 at 05:39:06PM +0200, David Kastrup wrote:\n> Now my proposal basically boils down to using the u+x bit on\n> directory/tree entries for tracking \"keep around when empty\".\n> \n> I think we are on the safe side to assume a directory with access\n> permissions zero (a-rwx) is something we never want to be able to\n> track with git.\n\nOk, so I think you are still missing the fundamental issue about why\nLinus is upset with your proposals.  One of the fundamental things\nwhich falls out of the \"Git Tracks Contents\" mantra is that\ninformation which you expect to be pushed forward future revisions (as\nopposed to metadata which is specific to a commit, such as the Author\nand Committer of a patch, the Commit log, etc.) *MUST* be information\nwhich is realized in the working tree.\n\nThat way, if you diff between working trees, one of which has either\nyour \".\" entry or your \"u+x\" bit, and of which doesn't, they need to\nbe *different* when run \"git diff\" on the two working trees.\n\nAnother way of putting is this single bit of information meaning \"keep\nthis directory around when empty\" is something that ***must*** be\nrepresentable in three different places: in a git tree object, in the\nindex, *AND* in the working tree.  The problem with \".\" is that since\nall directories contain the \".\" entry, you can't represent the bit of\ninformation you want to record in the working tree in that way.\n\nThere is a same problem with using the u+x permission, for the same\nreason.  Unless you want to make directories you want to keep around\nwith access permissions of zero in the working tree, you're *still*\nnot able to record presence or absence of the \"keep around when empty\nbit\" in the working tree.\n\nThat's why the \".gitignore\" entry is acceptable, where as your\nproposals are not.  The absence or presence of the \".gitignore\" entry\nin the working tree is a natural way of representing the \"keep around\nwhen empty\".  So would a \".do_not_erase\" file in the directory ---\nsort of like the \"Do Not Erase\" that professors would write on\nwhiteboards in order to request janitors to not erase them.  It seems\nthat you are objecting to having something tangible written on the\nwhiteboard --- or, in the directory, to indicate the \"do not erase\"\nnote.   \n\nBut the problem is that Linus very much wants the \"do not erase\" bit\nto be visible in the working directory, since to do otherwise would\nviolate fundamental design assumptions all over the git source files.\nMetadata such as the executable bit is actually stored in the working\ndirectory.  But we can't store the \"do not erase bit\" by leaving the\nexecutable permission off, since that will prevent the directory from\nbeing useful.\n\nSo your new proposal suffers from the same fundamental flaw as your\nprevious one.  \n\nMaybe you disagree with Linus's design constraint, but you've never\naddressed his specific concern on-point, which is that since Git\nTracks Content, if you want something to be tracked across revisions,\nit must be visible in the working tree.  That is, metadata in the\nsense of data which is not visible in the working tree, is not allowed\nto exist inside Git and carried across revisions.  So fundamentally,\nGit does not currently today support \"svn propset\" in terms of setting\nmetadata on a particular file which isn't visible in the working tree.\n\nWith SVN, today you can use svn propset to what you could think of as\nextended attributes.  So one proposal that you *could* try proposing\nis using extended attributes to represent arbitrary properties,\nincluding the one which you want, which is the \"do not erase\"\nproperty.  And one of the arguments might be that this way we could\nbetter preserve arbitrary properties currently set inside SVN, so that\nsuch repository could be faithfully translated into a Git repository.  \n\nThe problem with such a proposal is that it now requires that the\nfilesystem used to store the working directory MUST support extended\nattributes, and some filesystems, such as FAT filesystems, do not.\nAnd Git already has been accused of not being Windows friendly enough,\nand this would make things worse.\n\nIt's also a lot of hair for two very marginal features, namely being\nable to support arbitrary SVN property values, and the \"do not erase\nwhen empty\" directory bit.  Personally, I don't htink it's worth it,\nbut at least using filesystem xattrs to store that one bit of\ninformation would at least be faithful to the fundamental git design\nprincipal.\n\nRegards,\n\n\t\t\t\t\t\t- Ted\n"},{"id":"48155","messageId":"f806bb$ib1$1@sea.gmane.org","threadId":"9129","inReplyTo":"20070722175731.GA16658@thunk.org","subject":"Re: A simpler approach to tracking directories (was: The philosophy behind my directory proposal in a nutshell)","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-07-22T18:13:23Z","receivedAt":"2007-07-22T18:13:23Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Theodore Tso wrote:\n\n> Another way of putting is this single bit of information meaning \"keep\n> this directory around when empty\" is something that ***must*** be\n> representable in three different places: in a git tree object, in the\n> index, *AND* in the working tree.  The problem with \".\" is that since\n> all directories contain the \".\" entry, you can't represent the bit of\n> information you want to record in the working tree in that way.\n\nI don't think the \"do not delete when empty\" bit must be somehow represented\nin the working directory. It is enough to have this bit in index to deal\nwith working directory, and in the repository to have it persistent.\n\nCompare with submodules, and with unmerged entries (which sometimes do not\nhave worktree representation).\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"48160","messageId":"85myxoi8fi.fsf@lola.goethe.zz","threadId":"9129","inReplyTo":"20070722175731.GA16658@thunk.org","subject":"Re: A simpler approach to tracking directories","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-07-22T18:45:37Z","receivedAt":"2007-07-22T18:45:37Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Theodore Tso <tytso@mit.edu> writes:\n\n> On Sun, Jul 22, 2007 at 05:39:06PM +0200, David Kastrup wrote:\n>> Now my proposal basically boils down to using the u+x bit on\n>> directory/tree entries for tracking \"keep around when empty\".\n>> \n>> I think we are on the safe side to assume a directory with access\n>> permissions zero (a-rwx) is something we never want to be able to\n>> track with git.\n>\n> Ok, so I think you are still missing the fundamental issue about why\n> Linus is upset with your proposals.\n\nOr I am not careful in communicating what I consider obvious in\naddressing it.\n\n> One of the fundamental things which falls out of the \"Git Tracks\n> Contents\" mantra is that information which you expect to be pushed\n> forward future revisions (as opposed to metadata which is specific\n> to a commit, such as the Author and Committer of a patch, the Commit\n> log, etc.) *MUST* be information which is realized in the working\n> tree.\n\nFor every _file_ in the working tree, there is _one_ bit of\ninformation in the repository that is not in the working tree: namely\nwhether git is tracking this file at all.\n\n> That way, if you diff between working trees, one of which has either\n> your \".\" entry or your \"u+x\" bit, and of which doesn't, they need to\n> be *different* when run \"git diff\" on the two working trees.\n\nIf I have two identical working trees, and in one working tree a file\nA has been added into git, and in the other it hasn't, then git diff\nwill report a difference.\n\n> Another way of putting is this single bit of information meaning\n> \"keep this directory around when empty\" is something that ***must***\n> be representable in three different places: in a git tree object, in\n> the index, *AND* in the working tree.  The problem with \".\" is that\n> since all directories contain the \".\" entry, you can't represent the\n> bit of information you want to record in the working tree in that\n> way.\n\nBut if I have two identical working trees, where in one of them A has\nbeen added into git and in the other it hasn't, there _is_ a bit of\ndifference in the repository.\n\nI think the remaining problem boils down to the following: a file that\nis not tracked by git has nothing in the repository which one would\nassociate with it.  That is easy to understand.  But trees in the\nrepository are right now a consequence of tracking files: a file needs\na tree, and git creates one.  So we have an object in the repository\nwhich we naturally correlate with the directory in the working tree\nthat is required for holding the files in the working tree.  So the\nrelationship becomes somewhat less intuitive:\n\ngit tracks file -> file is in the repository\ngit does not track file -> file is not in the repository\n\nThat's easy.\n\ngit tracks directory -> tree permissions are not zero in the repository\ngit does not track directory -> no tree with non-zero permissions\n\nSo the problem in understanding is that in spite of git not tracking\nthe directory, there can be _still_ an _incidental_ tree whose\nexistence is solely to support the blobs in it.  This problem is\nacerbated by git having to actually manipulate working file\ndirectories even if it has no information about them.  So that git\n_works_ with directories does not help to clarify that it does not\n_track_ them.  At least one pointer that it does not track them,\nhowever, is that they are not even entered into the index.  So since\nno information flow into the repository happens, at the current point\nof time, all directories can be considered untracked.  git _is_\naccessing and manipulating them, but without any help from the\nrepository that would be specific to the directory.\n\n> There is a same problem with using the u+x permission, for the same\n> reason.  Unless you want to make directories you want to keep around\n> with access permissions of zero in the working tree, you're *still*\n> not able to record presence or absence of the \"keep around when\n> empty bit\" in the working tree.\n\nLike it is not encoded in the working tree whether or not git is\ntracking a particular file.\n\n> That's why the \".gitignore\" entry is acceptable, where as your\n> proposals are not.\n\nBut whether or not a file is tracked is not decided by a .gitignore\nentry: gitignore comes into play only when one is adding entire\ndirectories, and thus _implicitly_ adding files.\n\nThe explicit act or non-act of \"git-add file\" records a difference in\nthe repository that is nowhere reflected in the work directory.\n\n> But the problem is that Linus very much wants the \"do not erase\" bit\n> to be visible in the working directory, since to do otherwise would\n> violate fundamental design assumptions all over the git source\n> files.\n\nWhether or not a file is tracked is _not_ encoded in the work\ndirectory.  While the gitignore entries provide useful defaults, as\nlong as every git-add and git-rm is only naming single files, tracking\nand not tracking remains a possibility for every single file, a\npossibility nowhere reflected in the work directory.\n\n> So your new proposal suffers from the same fundamental flaw as your\n> previous one.\n\nIt pretty much behaves the same, yes.  After all, it has to represent\nthe difference between\n\nmkdir a\ntouch a/b\ngit-add a/b\ngit-commit -m x\ngit-rm a/b\ngit-commit -m x\n\n(where a should be removed) and\n\nmkdir a\ntouch a/b\ngit-add a\ngit-commit -m x\ngit-rm a/b\ngit-commit -m x\n\n(where a should be retained).  Feel free to address this.\n\n> Maybe you disagree with Linus's design constraint, but you've never\n> addressed his specific concern on-point, which is that since Git\n> Tracks Content, if you want something to be tracked across\n> revisions, it must be visible in the working tree.\n\nOh, I address it pretty much in every posting: whether or not a _file_\nis being tracked is _not_ visible in the working directory, and nobody\nsees a problem with that.  So this \"design constraint\" is very much\nviolated all the time, anyway.\n\n> The problem with such a proposal is that it now requires that the\n> filesystem used to store the working directory MUST support extended\n> attributes, and some filesystems, such as FAT filesystems, do not.\n> And Git already has been accused of not being Windows friendly\n> enough, and this would make things worse.\n\nWhere is the relation to my proposal?  Am I asking for anything that\nany file system could not represent?\n\n> It's also a lot of hair for two very marginal features, namely being\n> able to support arbitrary SVN property values, and the \"do not erase\n> when empty\" directory bit.\n\nMaybe we should call the bit by its meaning, not its effect.  Call it\nthe \"git has been told to track this directory\" bit.\n\nPerhaps then it gets less offensive.\n\n-- \nDavid Kastrup, Kriemhildstr. 15, 44793 Bochum\n"},{"id":"48200","messageId":"20070722214540.GA821@fieldses.org","threadId":"9129","inReplyTo":"85myxoi8fi.fsf@lola.goethe.zz","subject":"Re: A simpler approach to tracking directories","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-07-22T21:45:40Z","receivedAt":"2007-07-22T21:45:40Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Sun, Jul 22, 2007 at 08:45:37PM +0200, David Kastrup wrote:\n> Theodore Tso <tytso@mit.edu> writes:\n> > One of the fundamental things which falls out of the \"Git Tracks\n> > Contents\" mantra is that information which you expect to be pushed\n> > forward future revisions (as opposed to metadata which is specific\n> > to a commit, such as the Author and Committer of a patch, the Commit\n> > log, etc.) *MUST* be information which is realized in the working\n> > tree.\n> \n> For every _file_ in the working tree, there is _one_ bit of\n> information in the repository that is not in the working tree: namely\n> whether git is tracking this file at all.\n\nActually, no.  The index just stores data for a given set of files.  You\ncan think of the set of files for which data is stored in the index as\nthe set that is \"tracked\", but there's no independent\n\"tracked/untracked\" bit, and no way of marking a path as tracked without\nalso adding content at that path.\n\n--b.\n"}]}