{"thread":{"id":"28458","subject":"How to use git attributes to configure server-side checks?","startedAt":"2011-09-21T19:32:46Z","lastAt":"2012-02-17T19:59:55Z","messageCount":31,"participants":["Michael Haggerty","Jay Soffian","Junio C Hamano","Jeff King","Jakub Narebski","Stephen Bash"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"175959","messageId":"4E7A3BDE.3040301@alum.mit.edu","threadId":"28458","inReplyTo":null,"subject":"How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-21T19:32:46Z","receivedAt":"2011-09-21T19:32:46Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"I was thinking of using git attributes to configure a server-side\n\"update\" hook that does some basic sanity checking before accepting a\npush.  I thought I could do something like\n\n~/.gitattributes:\n    *.c whitespace\n\n~/crappy-vendor-code/.gitattributes:\n    # This code doesn't conform to our standards; disable check:\n    *.c -whitespace\n\nThis would allow fine-grained specification of which checks are applied\nto which files, and ensure that the hook configuration is kept\nsynchronized with changes to the content.\n\nWhat I can't figure out is how a server-side update hook can inquire\nabout the gitattributes that were associated with a file *in a\nparticular commit*, as opposed to in the current working tree.  I would\nlike to ask questions like \"was the \"whitespace\" attribute set on file F\nin commit C?\"\n\nI see that there is an (undocumented) API involving\ngit_attr_set_direction() that seems to let gitattributes to be read out\nof the index instead of the working tree.  But I am still confused:\n\n1. The \"git check-attr\" program doesn't seem to expose the\ngit_attr_set_direction() functionality.\n\n2. Even if it did, would that be enough?  It seems like the update hook\n(assuming a bare repository) would have to \"git reset\" the index to the\ncommit that it wants to check.  Is that allowed?  Is the index a scratch\nspace that the update hook can use however it likes?  If so, is there\nsome kind of locking that would prevent multiple simultaneous pushes\nfrom overwriting each other's index stat, or would the update script\nhave to implement its own locking scheme?\n\nAm I going about this entirely the wrong way?\n\nThanks,\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"175960","messageId":"CAG+J_DyxGW8MSYaRj2-fepFDeQDTsuy1S0VDgsu7u2CY+ZCZDQ@mail.gmail.com","threadId":"28458","inReplyTo":"4E7A3BDE.3040301@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2011-09-21T20:02:35Z","receivedAt":"2011-09-21T20:02:35Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Wed, Sep 21, 2011 at 3:32 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> I was thinking of using git attributes to configure a server-side\n> \"update\" hook that does some basic sanity checking before accepting a\n> push.  I thought I could do something like\n>\n> ~/.gitattributes:\n>    *.c whitespace\n>\n> ~/crappy-vendor-code/.gitattributes:\n>    # This code doesn't conform to our standards; disable check:\n>    *.c -whitespace\n>\n> This would allow fine-grained specification of which checks are applied\n> to which files, and ensure that the hook configuration is kept\n> synchronized with changes to the content.\n\nI do this by running diff --check. I'm actually doing it via Jenkins +\nGerrit, but it's done against a bare repo, so the idea should work\njust the same via a git hook. Here's the code I run in Jenkins in case\nit's at all helpful - https://gist.github.com/6b230f9bd8d4d2fd9895\n\nj.\n"},{"id":"175961","messageId":"7vy5xh1whq.fsf@alter.siamese.dyndns.org","threadId":"28458","inReplyTo":"4E7A3BDE.3040301@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-21T20:17:05Z","receivedAt":"2011-09-21T20:17:05Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> I was thinking of using git attributes to configure a server-side\n> \"update\" hook that does some basic sanity checking before accepting a\n> push.  I thought I could do something like\n>\n> ~/.gitattributes:\n>     *.c whitespace\n>\n> ~/crappy-vendor-code/.gitattributes:\n>     # This code doesn't conform to our standards; disable check:\n>     *.c -whitespace\n>\n> This would allow fine-grained specification of which checks are applied\n> to which files, and ensure that the hook configuration is kept\n> synchronized with changes to the content.\n>\n> What I can't figure out is how a server-side update hook can inquire\n> about the gitattributes that were associated with a file *in a\n> particular commit*, as opposed to in the current working tree.  I would\n> like to ask questions like \"was the \"whitespace\" attribute set on file F\n> in commit C?\"\n>\n> I see that there is an (undocumented) API involving\n> git_attr_set_direction() that seems to let gitattributes to be read out\n> of the index instead of the working tree.  But I am still confused:\n\nThe words \"server side\" automatically mean that there should be no working\ntree, and where there is no working tree there should be no index, so the\ndirection should not make any difference.  The attributes that are used to\nhelp whitespace checks should come from project.git/info/attributes in\nsuch a case [*1*].\n\nAs to the actual checking of the pushed contents, your pre-receive hook is\ncalled after all the objects received are placed in the object store, but\nbefore the refs are updated to conclude the push, and you can veto the\npush by exiting with non-zero status from the hook. Your hook will get\nwhich ref is being updated from what old commit to what new commit, so you\ncan either\n\n (1) grab the new commits introduced to the project using rev-list, and\n     invoke \"git show --check\" on each and every one of them; or\n\n (2) check only the endpoints, by running \"git diff --check\" between the\n     old and new commits. A pushed series may introduce a breakage early\n     in the series which is corrected later in the series and you would\n     not catch such a case if you used this method.\n\n[Footnote]\n\n*1* granted, that there are people who make a checkout from their post\nupdate hook, perhaps so that a build robot can be told to work on it or\nthe web server can deliver individual files. But that is merely a crude\nsubstitute of having a proper \"install\" procedure. As far as the\n\"server-side\" Git that accepts \"git push\" is concerned, such a working\ntree does not exist.\n"},{"id":"175988","messageId":"4E7AF1AE.5030005@alum.mit.edu","threadId":"28458","inReplyTo":"7vy5xh1whq.fsf@alter.siamese.dyndns.org","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-22T08:28:30Z","receivedAt":"2011-09-22T08:28:30Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/21/2011 10:17 PM, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n>> I was thinking of using git attributes to configure a server-side\n>> \"update\" hook that does some basic sanity checking before accepting a\n>> push.  I thought I could do something like\n>>\n>> ~/.gitattributes:\n>>     *.c whitespace\n>>\n>> ~/crappy-vendor-code/.gitattributes:\n>>     # This code doesn't conform to our standards; disable check:\n>>     *.c -whitespace\n>>\n>> This would allow fine-grained specification of which checks are applied\n>> to which files, and ensure that the hook configuration is kept\n>> synchronized with changes to the content.\n>\n> The words \"server side\" automatically mean that there should be no working\n> tree, and where there is no working tree there should be no index, so the\n> direction should not make any difference.  The attributes that are used to\n> help whitespace checks should come from project.git/info/attributes in\n> such a case [*1*].\n\nThanks for the reply and for explaining how the index can(not) be used\nfor this purpose.  But what you propose is not flexible enough for me.\nI would like the checking configuration to be *versioned* along with the\ncode.  For example, suppose my project decides to enforce a rule that\nall Python code needs to be indented with spaces.  It might be that not\nall of our old code adheres to this rule, and that we only want to clean\nup the code in master.  I would like to be able to\n\n1. Implement a new \"check-space-indent\" option in our update hook, which\nis applied to any file that has the \"check-space-indent\" attribute.  At\nfirst, no files have this attribute, so the new test has no effect.\n\n2. Start cleaning up code in master.  Each time a subdirectory tree is\ncleaned up, add a line like\n\n    *.py check-space-indent\n\nin a .gitattributes file at the root of the subdirectory tree.  While\nthis procedure proceeds incrementally, git ensures that code that has\nbeen cleaned up stays cleaned up.\n\n3. When all code is cleaned up, add the above line to the top-level\n.gitattributes file in the master branch.  But if there are some parts\nof the code that we don't want to clean up (for example, code acquired\nfrom elsewhere that uses different coding standards), we can turn off\nthe check for that subdirectory tree.\n\nNote that during this whole process all code passes the update hook,\nbecause we can configure it to ignore problems in code that hasn't been\ncleaned up yet.  And even at the end of the procedure, it is still\npossible to commit to older branches where tabs are still used for\nindentation because they don't use the new attribute.\n\nFor this to be possible, I would need to determine the git attributes to\napply to a particular file in a particular commit; something like\n\n    git check-attr check-space-indent $SHA1:path/to/file\n\nThis does not seem to be possible today without writing my own code to\ncrawl and parse the gitattributes files from a particular commit.\n\n>  (1) grab the new commits introduced to the project using rev-list, and\n>      invoke \"git show --check\" on each and every one of them; or\n\nWhere does \"git show --check\" read its gitattributes (i.e.,\n\"whitespace\") from?\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"175996","messageId":"CAG+J_DxtCx6-RKWLKFy+V7tOtu7UnUrke7iN8gNdGiY-sC52sQ@mail.gmail.com","threadId":"28458","inReplyTo":"4E7AF1AE.5030005@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2011-09-22T15:41:34Z","receivedAt":"2011-09-22T15:41:34Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Thu, Sep 22, 2011 at 4:28 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> Where does \"git show --check\" read its gitattributes (i.e.,\n> \"whitespace\") from?\n\nIt looks like builtin_checkdiff (diff.c) calls whitespace_rule (ws.c)\nwhich in turn calls git_check_attr (attr.c) which, in a bare repo,\nconsiders $(prefix)/etc/gitattributes, core.attributesfile and\n$GIT_DIR/info/attributes, falling back to the default whitespace rule\nof trailing_space, space_before_tab, and tab-width of 8\n(WS_DEFAULT_RULE in cache.h).\n\nThank you for this thread. I was under the illusion that diff-tree\n--check considered in-tree .gitattributes, but the code seems to\nindicate otherwise. :-(\n\nj.\n"},{"id":"176000","messageId":"20110922171340.GA2934@sigill.intra.peff.net","threadId":"28458","inReplyTo":"CAG+J_DxtCx6-RKWLKFy+V7tOtu7UnUrke7iN8gNdGiY-sC52sQ@mail.gmail.com","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-22T17:13:41Z","receivedAt":"2011-09-22T17:13:41Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Sep 22, 2011 at 11:41:34AM -0400, Jay Soffian wrote:\n\n> Thank you for this thread. I was under the illusion that diff-tree\n> --check considered in-tree .gitattributes, but the code seems to\n> indicate otherwise. :-(\n\nNo, we definitely don't use in-tree gitattributes. IIRC, there are some\nprecedence and ordering questions. I think the ordering now is:\n\n  1. Look in $GIT_DIR/info/attributes\n\n  2. If not found, look in per-directory .gitattributes\n\n  3. If not found, look in core.gitattributesfile\n\nWhere do in-tree attributes fit in? Between 1 and 2? Or 2 and 3? And\nwhich tree do we look at?\n\nHere are some examples:\n\n  a. If I do \"git checkout branch-foo\", we should look at branch-foo's\n     tree for things like crlf, right?  Do we still fall back to\n     per-directory .gitattributes in the working tree? On the one hand,\n     they're not really relevant to the commit we're moving to. But they\n     are respected in the current code, and can be useful when moving to\n     old commits which lack attributes.\n\n     I think this is where the index magic comes in in the current code\n     (we do something like \"load the index, then respect gitattributes\n     from the index\").\n\n     So maybe this is solved already.\n\n  b. You're diffing commit $a against commit $b. Whose gitattributes\n     have precedence? Is order important? Are gitattributes in the\n     working tree and index relevant?\n\n  c. You're diffing commit $a against HEAD. Which gitattributes have\n     precedence? Again, is order important (i.e., does \"diff -R\" look at\n     different attributes than \"diff\")?\n\nI'm sure there are others, too. And I don't think any of these is\ninsurmountable. But somebody needs to think through a lot of cases and\ncome up with consistent, sane behavior that does the right thing in each\ncase (considering both bare repositories and ones with working trees).\n\n-Peff\n"},{"id":"176002","messageId":"7vwrd0xzdc.fsf@alter.siamese.dyndns.org","threadId":"28458","inReplyTo":"4E7AF1AE.5030005@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-22T17:26:07Z","receivedAt":"2011-09-22T17:26:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> I would like the checking configuration to be *versioned* along with the\n> code.  For example, suppose my project decides to enforce a rule that\n> all Python code needs to be indented with spaces.  It might be that not\n> all of our old code adheres to this rule, and that we only want to clean\n> up the code in master.\n\nYou want to sneak in a badly formatted code? Add an entry to the in-tree\nattributes file to disable whitespace checking to cover that file!\n\nSo even though I agree with you that the check mechanism may need to be\naware of what revision it is checking and adjust which rules are applied\nwhen checking the revision, I do not think using in-tree attribute file is\nthe right solution to that problem.\n"},{"id":"176009","messageId":"CAG+J_DxdP2qHhttJOtWQTKeiDV2YbC_A_F+b9sDOZsWhWxjcjw@mail.gmail.com","threadId":"28458","inReplyTo":"20110922171340.GA2934@sigill.intra.peff.net","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2011-09-22T18:41:42Z","receivedAt":"2011-09-22T18:41:42Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Thu, Sep 22, 2011 at 1:13 PM, Jeff King <peff@peff.net> wrote:\n>\n> No, we definitely don't use in-tree gitattributes. IIRC, there are some\n> precedence and ordering questions. I think the ordering now is:\n>\n>  1. Look in $GIT_DIR/info/attributes\n>\n>  2. If not found, look in per-directory .gitattributes\n>\n>  3. If not found, look in core.gitattributesfile\n>\n> Where do in-tree attributes fit in? Between 1 and 2? Or 2 and 3? And\n> which tree do we look at?\n\nattr.c says:\n\n  a. built-in attributes\n  b. $(prefix)/etc/gitattributes unless GIT_ATTR_NOSYSTEM is set\n  c. core.attributesfile\n  d. per-directory .gitattributes\n  e. $GIT_DIR/info/attributes\n\nThe mechanics of (d) are established by git_attr_direction:\n\n  GIT_ATTR_CHECKIN: working-copy, then index\n  GIT_ATTR_CHECKOUT: index, then working-copy\n  GIT_ATTR_INDEX: index-only\n\nWhere GIT_ATTR_CHECKIN is the default direction and GIT_ATTR_CHECKOUT\nis used while checking-out files from the index. (GIT_ATTR_INDEX is\nused only by git-archive.)\n\nNote that (d) only occurs in non-bare repos or if direction is GIT_ATTR_INDEX.\n\n> Here are some examples:\n>\n>  a. If I do \"git checkout branch-foo\", we should look at branch-foo's\n>     tree for things like crlf, right?  Do we still fall back to\n>     per-directory .gitattributes in the working tree? On the one hand,\n>     they're not really relevant to the commit we're moving to. But they\n>     are respected in the current code, and can be useful when moving to\n>     old commits which lack attributes.\n>\n>     I think this is where the index magic comes in in the current code\n>     (we do something like \"load the index, then respect gitattributes\n>     from the index\").\n>\n>     So maybe this is solved already.\n>\n>  b. You're diffing commit $a against commit $b. Whose gitattributes\n>     have precedence? Is order important? Are gitattributes in the\n>     working tree and index relevant?\n>\n>  c. You're diffing commit $a against HEAD. Which gitattributes have\n>     precedence? Again, is order important (i.e., does \"diff -R\" look at\n>     different attributes than \"diff\")?\n>\n> I'm sure there are others, too. And I don't think any of these is\n> insurmountable. But somebody needs to think through a lot of cases and\n> come up with consistent, sane behavior that does the right thing in each\n> case (considering both bare repositories and ones with working trees).\n\nI think that diff-index --cached or when there is no working tree,\nshould set the direction to GIT_ATTR_INDEX so that it may be used with\na bare repo. In such case, the .gitattributes would come from the\nindex.\n\nConsistent with that, when comparing two commits (diff-tree), I think\nyou look at the .gitattributes in the second commit.\n\nj.\n"},{"id":"176011","messageId":"7vk490xtys.fsf@alter.siamese.dyndns.org","threadId":"28458","inReplyTo":"CAG+J_DxdP2qHhttJOtWQTKeiDV2YbC_A_F+b9sDOZsWhWxjcjw@mail.gmail.com","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-22T19:22:51Z","receivedAt":"2011-09-22T19:22:51Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n> Consistent with that, when comparing two commits (diff-tree), I think\n> you look at the .gitattributes in the second commit.\n\nThat would make \"diff A B\" and \"diff -R B A\" behave differently.\n"},{"id":"176017","messageId":"20110922205856.GA8563@sigill.intra.peff.net","threadId":"28458","inReplyTo":"CAG+J_DxdP2qHhttJOtWQTKeiDV2YbC_A_F+b9sDOZsWhWxjcjw@mail.gmail.com","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-22T20:58:56Z","receivedAt":"2011-09-22T20:58:56Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Sep 22, 2011 at 02:41:42PM -0400, Jay Soffian wrote:\n\n> attr.c says:\n> \n>   a. built-in attributes\n>   b. $(prefix)/etc/gitattributes unless GIT_ATTR_NOSYSTEM is set\n>   c. core.attributesfile\n>   d. per-directory .gitattributes\n>   e. $GIT_DIR/info/attributes\n> \n> The mechanics of (d) are established by git_attr_direction:\n> \n>   GIT_ATTR_CHECKIN: working-copy, then index\n>   GIT_ATTR_CHECKOUT: index, then working-copy\n>   GIT_ATTR_INDEX: index-only\n\nThanks for hunting it down. I had been thinking that \"attributes from\ntree\" would come either before or after (d) above, but the concept\nreally fits better into the second list (i.e., they're per-directory\nattributes, it's just a matter of which set of directories).\n\n> Where GIT_ATTR_CHECKIN is the default direction and GIT_ATTR_CHECKOUT\n> is used while checking-out files from the index. (GIT_ATTR_INDEX is\n> used only by git-archive.)\n\nHrm. But git archive works correctly in a bare repo with no index at\nall. It looks like we just populate an in-core index and feed that to\ngit_attr_set_direction. Which is a bit suboptimal for something like\ndiff, which might not need to look at all parts of the tree (I guess it\nis similarly suboptimal for archive with pathspecs).\n\nBut still, those are just performance considerations. We could use the\nsame trick for diff/log in a bare repo. I guess we'd end up refreshing\nthe index from each commit in a multi-commit log, which might be\nnoticeably slow.\n\n> Consistent with that, when comparing two commits (diff-tree), I think\n> you look at the .gitattributes in the second commit.\n\nThat makes some sense to me. As Junio pointed out, there is a catch with\n\"diff -R\". In that case, I would still think you would use the \"second\"\ncommit, even though we're reversing the diff. So:\n\n  git diff A B\n\nwould not be exactly equivalent to:\n\n  git diff -R B A\n\nin that the second would use attributes from \"A\" instead of \"B\".\n\nHowever, I think this is skirting around a somewhat larger issue, which\nis that gitattributes are sometimes about \"this is what the file is like\nat the current state of history\", and sometimes about \"this is what this\nfile is like throughout history\".\n\nFor example, imagine I've got a repository of binary files. At some\npoint, I decide to use gitattributes to configure a textconv filter. In\nmy non-bare repo, when I do \"git log\" I get nice textconv'd diffs going\nback through all of history. But if I push to a bare repo and try to do\na \"git log\" there, my attributes are ignored. So in this case, I like\nthat the working tree's attributes are applied retroactively, and I'd\nlike the bare repo to do the same.\n\nNow consider a different example. I have a repo with a script \"foo\" that\ncontains perl code, and I add .gitattributes marking it as such (for\nfunc headers, or maybe I have a magic external diff, or whatever[1]).\nLater, I decide that I hate perl and rewrite it in python, updating\ngitattributes. Now I _don't_ want the retroactive behavior. When I do a\n\"git log -p\", I want to see the old commits with the perl script shown\nusing the perl attribute, not the python. But what the heck would it\nmean to diff a recent python commit against an old perl one?\n\nEven though we think of the diff attributes as \"here's how you diff\",\nthey are really \"here are some annotations about the end points\". So for\nsomething like a textconv, you care about the attributes of _both_\nsides of a diff, applying the attributes of the \"from\" tree to the paths\nin that tree. Something like funcname is harder. I guess you'd probably\nwant to use the attributes from the \"from\" tree, since it is about\nreporting context from the \"from\" side.\n\nSo the semantics really end up depending on the particular attribute.\nSomething like \"-delta\" exists more outside the history or the state of\na particular commit.\n\nSo I think doing it \"right\" would be a lot more complicated than just\nreading the commits from a particular tree. I think it would mean adding\nmore context to all attribute lookups, and having each caller decide how\nthe results should be used.\n\nHowever, retroactively applying attributes from the working tree, even\nthough it is sometimes wrong (e.g., we get the perl/python thing wrong\n_now_ if you have a working tree), is often convenient in practice\n(because otherwise you end up duplicating your per-directory\ngitattributes in your info/attributes file), and rarely is it actually\nwrong (because changing the type of a file without changing its path\nisn't all that common).\n\nSo if the status quo with working trees (i.e., retroactively applying\nthe current gitattributes to past commits) is good enough, perhaps the\nbare-repository solution should be modeled the same way? In other words,\nshould \"git log -p\" in a bare repo be looking for attributes not in the\ncommits being diffed, but rather in HEAD[2]?\n\nThat at least would make it consistent with the non-bare behavior. And\nthen if we want to move forward with making particular attributes more\naware of their context, we can do it in _both_ the bare and non-bare\ncases.\n\n-Peff\n\n[1] The perl/python thing is probably not a huge deal, as funcnames are\n    the most likely thing to configure. But you can imagine it would be\n    much worse if some binary file changes formats, and you were using\n    textconv. Or something with word-diff, perhaps.\n\n[2] You can almost do this with:\n\n      git show HEAD:.gitattributes >info/attributes\n      git show commit-you-care-about\n      rm info/attributes\n\n    except that it won't handle any per-directory attributes files from\n    subdirectories. So I think you'd want a \"--attributes-from=HEAD\"\n    diff option or something similar.\n"},{"id":"176018","messageId":"20110922210421.GB8563@sigill.intra.peff.net","threadId":"28458","inReplyTo":"20110922205856.GA8563@sigill.intra.peff.net","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-22T21:04:21Z","receivedAt":"2011-09-22T21:04:21Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Sep 22, 2011 at 04:58:56PM -0400, Jeff King wrote:\n\n> That makes some sense to me. As Junio pointed out, there is a catch with\n> \"diff -R\". In that case, I would still think you would use the \"second\"\n> commit, even though we're reversing the diff. So:\n> \n>   git diff A B\n> \n> would not be exactly equivalent to:\n> \n>   git diff -R B A\n> \n> in that the second would use attributes from \"A\" instead of \"B\".\n\nI misread Junio's comment a bit. Re-reading it, this is exactly the\ninconsistency he complained about. However, I consider it somewhat of a\nfeature. We currently have two ways to express the same thing, and you\narrive at one or the other based on the way you are thinking of the\nproblem. But we can use that to disambiguate between the two cases; one\nis about going from A to B, and one is about inverting the operation of\ngoing from B to A. Right now they're equivalent, but they don't have to\nbe.\n\nIf you read the rest of my message, you will see that I think picking\n\"first\" or \"second\" arbitrarily like this might be barking up the wrong\ntree.  But I just wanted to clarify that point.\n\n-Peff\n"},{"id":"176031","messageId":"m3vcskqjcv.fsf@localhost.localdomain","threadId":"28458","inReplyTo":"4E7AF1AE.5030005@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-09-22T22:54:50Z","receivedAt":"2011-09-22T22:54:50Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> Thanks for the reply and for explaining how the index can(not) be used\n> for this purpose.  But what you propose is not flexible enough for me.\n> I would like the checking configuration to be *versioned* along with the\n> code. [...]\n\n[...]\n\n> For this to be possible, I would need to determine the git attributes to\n> apply to a particular file in a particular commit; something like\n> \n>     git check-attr check-space-indent $SHA1:path/to/file\n> \n> This does not seem to be possible today without writing my own code to\n> crawl and parse the gitattributes files from a particular commit.\n\nUnfortunately it doesn't seem to be there mechanism to query about\nstate of gitattributes at given commit.\n\nThere is a slight problem from the UI point of view of git-check-attr,\nnamely that there are _three_ pieces of information: a place to read\n.gitattributes from (working tree, index, commit), list of attributes\nto check (or --all) and list of files (list of paths).  You can use\n\"--\" to separate _two_ pieces of information.\n\nNb. the ability to read gitattributes from given commit would be\nuseful also for gitweb (the `encoding` gitattribute, etc.).\n\n-- \nJakub Narębski\n"},{"id":"176049","messageId":"4E7C44C8.10000@alum.mit.edu","threadId":"28458","inReplyTo":"7vwrd0xzdc.fsf@alter.siamese.dyndns.org","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-23T08:35:20Z","receivedAt":"2011-09-23T08:35:20Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/22/2011 07:26 PM, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n> \n>> I would like the checking configuration to be *versioned* along with the\n>> code.  For example, suppose my project decides to enforce a rule that\n>> all Python code needs to be indented with spaces.  It might be that not\n>> all of our old code adheres to this rule, and that we only want to clean\n>> up the code in master.\n> \n> You want to sneak in a badly formatted code? Add an entry to the in-tree\n> attributes file to disable whitespace checking to cover that file!\n\nNo, the scenario that I was trying to describe is a project that wants\nto tighten up its code formatting rules after years of laxity.  It is\nconvenient to support legacy branches that still contain nonconforming\ncode without having to reformat it all, just as it is convenient to fix\nthe current code incrementally rather than requiring all of the cleanup\nto be done in one big bang.  Thus it is important that new rules not be\nenforced retroactively on old code.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"176054","messageId":"4E7C5A3B.10703@alum.mit.edu","threadId":"28458","inReplyTo":"20110922205856.GA8563@sigill.intra.peff.net","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-23T10:06:51Z","receivedAt":"2011-09-23T10:06:51Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/22/2011 10:58 PM, Jeff King wrote:\n> However, I think this is skirting around a somewhat larger issue, which\n> is that gitattributes are sometimes about \"this is what the file is like\n> at the current state of history\", and sometimes about \"this is what this\n> file is like throughout history\".\n\nThis is a very dangerous line of thought.  When content is read out of a\nhistorical commit, the content must be identical to what was checked\ninto that commit.  For example, the EOL characters that I see in an old\nfile revision must not depend on my current HEAD or index.  This rule\nshould apply regardless of whether the content is being read to be\nchecked out, put into an archive, or diffed against some other revision.\n So for these purposes, I think there is no choice but to honor the\ngitattributes files in the tree/index/directory from which the content\nwas read.\n\nIf the user really wants to say \"this is what this file is like\nthroughout history\" (thereby altering history), then this should be a\nlocal decision that should be stored locally in $GIT_DIR/info/attributes.\n\nThere are other attributes that affect \"two-argument\" operations like\ndiff.  Here the policy has to depend on the situation.  In the case of\ndiff, I suggest that the relevant attributes be read from *both*\nversions of the file.  If they are the same, then obviously use them.\nIf they differ, then fall back to a \"safe\" default (for example, the\ndiff that would be used if *no* attributes had been specified).\nHowever, as a special case, if an attribute is specified in one version\nand unspecified in another, it would *usually* be OK to use the\nspecified version of the attributes and that might be considered a\nreasonable alternative.\n\nBy the way, it is possible that the two ends of a diff operation have\ndifferent filenames (e.g., with -M or -C).  In this case the attributes\nshould be looked up using the filename corresponding to the commit.\n\n> So I think doing it \"right\" would be a lot more complicated than just\n> reading the commits from a particular tree. I think it would mean adding\n> more context to all attribute lookups, and having each caller decide how\n> the results should be used.\n\nI agree.\n\n> So if the status quo with working trees (i.e., retroactively applying\n> the current gitattributes to past commits) is good enough, perhaps the\n> bare-repository solution should be modeled the same way? In other words,\n> should \"git log -p\" in a bare repo be looking for attributes not in the\n> commits being diffed, but rather in HEAD[2]?\n\nThis would be a very poor policy, modeled on a status quo that is *not*\ngood enough.  For example, HEAD might not even be a descendant of the\ncommit whose content is being interrogated; the commit might have new\nfiles and new gitattributes that would be ignored.  I suppose your\nsuggestion is better than the status quo, so it would be fine as a\nstarting point, *provided* it is clear that people should not rely on\nthis behavior not being improved later.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"176057","messageId":"4E7C6193.2020201@alum.mit.edu","threadId":"28458","inReplyTo":"m3vcskqjcv.fsf@localhost.localdomain","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-23T10:38:11Z","receivedAt":"2011-09-23T10:38:11Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/23/2011 12:54 AM, Jakub Narebski wrote:\n> There is a slight problem from the UI point of view of git-check-attr,\n> namely that there are _three_ pieces of information: a place to read\n> .gitattributes from (working tree, index, commit), list of attributes\n> to check (or --all) and list of files (list of paths).  You can use\n> \"--\" to separate _two_ pieces of information.\n\nAn alternative would be to accept <rev>:<path>, :<n>:<path>, and :<path>\nin addition to simple <path>.\n\nI also just remembered that currently the paths passed to\ngit-check-attr, git_check_attr(), and git_all_attrs() do not have to\ncorrespond to existing objects; the paths are compared as strings.\nPresumably we should retain this aspect of the behavior even if a\nrevision or tree is specified explicitly.\n\nThere are other problems in the UI of git-check-attr:\n\n1. Its \"-z\" option affects how standard input is interpreted; there is\nno way to cause the output to be generated with NUL separators.\n\n2. Its output does not distinguish between the special statuses\nunspecified/unset/set and possible string values\n\"unspecified\"/\"unset\"/\"set\".\n\nMaybe a --porcelain option could be used to overcome these shortcomings.\n\nIf necessary we could deprecate \"git check-attr\" and implement an\nimproved command (\"git get-attr\"?) that starts from a clean UI slate.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"176059","messageId":"33047451.27244.1316782148569.JavaMail.root@mail.hq.genarts.com","threadId":"28458","inReplyTo":"4E7C44C8.10000@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Stephen Bash","fromEmail":"bash@genarts.com","sentAt":"2011-09-23T12:49:08Z","receivedAt":"2011-09-23T12:49:08Z","isPatch":false,"sender":{"key":"bash@genarts.com","avatar":null},"body":"----- Original Message -----\n> From: \"Michael Haggerty\" <mhagger@alum.mit.edu>\n> Sent: Friday, September 23, 2011 4:35:20 AM\n> Subject: Re: How to use git attributes to configure server-side checks?\n>\n> On 09/22/2011 07:26 PM, Junio C Hamano wrote:\n> > Michael Haggerty <mhagger@alum.mit.edu> writes:\n> >\n> >> I would like the checking configuration to be *versioned* along with the\n> >> code. For example, suppose my project decides to enforce a rule that\n> >> all Python code needs to be indented with spaces. It might be that not\n> >> all of our old code adheres to this rule, and that we only want to clean\n> >> up the code in master.\n> >\n> > You want to sneak in a badly formatted code? Add an entry to the\n> > in-tree attributes file to disable whitespace checking to cover that file!\n> \n> No, the scenario that I was trying to describe is a project that wants\n> to tighten up its code formatting rules after years of laxity. It is\n> convenient to support legacy branches that still contain nonconforming\n> code without having to reformat it all, just as it is convenient to\n> fix the current code incrementally rather than requiring all of the\n> cleanup to be done in one big bang. Thus it is important that new rules not be\n> enforced retroactively on old code.\n\nWe're in the process of a similar change over (we're dealing with EOL rather than indents), but I attacked it from a different angle...  I wrote our update script to examine modified files and ensure compliance (diff-tree -r, iterate over blobs).  That way legacy files are left alone (even in master), but active development must live up to the current rules.  Is there a reason you need to go tree-by-tree rather than file-by-file?\n\nThanks,\nStephen\n"},{"id":"176064","messageId":"4E7C8A20.8050100@alum.mit.edu","threadId":"28458","inReplyTo":"33047451.27244.1316782148569.JavaMail.root@mail.hq.genarts.com","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-23T13:31:12Z","receivedAt":"2011-09-23T13:31:12Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/23/2011 02:49 PM, Stephen Bash wrote:\n> We're in the process of a similar change over (we're dealing with EOL\n> rather than indents), but I attacked it from a different angle...  I\n> wrote our update script to examine modified files and ensure\n> compliance (diff-tree -r, iterate over blobs).  That way legacy files\n> are left alone (even in master), but active development must live up\n> to the current rules.  Is there a reason you need to go tree-by-tree\n> rather than file-by-file?\n\nI want to avoid code churn, especially in third-party code.  With your\nsolution, I believe that we would be forced to entirely clean up any\nfile that we needed to touch.  The resulting code churn would make\nintegrating future upstream releases a nightmare.\n\nFor some kinds of checks, one could only check that the *lines* changed\nsatisfy the new rules.\n\nBut rather than thinking up workarounds, it seems like a better idea to\nfix git to handle .gitattributes correctly.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"176092","messageId":"20110923193341.GA26820@sigill.intra.peff.net","threadId":"28458","inReplyTo":"4E7C5A3B.10703@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-23T19:33:41Z","receivedAt":"2011-09-23T19:33:41Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Sep 23, 2011 at 12:06:51PM +0200, Michael Haggerty wrote:\n\n> This is a very dangerous line of thought.  When content is read out of a\n> historical commit, the content must be identical to what was checked\n> into that commit.  For example, the EOL characters that I see in an old\n> file revision must not depend on my current HEAD or index.  This rule\n> should apply regardless of whether the content is being read to be\n> checked out, put into an archive, or diffed against some other revision.\n>  So for these purposes, I think there is no choice but to honor the\n> gitattributes files in the tree/index/directory from which the content\n> was read.\n> \n> If the user really wants to say \"this is what this file is like\n> throughout history\" (thereby altering history), then this should be a\n> local decision that should be stored locally in $GIT_DIR/info/attributes.\n\nI think we're in agreement here that this is the right way to do things.\nMy points are that:\n\n  1. The current behavior is often convenient, even though it is wrong\n     in some cases. Using $GIT_DIR/info/attributes is manual and\n     annoying[1]. Turning on .gitattributes in the working tree and\n     having it impact \"git log -p\" on older commits is a huge\n     convenience. When it's right.\n\n  2. This isn't how we're doing it now, and I don't see a lot of bug\n     reports.  That doesn't mean there isn't room for improvement, but\n     it may mean the current strategy is good enough, especially if the\n     alternative ends up being very complex or hard to understand.\n\nMy biggest fear is not that we are wrong in some minority of the cases,\nbut that there is no good way to tell git it's wrong and to do something\nelse.\n\n[1] I really wish we had an elegant way of versioning meta-information\n    about a repository (like config, info/attributes, etc). I've hacked\n    around this before by having a special meta-branch for each repo,\n    checkout it out in an alternate directory, and then symlinking bits\n    of it into .git. But that's kind of ugly, too.\n\n    I'm not sure what a good solution would look like. There's a real\n    can of worms with respect to picking and choosing local versus\n    remote bits of meta-information, with some security implications.\n\n> There are other attributes that affect \"two-argument\" operations like\n> diff.  Here the policy has to depend on the situation.  In the case of\n> diff, I suggest that the relevant attributes be read from *both*\n> versions of the file.  If they are the same, then obviously use them.\n> If they differ, then fall back to a \"safe\" default (for example, the\n> diff that would be used if *no* attributes had been specified).\n> However, as a special case, if an attribute is specified in one version\n> and unspecified in another, it would *usually* be OK to use the\n> specified version of the attributes and that might be considered a\n> reasonable alternative.\n\nThose are sane ground rules. But specific contexts would want to be\nsmarter in some cases. For example, if you have two conflicting diff\nattributes that both define a textconv, you would not want to fallback\nto not doing any textconv (which is what your above text prescribes).\nInstead, you want to textconv each side individually according to its\nattributes, and then compare the result.\n\nOne could argue that textconv is therefore not a \"two-argument\"\noperation, since it works on each side individually. But it is part of\nthe \"diff\" attribute, and so it ends up being processed in a\ntwo-argument context (this is possibly a mistake in the original design\nof textconv).\n\n> By the way, it is possible that the two ends of a diff operation have\n> different filenames (e.g., with -M or -C).  In this case the attributes\n> should be looked up using the filename corresponding to the commit.\n\nWe do some of this already. For example, textconv will look up each side\nbased on its individual filename. But the funcname code, for example\ndoes this (\"one\" is the \"from\" side of the diff, \"two\" is the \"to\"\nside):\n\n  pe = diff_funcname_pattern(one);\n  if (!pe)\n          pe = diff_funcname_pattern(two);\n\nwhereas I think your proposed code would do:\n\n  pe1 = diff_funcname_pattern(one);\n  pe2 = diff_funcname_pattern(two);\n  if (!pe1)\n          pe = pe2; /* only one side, or both empty */\n  else if (!pe2)\n          pe = pe1; /* only one side */\n  else if (!pattern_cmp(pe1, pe2))\n          pe = pe1; /* identical, pick one */\n  else\n          pe = NULL; /* conflict, default to nothing */\n\n> > So if the status quo with working trees (i.e., retroactively applying\n> > the current gitattributes to past commits) is good enough, perhaps the\n> > bare-repository solution should be modeled the same way? In other words,\n> > should \"git log -p\" in a bare repo be looking for attributes not in the\n> > commits being diffed, but rather in HEAD[2]?\n> \n> This would be a very poor policy, modeled on a status quo that is\n> *not* good enough.  For example, HEAD might not even be a descendant\n> of the commit whose content is being interrogated; the commit might\n> have new files and new gitattributes that would be ignored.\n\nNotice the \"if\" in my statement. :)\n\nYes, that is a corner case that is utterly broken. It's also utterly\nbroken in the current code with a non-bare repository, where we respect\nthe checked-out .gitattributes (which generally come from HEAD). This\nwould just be a very simple way of harmonizing bare repositories with\nthe current non-bare behavior (broken or not).\n\n> I suppose your suggestion is better than the status quo, so it would\n> be fine as a starting point, *provided* it is clear that people should\n> not rely on this behavior not being improved later.\n\nSure. If we go down this road, we will be breaking the non-bare case,\ntoo, so we will have to deal with deprecations and all that, anyway.\n\n-Peff\n"},{"id":"176094","messageId":"7vobybt5bw.fsf@alter.siamese.dyndns.org","threadId":"28458","inReplyTo":"20110923193341.GA26820@sigill.intra.peff.net","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-23T19:40:51Z","receivedAt":"2011-09-23T19:40:51Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> We do some of this already. For example, textconv will look up each side\n> based on its individual filename. But the funcname code, for example\n> does this (\"one\" is the \"from\" side of the diff, \"two\" is the \"to\"\n> side):\n>\n>   pe = diff_funcname_pattern(one);\n>   if (!pe)\n>           pe = diff_funcname_pattern(two);\n\nWhat text would we see on the actual hunk header line? I had an impression\nthat we always take from the preimage. I might be wrong, but if that is\nindeed the case, shouldn't we be ignoring the attribute tacked on to the\npostimage side altogether?\n"},{"id":"176095","messageId":"20110923194431.GA27839@sigill.intra.peff.net","threadId":"28458","inReplyTo":"7vobybt5bw.fsf@alter.siamese.dyndns.org","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-23T19:44:31Z","receivedAt":"2011-09-23T19:44:31Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Sep 23, 2011 at 12:40:51PM -0700, Junio C Hamano wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > We do some of this already. For example, textconv will look up each side\n> > based on its individual filename. But the funcname code, for example\n> > does this (\"one\" is the \"from\" side of the diff, \"two\" is the \"to\"\n> > side):\n> >\n> >   pe = diff_funcname_pattern(one);\n> >   if (!pe)\n> >           pe = diff_funcname_pattern(two);\n> \n> What text would we see on the actual hunk header line? I had an impression\n> that we always take from the preimage. I might be wrong, but if that is\n> indeed the case, shouldn't we be ignoring the attribute tacked on to the\n> postimage side altogether?\n\nSort of. I think this is Michael's fallback case of \"if there was no\nattribute before, use the other side\". In other words, we are guessing\nif there was no attribute before, and there is one now, the reason is\nnot because they are two different formats but rather because the\nattribute simply hadn't been added yet on the other side.\n\nSo if you have three commits, and the second one adds the attribute, you\ncan diff commits 1 and 3 in either direction, and still get the benefit\nof the attribute.\n\nLike reading .gitattributes from the current directory to look at old\n(or even unrelated) commits, I think this is a convenience and is right\nin most cases, but can be spectacularly wrong in some corner cases.\n\n-Peff\n"},{"id":"176117","messageId":"4E7D7329.7070800@alum.mit.edu","threadId":"28458","inReplyTo":"20110923193341.GA26820@sigill.intra.peff.net","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-24T06:05:29Z","receivedAt":"2011-09-24T06:05:29Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/23/2011 09:33 PM, Jeff King wrote:\n> [1] I really wish we had an elegant way of versioning meta-information\n>     about a repository (like config, info/attributes, etc). I've hacked\n>     around this before by having a special meta-branch for each repo,\n>     checkout it out in an alternate directory, and then symlinking bits\n>     of it into .git. But that's kind of ugly, too.\n> \n>     I'm not sure what a good solution would look like. There's a real\n>     can of worms with respect to picking and choosing local versus\n>     remote bits of meta-information, with some security implications.\n\nThis could be implemented by having a single local config option that\nenables the use of an in-tree .gitconfig file:\n\n    git config core.useTreeConfig true\n\n(or whatever the correct naming convention would be).  This option would\ndefault to false, so the in-tree config would only occur following an\naffirmative decision by the cloner.\n\nIf finer granularity is required, config options could be classified\ninto \"security-relevant\" and \"non-security-relevant\" options, where the\nformer group basically includes anything that can cause arbitrary code\nto be executed.  Then there could be a \"core.useTreeConfig = safeonly\"\noption to allow only the harmless options.\n\nI think the priority of config options (highest to lowest) should be\n\n       $GIT_DIR/config\n       in-tree .gitconfig\n       ~/.gitconfig\n       $(prefix)/etc/gitconfig\n\nOf course, just like for attributes, it would have to be decided which\nversion of the .gitconfig to use in which situations.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"176119","messageId":"20110924061555.GB13974@sigill.intra.peff.net","threadId":"28458","inReplyTo":"4E7D7329.7070800@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-24T06:15:55Z","receivedAt":"2011-09-24T06:15:55Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Sep 24, 2011 at 08:05:29AM +0200, Michael Haggerty wrote:\n\n> This could be implemented by having a single local config option that\n> enables the use of an in-tree .gitconfig file:\n> \n>     git config core.useTreeConfig true\n> \n> (or whatever the correct naming convention would be).  This option would\n> default to false, so the in-tree config would only occur following an\n> affirmative decision by the cloner.\n\nBut once you've verified that the config looks OK and turned this option\non, how do you protect yourself from malicious config entering the repo\nthrough a fetch?\n\n> If finer granularity is required, config options could be classified\n> into \"security-relevant\" and \"non-security-relevant\" options, where the\n> former group basically includes anything that can cause arbitrary code\n> to be executed.  Then there could be a \"core.useTreeConfig = safeonly\"\n> option to allow only the harmless options.\n\nThis is the \"can of worms\" I referred to earlier. You have to start\nclassifying each option.\n\n> I think the priority of config options (highest to lowest) should be\n> \n>        $GIT_DIR/config\n>        in-tree .gitconfig\n>        ~/.gitconfig\n>        $(prefix)/etc/gitconfig\n\nOne catch with any precedence scheme is that there are certain config\nconstructs that cannot be overridden. For example, some options are\nrespected multiple times to form a list (e.g., remote fetch and push\nrefspecs). There's no way in you $GIT_DIR/config to say \"forget all of\nthe previous values you saw for this key\" that may have come from the\nin-tree .gitconfig.\n\nI think you could introduce a special syntax for that, maybe just:\n\n  # make a list with two elements\n  [foo]\n    bar = one\n    bar = two\n\n  # now let's imagine this is our \"reset\" syntax\n    bar =\n  # and now we can put in our own new values\n    bar = three\n\nwhere the final value of the config above would be (three).\n\nIt's actually not a new problem with in-tree config, and it doesn't tend\nto come up all that much because most config values are treated as\nsimple scalars, and later values overwrite earlier ones.\n\n> Of course, just like for attributes, it would have to be decided which\n> version of the .gitconfig to use in which situations.\n\nI'm not sure it makes sense to have it in the tree at all. For\nattributes it makes sense, because you are annotating a path at a\n_specific_ revision. But config is often much more meta- than that.\nTake textconv for an example. The gitattributes say \"foo.pdf should use\nthe 'pdf' diff driver\". That makes sense to go in a revision. But the\nconfig will say \"pdf files can be converted to text using\n/usr/bin/pdftotext\". That is not something that is tied to the revision\nat all, and should exist outside of any revision. I.e., whether I am\ndoing a \"git show\" on the HEAD, or on some ancient commit, I would want\nto use the same value, not whatever tool I used to convert PDFs years\nago.\n\n-Peff\n"},{"id":"176124","messageId":"4E7DB916.6010606@alum.mit.edu","threadId":"28458","inReplyTo":"20110924061555.GB13974@sigill.intra.peff.net","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-24T11:03:50Z","receivedAt":"2011-09-24T11:03:50Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/24/2011 08:15 AM, Jeff King wrote:\n> On Sat, Sep 24, 2011 at 08:05:29AM +0200, Michael Haggerty wrote:\n>> This could be implemented by having a single local config option that\n>> enables the use of an in-tree .gitconfig file:\n>>\n>>     git config core.useTreeConfig true\n>>\n>> (or whatever the correct naming convention would be).  This option would\n>> default to false, so the in-tree config would only occur following an\n>> affirmative decision by the cloner.\n> \n> But once you've verified that the config looks OK and turned this option\n> on, how do you protect yourself from malicious config entering the repo\n> through a fetch?\n\nFor most software projects, the user does\n\n    git pull\n    make\n\ndaily.  There is nothing that a nasty .gitconfig can do that can't be\ndone more easily by a nasty Makefile (or anything else in the build\nprocess).  The moment I pull from Junio's repository and run a build\nwithout having personally done a full code review first, I've given\nJunio complete pownership of my account.  For projects in which I invest\nsuch trust, \"core.useTreeConfig=true\" would be a convenience that does\nnot appreciably increase my risk.\n\n>> If finer granularity is required, config options could be classified\n>> into \"security-relevant\" and \"non-security-relevant\" options, where the\n>> former group basically includes anything that can cause arbitrary code\n>> to be executed.  Then there could be a \"core.useTreeConfig = safeonly\"\n>> option to allow only the harmless options.\n> \n> This is the \"can of worms\" I referred to earlier. You have to start\n> classifying each option.\n\nIt is not a \"can of worms\" in the sense of insoluble.  It is only a lot\nof work.  We could start today by setting a default that all config\noptions are dangerous, incrementally opening up options as they are vetted.\n\n>> I think the priority of config options (highest to lowest) should be\n>>\n>>        $GIT_DIR/config\n>>        in-tree .gitconfig\n>>        ~/.gitconfig\n>>        $(prefix)/etc/gitconfig\n> \n> One catch with any precedence scheme is that there are certain config\n> constructs that cannot be overridden.\n\nGood point, and good suggestion to allow config constructs to be cleared.\n\n>> Of course, just like for attributes, it would have to be decided which\n>> version of the .gitconfig to use in which situations.\n> \n> I'm not sure it makes sense to have it in the tree at all. For\n> attributes it makes sense, because you are annotating a path at a\n> _specific_ revision. But config is often much more meta- than that.\n> Take textconv for an example. The gitattributes say \"foo.pdf should use\n> the 'pdf' diff driver\". That makes sense to go in a revision. But the\n> config will say \"pdf files can be converted to text using\n> /usr/bin/pdftotext\". That is not something that is tied to the revision\n> at all, and should exist outside of any revision. I.e., whether I am\n> doing a \"git show\" on the HEAD, or on some ancient commit, I would want\n> to use the same value, not whatever tool I used to convert PDFs years\n> ago.\n\nThere are obviously config options that should not be versioned.  These\nshould not be stored in the tree.  (Perhaps they should be stored in\nanother branch, as you suggested.)  But there's no need to prevent\npeople from versioning *any* config options just because they shouldn't\nversion *all* of them.\n\nI think that your \"config-file includes\" proposal would make all of this\npossible or nearly possible, but I'll have to read your proposal more\ncarefully before I can comment.\n\n\nWhile we are on the topic of config settings, I have often thought that\nit would be nice for git's default settings to be set via a\nwell-commented config file, installed along with git, rather than via\nvalues compiled into the code.  This file and Documentation/config.txt\ncould be generated from a single source file as part of the build\nprocess.  Advantages:\n\n1. It would give a single place for people to see exactly what defaults\nare being applied, and a good starting point for seeing what can be\nchanged locally.\n\n2. It would ensure that the defaults listed in the documentation always\nmatch those being used, and prevent different default values from being\nused in different places in the code.\n\n3. It would make it easy to discover what default values have changed\nbetween two git versions (i.e., what new knobs there are to turn).\n\n4. It would make it easy for packagers to tweak the built-in defaults,\nand would make it obvious what defaults packagers had changed.  (Of\ncourse packagers can already just include an /etc/gitconfig, but it\nwould be better to reserve that file for sitewide changes).\n\nThe priority would obviously be:\n\n        $GIT_DIR/config\n        in-tree .gitconfig\n        ~/.gitconfig\n        $(prefix)/etc/gitconfig\n        git's installed defaults\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"176186","messageId":"7vwrcwq70k.fsf@alter.siamese.dyndns.org","threadId":"28458","inReplyTo":"4E7DB916.6010606@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-26T04:09:31Z","receivedAt":"2011-09-26T04:09:31Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> On 09/24/2011 08:15 AM, Jeff King wrote:\n> For most software projects, the user does\n>\n>     git pull\n>     make\n>\n> daily.  There is nothing that a nasty .gitconfig can do that can't be\n> done more easily by a nasty Makefile (or anything else in the build\n> process).  The moment I pull from Junio's repository and run a build\n> without having personally done a full code review first, I've given\n> Junio complete pownership of my account.\n\nI suspect that argument is somewhat leaky.\n\nWill I be the _only_ one you will be pulling from?  What if I were not so\ncareful and relay a contaminated in-tree configuration file (which I would\nnever use myself) to trusting downstream users like you?\n\n>> I'm not sure it makes sense to have it in the tree at all. For\n>> attributes it makes sense, because you are annotating a path at a\n>> _specific_ revision. But config is often much more meta- than that.\n>> Take textconv for an example. The gitattributes say \"foo.pdf should use\n>> the 'pdf' diff driver\". That makes sense to go in a revision. But the\n>> config will say \"pdf files can be converted to text using\n>> /usr/bin/pdftotext\". That is not something that is tied to the revision\n>> at all, and should exist outside of any revision. I.e., whether I am\n>> doing a \"git show\" on the HEAD, or on some ancient commit, I would want\n>> to use the same value, not whatever tool I used to convert PDFs years\n>> ago.\n\nI agree 100% with Peff on this point. What pdfviewer is configured to be\nused for my repository is tied closely to what I happen to have installed\non my box that I use that repository on. This is not by accident but by\ndesign why attributes only specify what _kind_ of payload is in the path,\nand leave it up to the config to say _how_ to handle each kind of payload\non the box).\n"},{"id":"176187","messageId":"4E7FFF6E.4070906@alum.mit.edu","threadId":"28458","inReplyTo":"7vwrcwq70k.fsf@alter.siamese.dyndns.org","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-26T04:28:30Z","receivedAt":"2011-09-26T04:28:30Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/26/2011 06:09 AM, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n> \n>> On 09/24/2011 08:15 AM, Jeff King wrote:\n>> For most software projects, the user does\n>>\n>>     git pull\n>>     make\n>>\n>> daily.  There is nothing that a nasty .gitconfig can do that can't be\n>> done more easily by a nasty Makefile (or anything else in the build\n>> process).  The moment I pull from Junio's repository and run a build\n>> without having personally done a full code review first, I've given\n>> Junio complete pownership of my account.\n> \n> I suspect that argument is somewhat leaky.\n> \n> Will I be the _only_ one you will be pulling from?  What if I were not so\n> careful and relay a contaminated in-tree configuration file (which I would\n> never use myself) to trusting downstream users like you?\n\nI'm not saying that trusting in-tree configuration files makes sense for\neverybody, and in the open-source world one must be very careful about\ndoing so.  But I think that among closely-cooperating groups (e.g.,\npersonal projects, many projects in industry) (1) we don't pull from\noutside the group and (2) we are forced to trust each other pretty\ncompletely anyway.  So I think that there are many sane use-cases for\ngiving users the opportunity to \"bless\" an in-tree config.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"176197","messageId":"20110926110552.GA20796@sigill.intra.peff.net","threadId":"28458","inReplyTo":"4E7DB916.6010606@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-09-26T11:05:52Z","receivedAt":"2011-09-26T11:05:52Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Sep 24, 2011 at 01:03:50PM +0200, Michael Haggerty wrote:\n\n> > But once you've verified that the config looks OK and turned this option\n> > on, how do you protect yourself from malicious config entering the repo\n> > through a fetch?\n> \n> For most software projects, the user does\n> \n>     git pull\n>     make\n> \n> daily.  There is nothing that a nasty .gitconfig can do that can't be\n> done more easily by a nasty Makefile (or anything else in the build\n> process).  The moment I pull from Junio's repository and run a build\n> without having personally done a full code review first, I've given\n> Junio complete pownership of my account.  For projects in which I invest\n> such trust, \"core.useTreeConfig=true\" would be a convenience that does\n> not appreciably increase my risk.\n\nTrue. I think it would be nice for their to be a less risky option, too,\nthough.  Which was part of the motivation in my earlier proposal for\nspecifying a ref that contains config. Then you can ignore it, track\nyour own local config which is derived from upstream, or do the easy but\ndangerous thing of just using the remote tracking ref directly.\n\n> There are obviously config options that should not be versioned.  These\n> should not be stored in the tree.  (Perhaps they should be stored in\n> another branch, as you suggested.)  But there's no need to prevent\n> people from versioning *any* config options just because they shouldn't\n> version *all* of them.\n\nDo you have an example of a config option whose old value should be\nrespected when looking at an old version? In general, the split between\nattributes and config was meant to split what is tied to a specific\nversion, and what should apply to all versions. We may not have followed\nthat in all cases, but if so, the right solution may actually be\nmigrating the functionality into .gitattributes.\n\n> While we are on the topic of config settings, I have often thought that\n> it would be nice for git's default settings to be set via a\n> well-commented config file, installed along with git, rather than via\n> values compiled into the code.  This file and Documentation/config.txt\n> could be generated from a single source file as part of the build\n> process.\n\nI think that can be a nice piece of documentation, but there may be some\ncomplications.  I seem to recall that there may be one or two options\nwhose builtin values cannot be replicated via config (i.e., the \"unset\"\nstate means something). But I may be misremembering.\n\nHowever, I'm not sure what you mean by \"rather than via values compiled\ninto the code\".  Would you somehow generate code that sets the default\naccording to your master file? Would git fail to start if the file is\nmissing? Or if a specific config option is missing? How would you track\nthat?\n\n-Peff\n"},{"id":"176208","messageId":"201109261614.09315.jnareb@gmail.com","threadId":"28458","inReplyTo":"20110926110552.GA20796@sigill.intra.peff.net","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-09-26T14:14:07Z","receivedAt":"2011-09-26T14:14:07Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jeff King wrote:\n> On Sat, Sep 24, 2011 at 01:03:50PM +0200, Michael Haggerty wrote:\n \n> > While we are on the topic of config settings, I have often thought that\n> > it would be nice for git's default settings to be set via a\n> > well-commented config file, installed along with git, rather than via\n> > values compiled into the code.  This file and Documentation/config.txt\n> > could be generated from a single source file as part of the build\n> > process.\n> \n> I think that can be a nice piece of documentation, but there may be some\n> complications.  I seem to recall that there may be one or two options\n> whose builtin values cannot be replicated via config (i.e., the \"unset\"\n> state means something). But I may be misremembering.\n> \n> However, I'm not sure what you mean by \"rather than via values compiled\n> into the code\".  Would you somehow generate code that sets the default\n> according to your master file? Would git fail to start if the file is\n> missing? Or if a specific config option is missing? How would you track\n> that?\n\nThere is also problem that it would screw up Git deprecation policy.\n * new behavior is introduced, with a knob that defaults to off\n * after some time knob starts to default to on\n * git uses new feature by default\n\nWith Git creating config file with state of config variables frozen at\nthe state of repository creation this would be not possible.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"176215","messageId":"4E809635.9050808@alum.mit.edu","threadId":"28458","inReplyTo":"20110926110552.GA20796@sigill.intra.peff.net","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-09-26T15:11:49Z","receivedAt":"2011-09-26T15:11:49Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/26/2011 01:05 PM, Jeff King wrote:\n> On Sat, Sep 24, 2011 at 01:03:50PM +0200, Michael Haggerty wrote:\n>> There are obviously config options that should not be versioned.  These\n>> should not be stored in the tree.  (Perhaps they should be stored in\n>> another branch, as you suggested.)  But there's no need to prevent\n>> people from versioning *any* config options just because they shouldn't\n>> version *all* of them.\n> \n> Do you have an example of a config option whose old value should be\n> respected when looking at an old version? In general, the split between\n> attributes and config was meant to split what is tied to a specific\n> version, and what should apply to all versions. We may not have followed\n> that in all cases, but if so, the right solution may actually be\n> migrating the functionality into .gitattributes.\n\nI hadn't realized this point about the split between gitconfig and\ngitattributes.  It makes sense.  I'd been thinking that it would be nice\nto be able to share changes to the git config the same way that source\ncode is shared, but you are right that the git config is versioned\ndifferently than the source code.  I can't think of any counterexamples\nright now.\n\n>> While we are on the topic of config settings, I have often thought that\n>> it would be nice for git's default settings to be set via a\n>> well-commented config file, installed along with git, rather than via\n>> values compiled into the code.  This file and Documentation/config.txt\n>> could be generated from a single source file as part of the build\n>> process.\n> \n> I think that can be a nice piece of documentation, but there may be some\n> complications.  I seem to recall that there may be one or two options\n> whose builtin values cannot be replicated via config (i.e., the \"unset\"\n> state means something). But I may be misremembering.\n\nThis is more a reason to implement a way to \"unset\" options than an\nargument against storing git's builtin defaults in a gitconfig-formatted\nfile.\n\n> However, I'm not sure what you mean by \"rather than via values compiled\n> into the code\".  Would you somehow generate code that sets the default\n> according to your master file? Would git fail to start if the file is\n> missing? Or if a specific config option is missing? How would you track\n> that?\n\nI think that git should read its \"as-installed\" config file at runtime\nto maximize the transparency.  If the file is missing then git should\nfail, just as it would if some other important part of git were missing\nfrom an install.  The absence of a required config option would be a bug\nand might cause git to abort just like any other bug.\n\nI probably shouldn't mention this lest people realize that I'm stupid\nand ugly, but...\n\nSubversion installs a file with all of its defaults into your\n~/.subversion directory the first time that it runs.  I find this\nfeature to be very helpful as a source of examples and to learn new\nfeatures.  But they do it a bit differently than I am proposing for\ngit--the file is written to the user's ~/.subversion, and is\nsubsequently edited by the user.  Because the file lives across\nSubversion upgrades, the options in this file are *commented out* to\nprevent them causing trouble in the future; i.e., they are for human\nconsumption only.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"184895","messageId":"4F3E9F86.3070802@alum.mit.edu","threadId":"28458","inReplyTo":"7vy5xh1whq.fsf@alter.siamese.dyndns.org","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2012-02-17T18:42:14Z","receivedAt":"2012-02-17T18:42:14Z","isPatch":false,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/21/2011 10:17 PM, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n>> I was thinking of using git attributes to configure a server-side\n>> \"update\" hook that does some basic sanity checking before accepting a\n>> push.  I thought I could do something like\n>> [...]\n>> I see that there is an (undocumented) API involving\n>> git_attr_set_direction() that seems to let gitattributes to be read out\n>> of the index instead of the working tree.  But I am still confused:\n> \n> The words \"server side\" automatically mean that there should be no working\n> tree, and where there is no working tree there should be no index, so the\n> direction should not make any difference.  The attributes that are used to\n> help whitespace checks should come from project.git/info/attributes in\n> such a case [*...*].\n\nI was just alerted by Scott Chacon's blog [1] to the fact that one can\nset GIT_INDEX_FILE to an arbitrary filename, thereby causing the index\nto be read/written from that file instead of $GIT_DIR/index.  It\noccurred to me that this feature, along with the addition of \"git\ncheck-attr --cached\" in 1.7.8, can be used to give server-side access to\nthe gitattributes for an arbitrary commit:\n\n    GIT_INDEX_FILE=\"$(tempfile)\"\n    export GIT_INDEX_FILE\n    git read-tree $COMMIT\n    git check-attr --cached attr -- pathname\n    ...\n    rm \"$GIT_INDEX_FILE\"\n\nEmpirically it seems to work (and it is surprisingly fast).  The use of\na temporary file prevents simultaneous accesses to the repository from\nstepping on each other.  This looks like a clean solution to my problem.\n Or is there some hidden pitfall in this approach?\n\nMichael\n\n[1] http://progit.org/2010/04/11/environment.html\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"184901","messageId":"7vd39dtg5t.fsf@alter.siamese.dyndns.org","threadId":"28458","inReplyTo":"4F3E9F86.3070802@alum.mit.edu","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-02-17T19:26:38Z","receivedAt":"2012-02-17T19:26:38Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> I was just alerted by Scott Chacon's blog [1] to the fact that one can\n> set GIT_INDEX_FILE to an arbitrary filename, thereby causing the index\n> to be read/written from that file instead of $GIT_DIR/index.\n\nThat's very old fashioned.  For almost five years, the preferred way to\nsay that has been \"git read-tree --index-output=file\" ;-)\n\nBut what you outlined should work.\n"},{"id":"184903","messageId":"7vy5s1s01w.fsf@alter.siamese.dyndns.org","threadId":"28458","inReplyTo":"7vd39dtg5t.fsf@alter.siamese.dyndns.org","subject":"Re: How to use git attributes to configure server-side checks?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-02-17T19:59:55Z","receivedAt":"2012-02-17T19:59:55Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n>\n>> I was just alerted by Scott Chacon's blog [1] to the fact that one can\n>> set GIT_INDEX_FILE to an arbitrary filename, thereby causing the index\n>> to be read/written from that file instead of $GIT_DIR/index.\n>\n> That's very old fashioned.  For almost five years, the preferred way to\n> say that has been \"git read-tree --index-output=file\" ;-)\n\nAh, I take that back.\n\nThere is any benefit to be had by using \"read-tree --index-output\" in the\nway used in your check-attr example.  Setting up a single GIT_INDEX_FILE\nand using it throughout as you did is indeed much more preferrable.\n\n> But what you outlined should work.\n"}]}