{"thread":{"id":"2615","subject":"Get rid of .git/branches/ and .git/remotes/?","startedAt":"2005-11-20T17:00:52Z","lastAt":"2005-11-28T10:51:51Z","messageCount":62,"participants":["Johannes Schindelin","Linus Torvalds","Sven Verdoolaege","Andreas Ericsson","Josef Weidendorfer","Junio C Hamano","Ryan Anderson","Petr Baudis","Lars Magne Ingebrigtsen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"12376","messageId":"Pine.LNX.4.63.0511201748440.14258@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":null,"subject":"Get rid of .git/branches/ and .git/remotes/?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-20T17:00:52Z","receivedAt":"2005-11-20T17:00:52Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nI just had a crazy idea. Since we have a framework in place to read/write \n.git/config, I thought that maybe it would be a nice thing to move the \ninformation which is in .git/branches or .git/remotes into the config.\n\nAdvantages:\n\n- it would be easy to copy your private configuration by copying just one \n  file,\n\n- it would be easy to add a switch to git-fetch/git-pull to actually\n  store/update the URL and head mapping under a certain nick,\n\n- we could get rid of some parsing code, and\n\n- it would arguably be more consistent.\n\nDisadvantage:\n\n- I know, I know, yet another change to the location of this \n  information...\n\n- (very lame) you could not find out which nicks you have stored with \"ls\"\n\nComments?\n\nCiao,\nDscho\n\nP.S.: I did not yet say anything about .git/info/, did I?\n"},{"id":"12379","messageId":"Pine.LNX.4.64.0511200935081.13959@g5.osdl.org","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511201748440.14258@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-20T18:09:50Z","receivedAt":"2005-11-20T18:09:50Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 20 Nov 2005, Johannes Schindelin wrote:\n> \n> I just had a crazy idea. Since we have a framework in place to read/write \n> .git/config, I thought that maybe it would be a nice thing to move the \n> information which is in .git/branches or .git/remotes into the config.\n\nI considered it, but thee thing is, it really wants \"nested names\", ie \nhaving multi-level base-names for the variables. At the same time, I \nabsolutely _abhor_ horrible crap like XML, which make nesting a \nfundamental part of their structure.\n\nXML may be \"logical\", but it has absolutely zero to do with being \nhuman-readable and clean. In short, XML is total and absolute CRAP (in \nfact, the \"X\" in \"XML\" stands for \"Crap\", but the XML designers were also \nincredibly bad spellers).\n\nSo while the basic notion of the git ini file does support nesting (we \ncould just make variable names be \"base.level1.final\" or any number of \nlevels deep), I don't know what a sane format would be. I have one \nsuggestion that in my opinion \"fits\" the .ini file syntax (see below), but \npeople may well hate it.\n\nBasically I've considered saying that one or more '.' characters at the \nstart of a section name would mean \"re-use the previous one\", so we could \nhave (this is a really bad example, just to show the implications):\n\n\t[core]\n\t\t[.values]\n\t\t\tfixed = true\n\t\t\tnested = fine\n\t\t\t[..example]\n\t\t\t\ttest = Hell yes\n\t\t[.other]\n\t\t\texample = strange\n\t\t[.]\n\t\t\tname = hi\n\n\t[section]\n\t\texample = yet another\n\nand that would result in a parse of\n\n\tcore.values.fixed = true\n\tcore.values.nested = fine\n\tcore.values.example.test = Hell yes\n\tcore.other.example = strange\n\tcore.name = hi\n\tsecontion.example = yet another\n\nand that seems reasonably clean. I'd also allow explicit \nmulti-level section names:\n\n\t[core.values]\n\t\tfixed = true\n\nso you could always write the above config file in an alternate format:\n\n\t[core.values] fixed = true\n\t[core.values] nested = fine\n\t[core.values.example] test = Hell yes\n\t[core.other] example = strange\n\t[core] name = hi\n\t[section] example = yet another\n\ninstead, using no implicit nesting at all (or, indeed, even re-using \nsections like \"core.values\").\n\nThat would allow things like\n\n\t[branches]\n\t\t[.origin]\n\t\t\turl = master.kernel.org:/pub/scm/git/git.git\n\t\t\tpull = master:origin\n\t\t[.mine]\n\t\t\turl = my.domain.com:/other/repo\n\t\t\tpull = master:mine\n\n(which could also be written as\n\n\t[branches.origin]\n\t\turl = master.kernel.org:/pub/scm/git/git.git\n\t\tpull = master:origin\n\n\t[branches.mine]\n\t\turl = my.domain.com:/other/repo\n\t\tpull = master:mine\n\nand the following mixed-indentation usage would be technically correct, \nbut perhaps crazy:\n\n\t[branches.origin]\n\t\turl = master.kernel.org:/pub/scm/git/git.git\n\t\tpull = master:origin\n\n\t    [.mine]\n\t\turl = my.domain.com:/other/repo\n\t\tpull = master:mine\n\nBasically, right now we only allow alphanumeric characters in the base \nname, and a new section name completely clears the old one. The above \nwould be a very simple extension of that: we would allow '.' in addition \nto alphanumerics, and any initial '.' characters would _keep_ that many \nlevels of the old name.\n\nI dunno. That seems a nice extension, and it would make these things \nvery unambiguous. But how do other .ini-file-like things do this?\n\nAnd I'm not 100% convinced that putting these branches in the config file \nhas any real advantages over keeping them as separate files. Having \neverything in one place is nice, of course, and being able to copy just \none file around might be convenient, but it _does_ make the config file \nmore complicated.\n\nAnyway, if you want to play with this, here's a trivial patch that may or \nmay not work.\n\n\t\tLinus\n\n----\ndiff --git a/config.c b/config.c\nindex 915bb97..3b9f300 100644\n--- a/config.c\n+++ b/config.c\n@@ -136,6 +136,19 @@ static int get_base_var(char *name)\n \t\t\treturn -1;\n \t\tif (c == ']')\n \t\t\treturn baselen;\n+\t\tif (c == '.') {\n+\t\t\tif (!baselen || name[baselen-1] == '.') {\n+\t\t\t\tfor (;;) {\n+\t\t\t\t\tif (!name[baselen])\n+\t\t\t\t\t\treturn -1;\n+\t\t\t\t\tif (name[baselen++] == '.')\n+\t\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tname[baselen++] = c;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!isalnum(c))\n \t\t\treturn -1;\n \t\tif (baselen > MAXNAME / 2)\n"},{"id":"12383","messageId":"20051120182943.GG8383MdfPADPa@greensroom.kotnet.org","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511200935081.13959@g5.osdl.org","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2005-11-20T18:29:43Z","receivedAt":"2005-11-20T18:29:43Z","isPatch":false,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Sun, Nov 20, 2005 at 10:09:50AM -0800, Linus Torvalds wrote:\n> and that would result in a parse of\n> \n> \tcore.values.fixed = true\n> \tcore.values.nested = fine\n> \tcore.values.example.test = Hell yes\n> \tcore.other.example = strange\n> \tcore.name = hi\n> \tsecontion.example = yet another\n> \n\n[..]\n\n> I dunno. That seems a nice extension, and it would make these things \n> very unambiguous. But how do other .ini-file-like things do this?\n\nNot sure if this falls in the \".ini-file-like\" category, but\nYAML (www.yaml.org) does nesting based on indentation.\nYour example would look like\n\ncore:\n  values:\n    fixed: true\n    nested: fine\n    example:\n      test: Hell yes\n  other:\n    example: strange\n  name: hi\nsecontion:\n  example: yet another\n\nor\n\ncore:\n  values: { fixed: true, nested: fine, example: { test: Hell yes } }\n  other: { example: strange }\n  name: hi\nsecontion: { example: 'yet another' }\n\nskimo\n"},{"id":"12384","messageId":"Pine.LNX.4.64.0511201103280.13959@g5.osdl.org","threadId":"2615","inReplyTo":"20051120182943.GG8383MdfPADPa@greensroom.kotnet.org","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-20T19:07:49Z","receivedAt":"2005-11-20T19:07:49Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 20 Nov 2005, Sven Verdoolaege wrote:\n> \n> Not sure if this falls in the \".ini-file-like\" category, but\n> YAML (www.yaml.org) does nesting based on indentation.\n\nThe main reason I don't like indentation is that it tends to have strange \nrules for \"tab\". Some people (incorrectly, of course) think that tabs are \nnot at fixed 8-byte things, so deciding the indentation of a tab often \nends up either disallowing tabs altogether (bad) or having other strange \nrules (disallowing spaces).\n\nSo I'm not religiously opposed to it, but I find it to be less than \noptimal.\n\nI'd rather have just _pure_ braces, but while that is natural to \nprogrammers, it's not very natural to most users, I think.\n\n\t\tLinus\n"},{"id":"12385","messageId":"4380CBAA.9010708@op5.se","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511201103280.13959@g5.osdl.org","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2005-11-20T19:16:58Z","receivedAt":"2005-11-20T19:16:58Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Linus Torvalds wrote:\n> \n> I'd rather have just _pure_ braces, but while that is natural to \n> programmers, it's not very natural to most users, I think.\n> \n\nSysadmins should be used to braces too (xinetd, dhcpd, named...).\n\nHow many office clerks do you expect to use git?\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"12386","messageId":"Pine.LNX.4.63.0511202039340.23586@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511200935081.13959@g5.osdl.org","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-20T19:50:41Z","receivedAt":"2005-11-20T19:50:41Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 20 Nov 2005, Linus Torvalds wrote:\n\n> \t[branches.origin]\n> \t\turl = master.kernel.org:/pub/scm/git/git.git\n> \t\tpull = master:origin\n> \n> \t[branches.mine]\n> \t\turl = my.domain.com:/other/repo\n> \t\tpull = master:mine\n\nI like this approach best. In fact, that was my idea on how to go about \nimplementing that feature.\n\nHowever, \n\n> \t[branches.origin]\n> \t\turl = master.kernel.org:/pub/scm/git/git.git\n> \t\tpull = master:origin\n> \n> \t    [.mine]\n> \t\turl = my.domain.com:/other/repo\n> \t\tpull = master:mine\n\nI don't like this. Usually, data in ini files is not dependent on its \nposition in the file, with the notable exception of section names. I never \nran across nested sections (probably for all the reasons XML is \nunreadable). And the sections should be exchangable, just for clarities \nsake.\n\n> And I'm not 100% convinced that putting these branches in the config file \n> has any real advantages over keeping them as separate files. Having \n> everything in one place is nice, of course, and being able to copy just \n> one file around might be convenient, but it _does_ make the config file \n> more complicated.\n\nAnd it _does_ make finding the information for less savvy git users more \neasy.\n\nI'm not 100% convinced, either, but it could be a better concept than \ndifferent files in different places and different formats basically doing \nthe same.\n\nBut my thinking went like this: if Pasky and Junio can not agree on one \nlocation and format, and therefore none of the two is deprecated, how \nabout giving them a way out they both might be able to agree to?\n\nCiao,\nDscho\n\nP.S.: Anybody noticed that I did not use 0xb4 in five days?\n"},{"id":"12399","messageId":"200511210026.30280.Josef.Weidendorfer@gmx.de","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511200935081.13959@g5.osdl.org","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2005-11-20T23:26:30Z","receivedAt":"2005-11-20T23:26:30Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Sunday 20 November 2005 19:09, Linus Torvalds wrote:\n> \t[branches.origin]\n> \t\turl = master.kernel.org:/pub/scm/git/git.git\n> \t\tpull = master:origin\n\nTwo things:\n* base names are case insensitive. Repository shortcuts are case\nsensitive (and head names, too)\n* to get rid of .git/branches/XXX, XXX has to be allowed as\nbase name. But XXX can contain anything a head name can (including \".\").\n\nNot really a problem. Use the ' for ' syntax:\n\n[remotes]\n\turl = master.kernel.org:/pub/scm/git/git.git for origin\n\tpull = master:origin for origin\n\nNot really nice. We can not have \"for\" as head name.\n\nJosef\n"},{"id":"12403","messageId":"Pine.LNX.4.63.0511210054260.24828@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"200511210026.30280.Josef.Weidendorfer@gmx.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-20T23:58:34Z","receivedAt":"2005-11-20T23:58:34Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 21 Nov 2005, Josef Weidendorfer wrote:\n\n> On Sunday 20 November 2005 19:09, Linus Torvalds wrote:\n> > \t[branches.origin]\n> > \t\turl = master.kernel.org:/pub/scm/git/git.git\n> > \t\tpull = master:origin\n> \n> Two things:\n> * base names are case insensitive. Repository shortcuts are case\n> sensitive (and head names, too)\n> * to get rid of .git/branches/XXX, XXX has to be allowed as\n> base name. But XXX can contain anything a head name can (including \".\").\n\nIs it that important that nicks can be case sensitive or contain spaces or \ndots? I.e. is it sensible to make a difference between\n\n\tgit pull Weidendorfer\n\nand\n\n\tgit pull weidendorfer\n???\n\nAlso, I'd rather write\n\n\tgit pull josef\n\nthan\n\n\tgit pull \"Josef Weidendorfer, III\"\n\n> Not really a problem. Use the ' for ' syntax:\n> \n> [remotes]\n> \turl = master.kernel.org:/pub/scm/git/git.git for origin\n> \tpull = master:origin for origin\n> \n> Not really nice. We can not have \"for\" as head name.\n\nNot really nice. Looks ugly. Violates DRY. (\"for blabla\" would not need to \nbe a problem; just enforce quotes around the name.)\n\nCiao,\nDscho\n"},{"id":"12548","messageId":"200511221831.03954.Josef.Weidendorfer@gmx.de","threadId":"2615","inReplyTo":"200511210026.30280.Josef.Weidendorfer@gmx.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2005-11-22T17:31:03Z","receivedAt":"2005-11-22T17:31:03Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Monday 21 November 2005 00:26, Josef Weidendorfer wrote:\n> On Sunday 20 November 2005 19:09, Linus Torvalds wrote:\n> > \t[branches.origin]\n> > \t\turl = master.kernel.org:/pub/scm/git/git.git\n> > \t\tpull = master:origin\n> \n> Two things:\n> * base names are case insensitive. Repository shortcuts are case\n> sensitive (and head names, too)\n> * to get rid of .git/branches/XXX, XXX has to be allowed as\n> base name. But XXX can contain anything a head name can (including \".\").\n> \n> Not really a problem. Use the ' for ' syntax:\n> \n> [remotes]\n> \turl = master.kernel.org:/pub/scm/git/git.git for origin\n> \tpull = master:origin for origin\n> \n> Not really nice. We can not have \"for\" as head name.\n\nWhat about another syntax for multivalue vars?\nProposed syntax:\n\n  [remote:origin]\n    url = master.kernel.org:/pub/scm/git/git.git\n    pull = master:origin\n\nFor this, the parser could return\n    remote.url = master.kernel.org:/pub/scm/git/git.git for origin\n    remote.pull = master:origin for origin\n\nBy introducing such a scheme, multi-value vars would fit perfectly\nfor use for .git/remotes or .git/branches.\n\nJosef\n"},{"id":"12551","messageId":"Pine.LNX.4.63.0511221854120.27872@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"200511221831.03954.Josef.Weidendorfer@gmx.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-22T17:56:50Z","receivedAt":"2005-11-22T17:56:50Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 22 Nov 2005, Josef Weidendorfer wrote:\n\n>   [remote:origin]\n>     url = master.kernel.org:/pub/scm/git/git.git\n>     pull = master:origin\n> \n> For this, the parser could return\n>     remote.url = master.kernel.org:/pub/scm/git/git.git for origin\n>     remote.pull = master:origin for origin\n> \n> By introducing such a scheme, multi-value vars would fit perfectly\n> for use for .git/remotes or .git/branches.\n\nI don't know if you missed it, but hierarchical config keys were \nintroduced by b17e659dd4007cb1d3eb5ac32b524c0c5ab59601:\n\n[remote.origin]\n\turl = master.kernel.org:/pub/scm/git/git.git\n\tpull = master:origin\n\nis parsable by\n\n\tgit-config-set --get remote.origin.url\n\nnow.\n\nHth,\nDscho\n"},{"id":"12558","messageId":"438371E8.2030701@op5.se","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511221854120.27872@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2005-11-22T19:30:48Z","receivedAt":"2005-11-22T19:30:48Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Johannes Schindelin wrote:\n> \n> \tgit-config-set --get remote.origin.url\n> \n\nSo... \"git-config-set\" is used for both getting and setting? Why not \njust \"git-config --set\" and \"git-config --get\" to make things a bit less \nconfusing?\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"12571","messageId":"200511230005.12957.Josef.Weidendorfer@gmx.de","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511221854120.27872@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2005-11-22T23:05:11Z","receivedAt":"2005-11-22T23:05:11Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Tuesday 22 November 2005 18:56, Johannes Schindelin wrote:\n> On Tue, 22 Nov 2005, Josef Weidendorfer wrote:\n> >   [remote:origin]\n> >     url = master.kernel.org:/pub/scm/git/git.git\n> >     pull = master:origin\n\n> I don't know if you missed it, but hierarchical config keys were \n> introduced by b17e659dd4007cb1d3eb5ac32b524c0c5ab59601:\n> \n> [remote.origin]\n> \turl = master.kernel.org:/pub/scm/git/git.git\n> \tpull = master:origin\n\nI know. My suggestion complements hierarchical keys:\n\n [myporcelain.headproperties: my/head.name]\n    merge.candidates = my/other.head\n    merge.default = your/master\n\nwould be the same as\n\n [myporcelain.headproperties]\n    merge.candidates = my/other.head for my/head.name\n    merge.default = your/master for my/head.name\n\nIt is about specifying the same \" for \"-part for multiple keys.\nThe idea is to use everything after a \":\\s*\" in a section name\nto use as prefix for any \" for \"-part of keys values given in\nthis section.\n\nJosef\n"},{"id":"12621","messageId":"Pine.LNX.4.63.0511231549320.8191@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"200511230005.12957.Josef.Weidendorfer@gmx.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-23T14:53:02Z","receivedAt":"2005-11-23T14:53:02Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 23 Nov 2005, Josef Weidendorfer wrote:\n\n> My suggestion complements hierarchical keys:\n> \n>  [myporcelain.headproperties: my/head.name]\n>     merge.candidates = my/other.head\n>     merge.default = your/master\n> \n> would be the same as\n> \n>  [myporcelain.headproperties]\n>     merge.candidates = my/other.head for my/head.name\n>     merge.default = your/master for my/head.name\n\nOkay. What about this config file?\n\n-- snip --\n\t[myporcelain.headproperties: my/head.name]\n\t\tmerge.candidates = my/other.head\n\t[myporcelain.headproperties]\n\t\tmerge.candidates = blabla for my/head.name\n-- snap --\n\nI am not totally opposed to what you are trying, but I think it \ncontradicts the KISS principle. (Note: the restriction that key names must\nnot start with a digit is also a contradiction to that.)\n\nCiao,\nDscho\n"},{"id":"12623","messageId":"Pine.LNX.4.63.0511231553390.8191@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"438371E8.2030701@op5.se","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-23T15:08:40Z","receivedAt":"2005-11-23T15:08:40Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 22 Nov 2005, Andreas Ericsson wrote:\n\n> Johannes Schindelin wrote:\n> > \n> > \tgit-config-set --get remote.origin.url\n> > \n> \n> So... \"git-config-set\" is used for both getting and setting? Why not just\n> \"git-config --set\" and \"git-config --get\" to make things a bit less confusing?\n\nI tried to do this more like a proof of a concept (Yeah, famous last \nwords...) and tried to be not so intrusive. There is already a config.c, \nand to keep with the naming, this would have to move to config-lib.c to \nmake space for config.c which really is the source for git-config$(X).\n\nShould we rename config.c to config-lib.c, and config-set.c to config.c? \nPersonally, I think it too intrusive, but what the heck.\n\nCiao,\nDscho\n"},{"id":"12624","messageId":"200511231639.59866.Josef.Weidendorfer@gmx.de","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511231549320.8191@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2005-11-23T15:39:58Z","receivedAt":"2005-11-23T15:39:58Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Wednesday 23 November 2005 15:53, Johannes Schindelin wrote:\n> Okay. What about this config file?\n> \n> -- snip --\n> \t[myporcelain.headproperties: my/head.name]\n> \t\tmerge.candidates = my/other.head\n> \t[myporcelain.headproperties]\n> \t\tmerge.candidates = blabla for my/head.name\n> -- snap --\n\nI am not sure you want to show here. Your example gives\n\n myporcelain.headproperties.merge.candidates = my/other.head for my/head.name\n myporcelain.headproperties.merge.candidates = blabla for my/head.name\n\nI.e. 2 values for the same variable with the same \"for\" specification.\nThis is perfectly valid.\n\nAre you talking about the multiple representations for the same thing?\nThen hierarchical config keys already introduce this:\n\n [myporcelain]\n    headproperties.merge.candidates = blabla\n\nis the same as\n\n [myprocelain.headproperties.merge]\n    candidates = blabla\n \n> I am not totally opposed to what you are trying, but I think it \n> contradicts the KISS principle.\n\nThis suggestion is about easier reading of config files; IMHO far easier\nwith some use cases; but yes, it is arguable if it's worth an added\ncomplexity of config.c/config-set.c.\n\nAnd of course this is no issue if config files are only to be written\nby git-config-set. But I do not think this was the goal of the config\nformat.\n\nJosef\n\n> (Note: the restriction that key names must \n> not start with a digit is also a contradiction to that.)\n> \n> Ciao,\n> Dscho\n> \n> -\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n> \n> \n"},{"id":"12629","messageId":"Pine.LNX.4.63.0511231746140.9446@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"200511231639.59866.Josef.Weidendorfer@gmx.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-23T17:22:22Z","receivedAt":"2005-11-23T17:22:22Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 23 Nov 2005, Josef Weidendorfer wrote:\n\n>  [myporcelain]\n>     headproperties.merge.candidates = blabla\n\nWith such a config file, git complains loudly. Key names are only allowed \nto be alphanumerical, and the first letter cannot even be a digit. No \ndots.\n\n> This suggestion is about easier reading of config files; IMHO far easier\n> with some use cases; but yes, it is arguable if it's worth an added\n> complexity of config.c/config-set.c.\n\nWell, I'll be glad to help the implementation of whatever we agree on.\n\nCiao,\nDscho\n"},{"id":"12648","messageId":"7viruj3q7z.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511231553390.8191@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-23T23:21:36Z","receivedAt":"2005-11-23T23:21:36Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> So... \"git-config-set\" is used for both getting and setting? Why not just\n>> \"git-config --set\" and \"git-config --get\" to make things a bit less confusing?\n>\n> I tried to do this more like a proof of a concept (Yeah, famous last \n> words...) and tried to be not so intrusive. There is already a config.c, \n> and to keep with the naming, this would have to move to config-lib.c to \n> make space for config.c which really is the source for git-config$(X).\n>\n> Should we rename config.c to config-lib.c, and config-set.c to config.c? \n> Personally, I think it too intrusive, but what the heck.\n\nI do not think that change is intrusive.  We've renamed source\nfiles number of times ;-).\n\nI somehow get a very funny feeling to see \"git-XXXX --get\"\ncommand that reports different things in different repositories\n(for obvious reasons) called git-config, and not\ngit-repository-config.  But it probably is just me.\n\nAnyway, the whole \"remote specification in config file\" is not a\nvery high priority for me right now.\n"},{"id":"12651","messageId":"4384FB61.40506@op5.se","threadId":"2615","inReplyTo":"7viruj3q7z.fsf@assigned-by-dhcp.cox.net","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2005-11-23T23:29:37Z","receivedAt":"2005-11-23T23:29:37Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> \n> I somehow get a very funny feeling to see \"git-XXXX --get\"\n> command that reports different things in different repositories\n> (for obvious reasons) called git-config, and not\n> git-repository-config.  But it probably is just me.\n> \n\ngit-repo-config is way friendlier for us poor lazy folks. That last 'y' \nin \"repository\" really breaks the flow.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"12653","messageId":"Pine.LNX.4.63.0511240042350.11106@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"4384FB61.40506@op5.se","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-23T23:42:58Z","receivedAt":"2005-11-23T23:42:58Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 24 Nov 2005, Andreas Ericsson wrote:\n\n> git-repo-config is way friendlier for us poor lazy folks. That last 'y' in\n> \"repository\" really breaks the flow.\n\nHow about \"git-local-config\"?\n\nCiao,\nDscho\n"},{"id":"12681","messageId":"43857430.7060103@op5.se","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511240042350.11106@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2005-11-24T08:05:04Z","receivedAt":"2005-11-24T08:05:04Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Johannes Schindelin wrote:\n> Hi,\n> \n> On Thu, 24 Nov 2005, Andreas Ericsson wrote:\n> \n> \n>>git-repo-config is way friendlier for us poor lazy folks. That last 'y' in\n>>\"repository\" really breaks the flow.\n> \n> \n> How about \"git-local-config\"?\n> \n\nNah. It would really mess things up if there's ever such a thing as a \nreal local config (ie, ~/.gitrc).\n\ngit-config-set handles configuration for a particular repo, so \ngit-repo-config is better, IMO.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"12684","messageId":"7vsltmwiky.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"43857430.7060103@op5.se","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-24T08:33:49Z","receivedAt":"2005-11-24T08:33:49Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andreas Ericsson <ae@op5.se> writes:\n\n> git-config-set handles configuration for a particular repo, so \n> git-repo-config is better, IMO.\n\nOk, so git-repo-config that is.  Johannes?\n"},{"id":"12692","messageId":"Pine.LNX.4.63.0511241127020.12985@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"7vsltmwiky.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] Rename git-config-set to git-repo-config","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-24T10:36:01Z","receivedAt":"2005-11-24T10:36:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"... and adjust all references.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\n\tOn Thu, 24 Nov 2005, Junio C Hamano wrote:\n\t\n\t> Andreas Ericsson <ae@op5.se> writes:\n\t> \n\t> > git-config-set handles configuration for a particular repo, so\n\t> > git-repo-config is better, IMO.\n\t> \n\t> Ok, so git-repo-config that is.  Johannes?\n\n\tSorry, git-mv did not work on my system. I can now confirm that\n\tthere is *at least* one perl 5.6 version out there which does not\n\tlike lists in open statements at all. Grmpf.\n\n\tFurther grpmf: Is it intended behaviour that git-diff *detects* \n\trenames, while git-format-patch *doesn't*?\n\n .gitignore                        |    2 +\n Documentation/git-repo-config.txt |   36 +++++++++++++-------------\n Documentation/git.txt             |    6 ++--\n Makefile                          |    2 +\n repo-config.c                     |    2 +\n t/t1300-repo-config.sh            |   52 +++++++++++++++++++------------------\n 6 files changed, 50 insertions(+), 50 deletions(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 074ebe9..0876525 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -17,7 +17,6 @@ git-clone\n git-clone-pack\n git-commit\n git-commit-tree\n-git-config-set\n git-convert-objects\n git-count-objects\n git-cvsexportcommit\n@@ -77,6 +76,7 @@ git-receive-pack\n git-relink\n git-rename\n git-repack\n+git-repo-config\n git-request-pull\n git-reset\n git-resolve\ndiff --git a/Documentation/git-config-set.txt b/Documentation/git-repo-config.txt\nsimilarity index 82%\nrename from Documentation/git-config-set.txt\nrename to Documentation/git-repo-config.txt\nindex bfbd421..92b9156 100644\n--- a/Documentation/git-config-set.txt\n+++ b/Documentation/git-repo-config.txt\n@@ -1,19 +1,19 @@\n-git-config-set(1)\n+git-repo-config(1)\n ===============\n \n NAME\n ----\n-git-config-set - Set options in .git/config.\n+git-repo-config - Get and set options in .git/config.\n \n \n SYNOPSIS\n --------\n-'git-config-set' name [value [value_regex]]\n-'git-config-set' --replace-all name [value [value_regex]]\n-'git-config-set' --get name [value_regex]\n-'git-config-set' --get-all name [value_regex]\n-'git-config-set' --unset name [value_regex]\n-'git-config-set' --unset-all name [value_regex]\n+'git-repo-config' name [value [value_regex]]\n+'git-repo-config' --replace-all name [value [value_regex]]\n+'git-repo-config' --get name [value_regex]\n+'git-repo-config' --get-all name [value_regex]\n+'git-repo-config' --unset name [value_regex]\n+'git-repo-config' --unset-all name [value_regex]\n \n DESCRIPTION\n -----------\n@@ -89,7 +89,7 @@ Given a .git/config like this:\n you can set the filemode to true with\n \n ------------\n-% git config-set core.filemode true\n+% git repo-config core.filemode true\n ------------\n \n The hypothetic proxy command entries actually have a postfix to discern\n@@ -97,7 +97,7 @@ to what URL they apply. Here is how to c\n to \"ssh\".\n \n ------------\n-% git config-set proxy.command '\"ssh\" for kernel.org' 'for kernel.org$'\n+% git repo-config proxy.command '\"ssh\" for kernel.org' 'for kernel.org$'\n ------------\n \n This makes sure that only the key/value pair for kernel.org is replaced.\n@@ -105,7 +105,7 @@ This makes sure that only the key/value \n To delete the entry for renames, do\n \n ------------\n-% git config-set --unset diff.renames\n+% git repo-config --unset diff.renames\n ------------\n \n If you want to delete an entry for a multivar (like proxy.command above),\n@@ -114,45 +114,45 @@ you have to provide a regex matching the\n To query the value for a given key, do\n \n ------------\n-% git config-set --get core.filemode\n+% git repo-config --get core.filemode\n ------------\n \n or\n \n ------------\n-% git config-set core.filemode\n+% git repo-config core.filemode\n ------------\n \n or, to query a multivar:\n \n ------------\n-% git config-set --get proxy.command \"for kernel.org$\"\n+% git repo-config --get proxy.command \"for kernel.org$\"\n ------------\n \n If you want to know all the values for a multivar, do:\n \n ------------\n-% git config-set --get-all proxy.command\n+% git repo-config --get-all proxy.command\n ------------\n \n If you like to live dangerous, you can replace *all* proxy.commands by a\n new one with\n \n ------------\n-% git config-set --replace-all proxy.command ssh\n+% git repo-config --replace-all proxy.command ssh\n ------------\n \n However, if you really only want to replace the line for the default proxy,\n i.e. the one without a \"for ...\" postfix, do something like this:\n \n ------------\n-% git config-set proxy.command ssh '! for '\n+% git repo-config proxy.command ssh '! for '\n ------------\n \n To actually match only values with an exclamation mark, you have to\n \n ------------\n-% git config-set section.key value '[!]'\n+% git repo-config section.key value '[!]'\n ------------\n \n \ndiff --git a/Documentation/git.txt b/Documentation/git.txt\nindex 694fee8..a518249 100644\n--- a/Documentation/git.txt\n+++ b/Documentation/git.txt\n@@ -84,9 +84,6 @@ gitlink:git-checkout-index[1]::\n gitlink:git-commit-tree[1]::\n \tCreates a new commit object\n \n-gitlink:git-config-set[1]::\n-\tSet options in .git/config.\n-\n gitlink:git-hash-object[1]::\n \tComputes the object ID from a file.\n \n@@ -111,6 +108,9 @@ gitlink:git-prune-packed[1]::\n gitlink:git-read-tree[1]::\n \tReads tree information into the directory index\n \n+gitlink:git-repo-config[1]::\n+\tGet and set options in .git/config.\n+\n gitlink:git-unpack-objects[1]::\n \tUnpacks objects out of a packed archive.\n \ndiff --git a/Makefile b/Makefile\nindex 53bba2f..c47eeec 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -134,7 +134,7 @@ PROGRAMS = \\\n \tgit-unpack-objects$X git-update-index$X git-update-server-info$X \\\n \tgit-upload-pack$X git-verify-pack$X git-write-tree$X \\\n \tgit-update-ref$X git-symbolic-ref$X git-check-ref-format$X \\\n-\tgit-name-rev$X git-pack-redundant$X git-config-set$X git-var$X\n+\tgit-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X\n \n # what 'all' will build and 'install' will install.\n ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) git$X\ndiff --git a/config-set.c b/repo-config.c\nsimilarity index 98%\nrename from config-set.c\nrename to repo-config.c\nindex d938f96..b2569b7 100644\n--- a/config-set.c\n+++ b/repo-config.c\n@@ -2,7 +2,7 @@\n #include <regex.h>\n \n static const char git_config_set_usage[] =\n-\"git-config-set [--get | --get-all | --replace-all | --unset | --unset-all] name [value [value_regex]]\";\n+\"git-repo-config [--get | --get-all | --replace-all | --unset | --unset-all] name [value [value_regex]]\";\n \n static char* key = NULL;\n static char* value = NULL;\ndiff --git a/t/t1300-config-set.sh b/t/t1300-repo-config.sh\nsimilarity index 81%\nrename from t/t1300-config-set.sh\nrename to t/t1300-repo-config.sh\nindex 7a5849a..5e994ff 100644\n--- a/t/t1300-config-set.sh\n+++ b/t/t1300-repo-config.sh\n@@ -3,13 +3,13 @@\n # Copyright (c) 2005 Johannes Schindelin\n #\n \n-test_description='Test git-config-set in different settings'\n+test_description='Test git-repo-config in different settings'\n \n . ./test-lib.sh\n \n test -f .git/config && rm .git/config\n \n-git-config-set core.penguin \"little blue\"\n+git-repo-config core.penguin \"little blue\"\n \n cat > expect << EOF\n #\n@@ -22,7 +22,7 @@ EOF\n \n test_expect_success 'initial' 'cmp .git/config expect'\n \n-git-config-set Core.Movie BadPhysics\n+git-repo-config Core.Movie BadPhysics\n \n cat > expect << EOF\n #\n@@ -36,7 +36,7 @@ EOF\n \n test_expect_success 'mixed case' 'cmp .git/config expect'\n \n-git-config-set Cores.WhatEver Second\n+git-repo-config Cores.WhatEver Second\n \n cat > expect << EOF\n #\n@@ -52,7 +52,7 @@ EOF\n \n test_expect_success 'similar section' 'cmp .git/config expect'\n \n-git-config-set CORE.UPPERCASE true\n+git-repo-config CORE.UPPERCASE true\n \n cat > expect << EOF\n #\n@@ -70,10 +70,10 @@ EOF\n test_expect_success 'similar section' 'cmp .git/config expect'\n \n test_expect_success 'replace with non-match' \\\n-\t'git-config-set core.penguin kingpin !blue'\n+\t'git-repo-config core.penguin kingpin !blue'\n \n test_expect_success 'replace with non-match (actually matching)' \\\n-\t'git-config-set core.penguin \"very blue\" !kingpin'\n+\t'git-repo-config core.penguin \"very blue\" !kingpin'\n \n cat > expect << EOF\n #\n@@ -106,7 +106,7 @@ EOF\n cp .git/config .git/config2\n \n test_expect_success 'multiple unset' \\\n-\t'git-config-set --unset-all beta.haha'\n+\t'git-repo-config --unset-all beta.haha'\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -122,7 +122,7 @@ test_expect_success 'multiple unset is c\n mv .git/config2 .git/config\n \n test_expect_success '--replace-all' \\\n-\t'git-config-set --replace-all beta.haha gamma'\n+\t'git-repo-config --replace-all beta.haha gamma'\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -136,7 +136,7 @@ EOF\n \n test_expect_success 'all replaced' 'cmp .git/config expect'\n \n-git-config-set beta.haha alpha\n+git-repo-config beta.haha alpha\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -150,7 +150,7 @@ EOF\n \n test_expect_success 'really mean test' 'cmp .git/config expect'\n \n-git-config-set nextsection.nonewline wow\n+git-repo-config nextsection.nonewline wow\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -165,8 +165,8 @@ EOF\n \n test_expect_success 'really really mean test' 'cmp .git/config expect'\n \n-test_expect_success 'get value' 'test alpha = $(git-config-set beta.haha)'\n-git-config-set --unset beta.haha\n+test_expect_success 'get value' 'test alpha = $(git-repo-config beta.haha)'\n+git-repo-config --unset beta.haha\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -180,7 +180,7 @@ EOF\n \n test_expect_success 'unset' 'cmp .git/config expect'\n \n-git-config-set nextsection.NoNewLine \"wow2 for me\" \"for me$\"\n+git-repo-config nextsection.NoNewLine \"wow2 for me\" \"for me$\"\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -196,18 +196,18 @@ EOF\n test_expect_success 'multivar' 'cmp .git/config expect'\n \n test_expect_success 'non-match' \\\n-\t'git-config-set --get nextsection.nonewline !for'\n+\t'git-repo-config --get nextsection.nonewline !for'\n \n test_expect_success 'non-match value' \\\n-\t'test wow = $(git-config-set --get nextsection.nonewline !for)'\n+\t'test wow = $(git-repo-config --get nextsection.nonewline !for)'\n \n test_expect_failure 'ambiguous get' \\\n-\t'git-config-set --get nextsection.nonewline'\n+\t'git-repo-config --get nextsection.nonewline'\n \n test_expect_success 'get multivar' \\\n-\t'git-config-set --get-all nextsection.nonewline'\n+\t'git-repo-config --get-all nextsection.nonewline'\n \n-git-config-set nextsection.nonewline \"wow3\" \"wow$\"\n+git-repo-config nextsection.nonewline \"wow3\" \"wow$\"\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -222,15 +222,15 @@ EOF\n \n test_expect_success 'multivar replace' 'cmp .git/config expect'\n \n-test_expect_failure 'ambiguous value' 'git-config-set nextsection.nonewline'\n+test_expect_failure 'ambiguous value' 'git-repo-config nextsection.nonewline'\n \n test_expect_failure 'ambiguous unset' \\\n-\t'git-config-set --unset nextsection.nonewline'\n+\t'git-repo-config --unset nextsection.nonewline'\n \n test_expect_failure 'invalid unset' \\\n-\t'git-config-set --unset somesection.nonewline'\n+\t'git-repo-config --unset somesection.nonewline'\n \n-git-config-set --unset nextsection.nonewline \"wow3$\"\n+git-repo-config --unset nextsection.nonewline \"wow3$\"\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n@@ -244,12 +244,12 @@ EOF\n \n test_expect_success 'multivar unset' 'cmp .git/config expect'\n \n-test_expect_failure 'invalid key' 'git-config-set inval.2key blabla'\n+test_expect_failure 'invalid key' 'git-repo-config inval.2key blabla'\n \n-test_expect_success 'correct key' 'git-config-set 123456.a123 987'\n+test_expect_success 'correct key' 'git-repo-config 123456.a123 987'\n \n test_expect_success 'hierarchical section' \\\n-\t'git-config-set 1.2.3.alpha beta'\n+\t'git-repo-config 1.2.3.alpha beta'\n \n cat > expect << EOF\n [beta] ; silly comment # another comment\n"},{"id":"12695","messageId":"7v8xveth4l.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511241127020.12985@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Rename git-config-set to git-repo-config","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-24T11:33:30Z","receivedAt":"2005-11-24T11:33:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks for the patch.  I unfortunately was doing the same,\nbecause I wanted to get the repo-format-validation stuff into a\npresentable shape, and I thought this would interfere with it\nand wanted to do it first (fortunately it didn't).  They are\nboth in the proposed updates branch.  At a quick glance, I think\nyour patch is identical to what I did (there aren't that many\ndifferent ways to rename a command after all).\n\n> \tSorry, git-mv did not work on my system. I can now confirm that\n> \tthere is *at least* one perl 5.6 version out there which does not\n> \tlike lists in open statements at all. Grmpf.\n\nYeah, perl5.8delta says that is 5.8 feature.  As discussed on\nthe list with Merlyn, we have a fair amount of backporting, I\nsuspect.  At least we should work on 5.6, if not 5.5.\n\nI do not use git-mv myself.  It does not work in subdirectories,\nand typing Documentation/ twice to move just one file is a\nchore, so I tend to just 'R' (rename) the file, move to the\nrenamed file, and '!' (run shell command on the specified path)\nwith 'git-add', all within a single Emacs dired buffer.\n\n> \tFurther grpmf: Is it intended behaviour that git-diff *detects* \n> \trenames, while git-format-patch *doesn't*?\n\nI do not want to force all the kernel subsystem maintainers to\nuse git (namely, git-apply) to process e-mails, so format-patch\nshould not default to git specific renaming patches.\n\nAn option to git-format-patch _might_ make sense someday.  Maybe\nafter the world domination ;-).\n\nOh, wait.  It already can produce renaming patches, just does\nnot do it by default.\n\n\t\tJunio \"again I forgot what I implemented before;\n\t\tsheesh I even used it myself to feed some patches\n                to Linus\" Hamano\n \n"},{"id":"12698","messageId":"Pine.LNX.4.63.0511241419390.14297@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"7v8xveth4l.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Rename git-config-set to git-repo-config","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-24T13:28:31Z","receivedAt":"2005-11-24T13:28:31Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 24 Nov 2005, Junio C Hamano wrote:\n\n> Thanks for the patch.  I unfortunately was doing the same,\n> because I wanted to get the repo-format-validation stuff into a\n> presentable shape, and I thought this would interfere with it\n> and wanted to do it first (fortunately it didn't).  They are\n> both in the proposed updates branch.  At a quick glance, I think\n> your patch is identical to what I did (there aren't that many\n> different ways to rename a command after all).\n\nWell, there are differences:\n\n- I did not adjust the length of the \"=====\" line in the dox,\n\n- I adjusted the punch line to \"Get and set options in .git/config.\"\n  (both in git-repo-config and git, but you have it in git, exchanged...), \n  and\n\n- I did not rename the usage string in repo-config.c.\n\n> At least we should work on 5.6, if not 5.5.\n\nAgree. I don't find too many bad things about\n\n\topen F, 'git-ls-files -z |' or die 'blabla';\n\n> I do not use git-mv myself.  It does not work in subdirectories,\n> and typing Documentation/ twice to move just one file is a\n> chore, so I tend to just 'R' (rename) the file, move to the\n> renamed file, and '!' (run shell command on the specified path)\n> with 'git-add', all within a single Emacs dired buffer.\n\nWell, I don't use Emacs any longer, since it was such a hassle to install \nit on every machine. I still like it, though.\n\nAs for git-mv: looks like we need a \"git-perl-setup.perl\", right?\n\n> An option to git-format-patch _might_ make sense someday.  Maybe\n> after the world domination ;-).\n> \n> Oh, wait.  It already can produce renaming patches, just does\n> not do it by default.\n> \n> \t\tJunio \"again I forgot what I implemented before;\n> \t\tsheesh I even used it myself to feed some patches\n>                 to Linus\" Hamano\n\n*grin* Thanks for pointing that out, Oh Merciful Maintainer (OMM)!\n\nCiao,\nDscho \"trying to find a place to put his flagellations which is hard in \nthe absence of a last name in his typical signature\"\n"},{"id":"12706","messageId":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511241419390.14297@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Rename git-config-set to git-repo-config","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-24T21:24:58Z","receivedAt":"2005-11-24T21:24:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Well, there are differences:\n\nThanks; I took yours (big thanks to Tony for teaching us how\ngreat topic branches are -- I can just blow my \"hold/repoconfig\"\nbranch which had only one patch away, apply yours to \"master\"\nand merge with other topics), with one minor adjustment.\n\n> - I did not adjust the length of the \"=====\" line in the dox,\n\nIn \"make doc\", asciidoc barfs if they do not match, so I\nadjusted this.\n\n> Well, I don't use Emacs any longer, since it was such a hassle to install \n> it on every machine. I still like it, though.\n\nI do not encourge use of Emacs to others; I was using it as an\nexcuse for not debugging nor testing it personally myself ;-).\n\n> As for git-mv: looks like we need a \"git-perl-setup.perl\", right?\n\nDepends on what that git-$lang-setup.$lang does, but I am not\nquite sure.  Currently, using git-sh-setup implies you run only\nfrom toplevel, with fairly convoluted logic.\n\nI was looking at git-sh-setup does for the last couple of days;\nand it is really hard to decide what the best approach is to\nmake various pieces subdirectory safe.\n\nCurrently git C-level tools works like this:\n\n - Natively, they work only from the project toplevel.  Period.\n\n - GIT_DIR defaults to \".git\".  GIT_OBJECT_DIRECTORY defaults\n   to \"$GIT_DIR/objects\".\n\n - If GIT_DIR environment variable does not exist, tools that\n   use setup_git_directory() try to find a directory that has a\n   subdirectory that looks like a valid GIT_DIR, and chdir() to\n   that directory.  They remember the relative path from the new\n   cwd() to the original.  If you started from a subdirectory,\n   they work at the toplevel, but know where it came from\n   e.g. \"Documentation/howto/\".\n\n   The users of setup_git_directory() are responsible for\n   prepending that relative path to user supplied repository\n   relative pathnames.  Two functions, prefix_path() and\n   get_pathspec(), are supplied to help this process.\n\n   If GIT_DIR environment variable exists, setup_git_directory()\n   does not do any \".git/\" discovery (there is no point doing so\n   because the user told us where it is).  HOWEVER, as a side\n   effect of having GIT_DIR, they cannot know where their\n   current directory is relative to the project toplevel.  IOW,\n   they require to be started at the project toplevel if GIT_DIR\n   environment variable exists, and I think this behaviour is\n   the only one that makes sense [*1*].\n\n - The ones that use enter_repo() takes user supplied path,\n   chdir() to it and sets GIT_DIR=. environment.  They work in\n   naked repository without associated working tree so this is a\n   sane behaviour.\n\n - The ones that use neither assume that they are at the project\n   toplevel if they need to access working tree.\n\nAmong the scripts, the ones that do _not_ use git-sh-setup but\ncan work in subdirectories work this way:\n\n - Do not do project toplevel discovery, do not do chdir.\n\n - Use only tools that use setup_git_directory().\n\n - If an access to \".git\" is needed, find out where it is by\n   running \"git-rev-parse --git-dir\", but _do_ _not_ export it\n   as GIT_DIR; otherwise the tools that use\n   setup_git_directory() would not work as expected.\n\n - They do _not_ work from subdirectory if the user has GIT_DIR\n   environment set [*2*].\n\nThe ones that do use git-sh-setup can use GIT_DIR shell variable\ngiven by git-sh-setup, but git-sh-setup does _not_ export it\n(very important).  If GIT_DIR environment was given by the user,\nthe commands would not work from subdirectory because many\nC-level tools they use have setup_git_directory() internally as\nmentioned before.  Otherwise, GIT_DIR is set to .git by this\nscript, which means these commands can run from the toplevel\nonly.\n\n\n[Footnote]\n\n*1* This is because GIT_DIR can point at totally out-of-tree.\nYour working tree can live in tmpfs filesystem and GIT_DIR on\nsafer location.  You may lose uncommitted changes in exchange\nfor etter filesystem performance this way.\n\nWe _could_ special case when GIT_DIR is set to \"/some/path/.git\"\nand \"/some/path/\" is (grand)*parent directory of the current\ndirectory (e.g. /some/path/Documentation/howto), and do the\nusual chdir() + prefix, but I suspect this leads to more\nconfusion not less.  The rules when things work and do not in\nsubdirectories become too complex.\n\n*2* This cannot be helped; see *1* above.\n"},{"id":"12707","messageId":"Pine.LNX.4.63.0511242252080.26485@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Rename git-config-set to git-repo-config","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-24T21:54:01Z","receivedAt":"2005-11-24T21:54:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 24 Nov 2005, Junio C Hamano wrote:\n\n>  - Natively, they work only from the project toplevel.  Period.\n\nHow about changing *that*? Like, define a GIT_CWD_PREFIX, and checking in \nthe C parts?\n\nAfter all, the biggest problem with the scripts in a subdirectory is that \nthey do not necessarily know which parameter means what, i.e. when to \nprefix it and when not.\n\nA small helper a là git_path() should do, right?\n\nCiao,\nDscho\n"},{"id":"12752","messageId":"7vy83cdu7r.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511242252080.26485@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Rename git-config-set to git-repo-config","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T02:22:00Z","receivedAt":"2005-11-26T02:22:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>>  - Natively, they work only from the project toplevel.  Period.\n>\n> How about changing *that*?\n\nI once advocated for an environment to name the top of working\ntree directory --- it might make sense to resurrect that one.\n\n\"natively\" was a bad choice of word.  What I meant by the above\nwas that the core library part (what is in read-cache,\nsha1_file, etc) works on canonical path, which is defined to be\nproject toplevel relative.  I do not think changing that is wise\nnor necessary.\n\nThe setup_git_directory() interface is a good way to take path\narguments given by the end user and convert them into canonical\npath form.  So instead of punting when GIT_DIR is specified that\nwe have no way knowing where the working tree top is, we could\nuse GIT_WORKING_TREE, if exists, and use that location as the\ntoplevel when we need to access the working tree.  That implies\nwe chdir() to that directory and do necessary prefix adjustments\nbefore returning.  But I'd rather postpone that after 1.0.\n"},{"id":"12755","messageId":"Pine.LNX.4.64.0511251953081.13959@g5.osdl.org","threadId":"2615","inReplyTo":"7vy83cdu7r.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Rename git-config-set to git-repo-config","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-26T04:05:46Z","receivedAt":"2005-11-26T04:05:46Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 25 Nov 2005, Junio C Hamano wrote:\n>\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> >>  - Natively, they work only from the project toplevel.  Period.\n> >\n> > How about changing *that*?\n> \n> I once advocated for an environment to name the top of working\n> tree directory --- it might make sense to resurrect that one.\n\nPlease don't. \n\nWe should just make the scripts do it automatically instead.\n\n\"git-rev-parse\" already has support for all of this, and you can do\n\n\tGIT_DIR=$(git-rev-parse --git-dir)\n\tGIT_PREFIX=$(git-rev-parse --show-prefix)\n\nwhere the first one shows the GIT_DIR, and the second one shows where in a \ngit directory we are (empty if we're at the root).\n\nAnd most of the git commands written in C (where it makes sense) can \nalready handle being inside a subdirectory. So can a number of the \nshell-scripts (for example, doing a \"git log\" inside a subdirectory \nalready does the log for just that subdirectory).\n\nIn fact, I'd prefer if _every_ command just did the right thing inside a \nsubdirectory. \n\nI sent out this patch a week or two ago - it still applies, and it still \nmostly does the right thing. It makes at least \"gitk\" work right inside a \nsubdirectory, and might make things like \"git commit\" and friends do the \nsame.\n\nMore testing still needed, but I think this is going in the right \ndirection.\n\nComments? I got none the first time around.\n\n\t\tLinus\n\n----\n\nNOTE! This has some seriously far-reaching implications. One of them is \nthat a few programs will automagically start working inside some random \ndirectories.\n\nAnd probably others won't. Instead of saying \"Not a git archive\", they \nmight run and do strange things.\n\nThe patch is definitely a big step in the right direction: it makes the \nshell scripts that include \"git-sh-setup\" act a lot more like the programs \nthat automatically find the git directory. But everybody that includes \ngit-sh-setup should be verified.\n\nThis fixes gitk to also work the same way, btw.\n\n---\ndiff --git a/git-sh-setup.sh b/git-sh-setup.sh\nindex dbb9884..044b0b4 100755\n--- a/git-sh-setup.sh\n+++ b/git-sh-setup.sh\n@@ -3,7 +3,7 @@\n # Set up GIT_DIR and GIT_OBJECT_DIRECTORY\n # and return true if everything looks ok\n #\n-: ${GIT_DIR=.git}\n+: ${GIT_DIR=$(git-rev-parse --git-dir)} || exit\n : ${GIT_OBJECT_DIRECTORY=\"$GIT_DIR/objects\"}\n \n # Having this variable in your environment would break scripts because\ndiff --git a/gitk b/gitk\nindex a9d37d9..a934255 100755\n--- a/gitk\n+++ b/gitk\n@@ -12,7 +12,7 @@ proc gitdir {} {\n     if {[info exists env(GIT_DIR)]} {\n \treturn $env(GIT_DIR)\n     } else {\n-\treturn \".git\"\n+\treturn [exec git-rev-parse --git-dir]\n     }\n }\n \ndiff --git a/setup.c b/setup.c\nindex c487d7e..96085dd 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -53,11 +53,10 @@ const char **get_pathspec(const char *pr\n \tconst char **p;\n \tint prefixlen;\n \n-\tif (!prefix && !entry)\n-\t\treturn NULL;\n-\n \tif (!entry) {\n \t\tstatic const char *spec[2];\n+\t\tif (!prefix || !*prefix)\n+\t\t\treturn NULL;\n \t\tspec[0] = prefix;\n \t\tspec[1] = NULL;\n \t\treturn spec;\n@@ -120,9 +119,19 @@ const char *setup_git_directory(void)\n \n \tif (offset == len)\n \t\treturn NULL;\n-\n \t/* Make \"offset\" point to past the '/', and add a '/' at the end */\n \toffset++;\n+\n+\t/*\n+\t * If we're inside the \".git\" directory, we have an empty prefix\n+\t */\n+\tif (!strncmp(cwd + offset, \".git\", 4)) {\n+\t\tswitch (cwd[offset+4]) {\n+\t\tcase '\\0': case '/':\n+\t\t\treturn \"\";\n+\t\t}\n+\t}\n+\n \tcwd[len++] = '/';\n \tcwd[len] = 0;\n \treturn cwd + offset;\n"},{"id":"12756","messageId":"Pine.LNX.4.64.0511252006050.13959@g5.osdl.org","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511251953081.13959@g5.osdl.org","subject":"Re: [PATCH] Rename git-config-set to git-repo-config","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-26T04:07:29Z","receivedAt":"2005-11-26T04:07:29Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 25 Nov 2005, Linus Torvalds wrote:\n> \n> In fact, I'd prefer if _every_ command just did the right thing inside a \n> subdirectory. \n\nSide note: the thing I like best about the patch I just sent out is that \nit also makes things automagically work when you're inside the \".git\" \ndirectory. So you should be able to do a \"git log\" inside a \"raw\" archive \nwithout setting GIT_DIR=. explicitly.\n\n\t\t\tLinus\n"},{"id":"12757","messageId":"7v4q609crk.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Rename git-config-set to git-repo-config","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T05:52:31Z","receivedAt":"2005-11-26T05:52:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> Please don't. \n>\n> We should just make the scripts do it automatically instead.\n\nDon't worry, we are in agreement about that goal.\n\n> \"git-rev-parse\" already has support for all of this, and you can do\n>\n> \tGIT_DIR=$(git-rev-parse --git-dir)\n> \tGIT_PREFIX=$(git-rev-parse --show-prefix)\n>\n> where the first one shows the GIT_DIR, and the second one shows where in a \n> git directory we are (empty if we're at the root).\n\nNot in one case -- out-of-tree GIT_DIR.  That is what\nGIT_WORKING_TREE is about.\n\n> In fact, I'd prefer if _every_ command just did the right thing inside a \n> subdirectory. \n\nOf course.\n\nThe case your patch does not cover that I am worried about is\nwhere GIT_DIR is totally out of the tree.  Something like\nGIT_DIR=/home/torvalds/uemacs.git and working tree at\n/tmp/uemacs.  There is currently no way for the tools to figure\nout where the working tree toplevel is in such an arrangement,\nand that is when GIT_WORKING_TREE becomes useful.\n\nUnder normal use pattern, with GIT_DIR not in such a funny place\nbut immediately under working tree root, you do not need GIT_DIR\nnor GIT_WORKING_TREE.  We can figure things ourselves by\nchdir()-up and looking for '.git/' directory.\n\n> I sent out this patch a week or two ago - it still applies, and it still \n> mostly does the right thing. It makes at least \"gitk\" work right inside a \n> subdirectory, and might make things like \"git commit\" and friends do the \n> same.\n\nI am afraid it needs more work --- as long as a script uses only\nC-level that use setup_git_directory(), everything should work,\nand in such a case you do not even need sh-setup --- asking\n\"git-rev-parse --git-dir\" is enough, just like you did in\ngit-add.  If the script does not have to know where GIT_DIR is\n(and I do not think gitk needs to know it, although it digs\nthere by hand), it does not even need to do that.  As you said,\ngit-log and git-whatchanged works without any funny trick and\nare fine examples of that.\n\n> More testing still needed, but I think this is going in the right \n> direction.\n>\n> Comments? I got none the first time around.\n\nAmong the ones I looked at that use git-sh-setup in\nDocumentation directory of git.git:\n\n - git-checkout nor git-reset do not work because git-read-tree\n   does not use setup_git_directory(), and git-sh-setup does not\n   export GIT_DIR.\n\n   And exporting GIT_DIR from git-sh-setup is not a solution.\n   To setup_git_directory(), existence of GIT_DIR environment\n   currently means you cannot tell where your toplevel is\n   anymore.  We could check GIT_DIR against getcwd() and if it\n   is a grand*parent directory, do an appropriate thing\n   including chdir(\"$GIT_DIR/..\") and returning an adjusted\n   prefix, but we don't.  And that would not work if GIT_DIR is\n   really out-of-tree anyway.\n\n   That is why I keep saying GIT_WORKING_TREE.  We could export\n   both GIT_DIR and GIT_WORKING_TREE from git-sh-setup, and\n   teach the C-level commands that need access to working tree\n   to look at it, just like we default GIT_OBJECT_DIRECTORY from\n   git-sh-setup.  People with out of tree GIT_DIR needs to\n   export both GIT_DIR and GIT_WORKING_TREE to override both,\n   just like people with object directory in nonstandard place\n   need to export GIT_OBJECT_DIRECTORY.\n\n   Maybe GIT_WORKING_TREE can default to \"$GIT_DIR/..\", just\n   like GIT_OBJECT_DIRECTORY defaults to \"$GIT_DIR/objects\".\n\n   Another obvious approach is to stop supporting out-of-tree\n   GIT_DIR, but I suspect that probably means we should ignore\n   GIT_DIR environment and always chdir()-up to find .git/\n   (which is fine and sane but is probably an uncomfortably big\n   change).\n\n - git-prune does not work because git-fsck-objects does not\n   know where GIT_DIR is (again, GIT_DIR not exported).\n\n - git-tag works.\n\n\nHere is a list of C-level and their subdirectory-readiness\nstatus.\n\n\nThese do not look at .git at all -- automatically subdirectory\nready ;-):\n\n\tcheck-ref-format get-tar-commit-id git index-pack\n\tmailinfo mailsplit patch-id shell show-index stripspace\n\tverify-pack\n\nUses setup_git_directory() and subdirectory ready:\n\n        cat-file config-set diff-files diff-index diff-stages\n        diff-tree ls-files name-rev rev-list rev-parse\n        show-branch symbolic-ref update-index update-ref var\n\nUses enter_repo() to work from the toplevel:\n\n\tdaemon receive-pack upload-pack\n\nWants GIT_DIR to know where it is and working tree access is\nalways toplevel:\n\n\tapply checkout-index clone-pack commit-tree\n\tconvert-objects fetch-pack fsck-objects hash-object\n\thttp-fetch http-push init-db local-fetch ls-tree\n\tmerge-base merge-index mktag pack-objects pack-redundant\n\tpeek-remote prune-packed read-tree send-pack ssh-fetch\n\tssh-upload tar-tree unpack-file unpack-objects\n\tupdate-server-info write-tree\n"},{"id":"12759","messageId":"7voe477n4i.fsf_-_@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511251953081.13959@g5.osdl.org","subject":"[PATCH 0/8] Make C-level operable from subdirectories","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T09:51:41Z","receivedAt":"2005-11-26T09:51:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> On Fri, 25 Nov 2005, Junio C Hamano wrote:\n>>\n>> I once advocated for an environment to name the top of working\n>> tree directory --- it might make sense to resurrect that one.\n>\n> Please don't. \n>\n> We should just make the scripts do it automatically instead.\n\nHere comes an 8-patch series.\n\n  [PATCH 1/8] git-apply: work from subdirectory.\n  [PATCH 2/8] peek-remote: honor proxy config even from subdirectory.\n  [PATCH 3/8] fsck-objects: work from subdirectory.\n  [PATCH 4/8] checkout-index: work from subdirectory.\n  [PATCH 5/8] hash-object: work within subdirectory.\n  [PATCH 6/8] ls-tree: work from subdirectory.\n  [PATCH 7/8] Make networking commands to work from a subdirectory.\n  [PATCH 8/8] Make the rest of commands work from a subdirectory.\n"},{"id":"12762","messageId":"7viruf68bz.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 1/8] git-apply: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T09:56:32Z","receivedAt":"2005-11-26T09:56:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This adds three things:\n\n - prefix_filename() is like prefix_path() but can be used to\n   name any file on the filesystem, not the files that might go\n   into the index file.\n\n - git-apply uses setup_git_directory() to find out the GIT_DIR\n   and reads configuration file.  Later this would allow us to\n   affect the behaviour of the command from the configuration.\n\n - When git-apply is run from a subdirectory, it applies the\n   given patch only to the files under the current directory and\n   below.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n apply.c |   15 +++++++++++++++\n cache.h |    1 +\n setup.c |   15 +++++++++++++++\n 3 files changed, 31 insertions(+), 0 deletions(-)\n\napplies-to: 9ccf8849fa9b522a344645c2f28f12ab036e30d5\nc20b8d006edfa964b3df5e4c5cc28cb93edcb240\ndiff --git a/apply.c b/apply.c\nindex 50be8f3..ae06d41 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -16,6 +16,9 @@\n //  --numstat does numeric diffstat, and doesn't actually apply\n //  --index-info shows the old and new index info for paths if available.\n //\n+static const char *prefix;\n+static int prefix_length;\n+\n static int allow_binary_replacement = 0;\n static int check_index = 0;\n static int write_index = 0;\n@@ -1706,6 +1709,12 @@ static int use_patch(struct patch *p)\n \t\t\treturn 0;\n \t\tx = x->next;\n \t}\n+\tif (prefix && *prefix) {\n+\t\tint pathlen = strlen(pathname);\n+\t\tif (pathlen <= prefix_length ||\n+\t\t    memcmp(prefix, pathname, prefix_length))\n+\t\t\treturn 0;\n+\t}\n \treturn 1;\n }\n \n@@ -1784,6 +1793,10 @@ int main(int argc, char **argv)\n \tint i;\n \tint read_stdin = 1;\n \n+\tprefix = setup_git_directory();\n+\tprefix_length = prefix ? strlen(prefix) : 0;\n+\tgit_config(git_default_config);\n+\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \t\tint fd;\n@@ -1845,6 +1858,8 @@ int main(int argc, char **argv)\n \t\t\tline_termination = 0;\n \t\t\tcontinue;\n \t\t}\n+\t\targ = prefix_filename(prefix, prefix_length, arg);\n+\n \t\tfd = open(arg, O_RDONLY);\n \t\tif (fd < 0)\n \t\t\tusage(apply_usage);\ndiff --git a/cache.h b/cache.h\nindex 6ac94c5..62920ce 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -149,6 +149,7 @@ extern char *get_graft_file(void);\n extern const char **get_pathspec(const char *prefix, const char **pathspec);\n extern const char *setup_git_directory(void);\n extern const char *prefix_path(const char *prefix, int len, const char *path);\n+extern const char *prefix_filename(const char *prefix, int len, const char *path);\n \n #define alloc_nr(x) (((x)+16)*3/2)\n \ndiff --git a/setup.c b/setup.c\nindex ab3c778..54f6a34 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -47,6 +47,21 @@ const char *prefix_path(const char *pref\n \treturn path;\n }\n \n+/* \n+ * Unlike prefix_path, this should be used if the named file does\n+ * not have to interact with index entry; i.e. name of a random file\n+ * on the filesystem.\n+ */\n+const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)\n+{\n+\tstatic char path[PATH_MAX];\n+\tif (!pfx || !*pfx || arg[0] == '/')\n+\t\treturn arg;\n+\tmemcpy(path, pfx, pfx_len);\n+\tstrcpy(path + pfx_len, arg);\n+\treturn path;\n+}\n+\n const char **get_pathspec(const char *prefix, const char **pathspec)\n {\n \tconst char *entry = *pathspec;\n---\n0.99.9.GIT\n"},{"id":"12761","messageId":"7vd5kn68bq.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 2/8] peek-remote: honor proxy config even from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T09:56:41Z","receivedAt":"2005-11-26T09:56:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Introduce setup_git_directory_gently() which does not die() if\ncalled outside a git repository, and use it so that later\ngit_config() would work as expected even from a subdirectory,\nwithout failing the whole command if run outside a git\nrepository.\n\nUse it at the beginning of peek-remote so that git:// proxy can\nbe picked up from the configuration file.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n cache.h       |    1 +\n peek-remote.c |    3 +++\n setup.c       |   11 ++++++++---\n 3 files changed, 12 insertions(+), 3 deletions(-)\n\napplies-to: 6afe0a2dc5da18d1090e8d660e45e2c777bfeaaa\n1fe3fae4e1dcd864af4010ee572a3bc6de996e95\ndiff --git a/cache.h b/cache.h\nindex 62920ce..13806d3 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -147,6 +147,7 @@ extern char *get_graft_file(void);\n #define ALTERNATE_DB_ENVIRONMENT \"GIT_ALTERNATE_OBJECT_DIRECTORIES\"\n \n extern const char **get_pathspec(const char *prefix, const char **pathspec);\n+extern const char *setup_git_directory_gently(int *);\n extern const char *setup_git_directory(void);\n extern const char *prefix_path(const char *prefix, int len, const char *path);\n extern const char *prefix_filename(const char *prefix, int len, const char *path);\ndiff --git a/peek-remote.c b/peek-remote.c\nindex ee49bf3..a90cf22 100644\n--- a/peek-remote.c\n+++ b/peek-remote.c\n@@ -27,6 +27,9 @@ int main(int argc, char **argv)\n \tchar *dest = NULL;\n \tint fd[2];\n \tpid_t pid;\n+\tint nongit = 0;\n+\n+\tsetup_git_directory_gently(&nongit);\n \n \tfor (i = 1; i < argc; i++) {\n \t\tchar *arg = argv[i];\ndiff --git a/setup.c b/setup.c\nindex 54f6a34..b697bf9 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -107,7 +107,7 @@ static int is_toplevel_directory(void)\n \treturn 1;\n }\n \n-static const char *setup_git_directory_1(void)\n+const char *setup_git_directory_gently(int *nongit_ok)\n {\n \tstatic char cwd[PATH_MAX+1];\n \tint len, offset;\n@@ -154,8 +154,13 @@ static const char *setup_git_directory_1\n \t\t\tbreak;\n \t\tchdir(\"..\");\n \t\tdo {\n-\t\t\tif (!offset)\n+\t\t\tif (!offset) {\n+\t\t\t\tif (nongit_ok) {\n+\t\t\t\t\t*nongit_ok = 1;\n+\t\t\t\t\treturn NULL;\n+\t\t\t\t}\n \t\t\t\tdie(\"Not a git repository\");\n+\t\t\t}\n \t\t} while (cwd[--offset] != '/');\n \t}\n \n@@ -171,6 +176,6 @@ static const char *setup_git_directory_1\n \n const char *setup_git_directory(void)\n {\n-\tconst char *retval = setup_git_directory_1();\n+\tconst char *retval = setup_git_directory_gently(NULL);\n \treturn retval;\n }\n---\n0.99.9.GIT\n"},{"id":"12760","messageId":"7v7jav68bi.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 3/8] fsck-objects: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T09:56:49Z","receivedAt":"2005-11-26T09:56:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Not much point making it work from subdirectory, but for a\nconsistency make it so.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n fsck-objects.c |    2 ++\n 1 files changed, 2 insertions(+), 0 deletions(-)\n\napplies-to: 802056c105a0cb936137f141a8e6e546224f3a07\n1bd646921ec7278fad9a38281678227769046291\ndiff --git a/fsck-objects.c b/fsck-objects.c\nindex 0433a1d..90e638e 100644\n--- a/fsck-objects.c\n+++ b/fsck-objects.c\n@@ -431,6 +431,8 @@ int main(int argc, char **argv)\n {\n \tint i, heads;\n \n+\tsetup_git_directory();\n+\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \n---\n0.99.9.GIT\n"},{"id":"12763","messageId":"7v1x1368b9.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 4/8] checkout-index: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T09:56:58Z","receivedAt":"2005-11-26T09:56:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"With this, git-checkout-index from a subdirectory works as\nexpected.  Note that \"git-checkout-index -a\" checks out files\nonly in the current directory and under.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n checkout-index.c |   12 +++++++++++-\n 1 files changed, 11 insertions(+), 1 deletions(-)\n\napplies-to: 5609c84ffd98e1b253c4cb46523245c3be553624\n556dc2ebd6566fc032444224a145d3cb422eecc4\ndiff --git a/checkout-index.c b/checkout-index.c\nindex dab3778..f1e716d 100644\n--- a/checkout-index.c\n+++ b/checkout-index.c\n@@ -34,6 +34,9 @@\n  */\n #include \"cache.h\"\n \n+static const char *prefix;\n+static int prefix_length;\n+\n static struct checkout state = {\n \t.base_dir = \"\",\n \t.base_dir_len = 0,\n@@ -69,6 +72,10 @@ static int checkout_all(void)\n \t\tstruct cache_entry *ce = active_cache[i];\n \t\tif (ce_stage(ce))\n \t\t\tcontinue;\n+\t\tif (prefix && *prefix &&\n+\t\t    ( ce_namelen(ce) <= prefix_length ||\n+\t\t      memcmp(prefix, ce->name, prefix_length) ))\n+\t\t\tcontinue;\n \t\tif (checkout_entry(ce, &state) < 0)\n \t\t\terrs++;\n \t}\n@@ -91,6 +98,9 @@ int main(int argc, char **argv)\n \tint newfd = -1;\n \tint all = 0;\n \n+\tprefix = setup_git_directory();\n+\tprefix_length = prefix ? strlen(prefix) : 0;\n+\n \tif (read_cache() < 0) {\n \t\tdie(\"invalid cache\");\n \t}\n@@ -155,7 +165,7 @@ int main(int argc, char **argv)\n \n \t\tif (all)\n \t\t\tdie(\"git-checkout-index: don't mix '--all' and explicit filenames\");\n-\t\tcheckout_file(arg);\n+\t\tcheckout_file(prefix_path(prefix, prefix_length, arg));\n \t}\n \n \tif (all)\n---\n0.99.9.GIT\n"},{"id":"12767","messageId":"7vveyf4tqr.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 5/8] hash-object: work within subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T09:57:00Z","receivedAt":"2005-11-26T09:57:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When -w is given, it needs to find out where the .git directory\nis, so run the setup_git_directory() when we see a -w.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n hash-object.c |   19 ++++++++++++++++---\n 1 files changed, 16 insertions(+), 3 deletions(-)\n\napplies-to: b0041c758e0fc01e5ec05bd0543d04d1a9cb17f5\n61fdef6a50c99c98feebd71f499450cf97a8c169\ndiff --git a/hash-object.c b/hash-object.c\nindex c8c9adb..3075328 100644\n--- a/hash-object.c\n+++ b/hash-object.c\n@@ -6,6 +6,9 @@\n  */\n #include \"cache.h\"\n \n+static const char *prefix;\n+static int prefix_length = -1;\n+\n static void hash_object(const char *path, const char *type, int write_object)\n {\n \tint fd;\n@@ -36,10 +39,20 @@ int main(int argc, char **argv)\n \t\t\t\tdie(hash_object_usage);\n \t\t\ttype = argv[i];\n \t\t}\n-\t\telse if (!strcmp(argv[i], \"-w\"))\n+\t\telse if (!strcmp(argv[i], \"-w\")) {\n+\t\t\tif (prefix_length < 0) {\n+\t\t\t\tprefix = setup_git_directory();\n+\t\t\t\tprefix_length = prefix ? strlen(prefix) : 0;\n+\t\t\t}\n \t\t\twrite_object = 1;\n-\t\telse\n-\t\t\thash_object(argv[i], type, write_object);\n+\t\t}\n+\t\telse {\n+\t\t\tchar *arg = argv[i];\n+\t\t\tif (0 <= prefix_length)\n+\t\t\t\targ = prefix_filename(prefix, prefix_length,\n+\t\t\t\t\t\t      arg);\n+\t\t\thash_object(arg, type, write_object);\n+\t\t}\n \t}\n \treturn 0;\n }\n---\n0.99.9.GIT\n"},{"id":"12766","messageId":"7vpson4tqi.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T09:57:09Z","receivedAt":"2005-11-26T09:57:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This makes ls-tree to work from subdirectory.  It defaults to\nshow the paths under the current subdirectory, and interprets\nuser-supplied paths as relative to the current subdirectory.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n ls-tree.c |   21 ++++++++++++++++-----\n 1 files changed, 16 insertions(+), 5 deletions(-)\n\napplies-to: 4e55e4796ee699c9361b3751a36a85ba282119a8\n40af60bb52cd86e1f089eeb89b2d3d79531c55d1\ndiff --git a/ls-tree.c b/ls-tree.c\nindex d9f15e3..ed546a5 100644\n--- a/ls-tree.c\n+++ b/ls-tree.c\n@@ -8,6 +8,8 @@\n #include \"tree.h\"\n #include \"quote.h\"\n \n+static const char *prefix;\n+\n static int line_termination = '\\n';\n #define LS_RECURSIVE 1\n #define LS_TREE_ONLY 2\n@@ -204,7 +206,7 @@ static int list_one(const char *path)\n \treturn err;\n }\n \n-static int list(char **path)\n+static int list(const char **path)\n {\n \tint i;\n \tint err = 0;\n@@ -216,11 +218,16 @@ static int list(char **path)\n static const char ls_tree_usage[] =\n \t\"git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]\";\n \n-int main(int argc, char **argv)\n+int main(int argc, const char **argv)\n {\n-\tstatic char *path0[] = { \"\", NULL };\n-\tchar **path;\n+\tstatic const char *path0[] = { \"\", NULL };\n+\tconst char **path;\n \tunsigned char sha1[20];\n+\tint nongit = 0;\n+\n+\tprefix = setup_git_directory_gently(&nongit);\n+\tif (prefix)\n+\t\tpath0[0] = prefix;\n \n \twhile (1 < argc && argv[1][0] == '-') {\n \t\tswitch (argv[1][1]) {\n@@ -244,7 +251,11 @@ int main(int argc, char **argv)\n \tif (get_sha1(argv[1], sha1) < 0)\n \t\tusage(ls_tree_usage);\n \n-\tpath = (argc == 2) ? path0 : (argv + 2);\n+\tif (argc == 2)\n+\t\tpath = path0;\n+\telse\n+\t\tpath = get_pathspec(prefix, argv + 2);\n+\n \tprepare_root(sha1);\n \tif (list(path) < 0)\n \t\tdie(\"list failed\");\n---\n0.99.9.GIT\n"},{"id":"12765","messageId":"7vk6ev4tqd.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 7/8] Make networking commands to work from a subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T09:57:14Z","receivedAt":"2005-11-26T09:57:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"These are whole-tree operations and there is not much point\nmaking them operable from within a subdirectory, but it is easy\nto do so, and using setup_git_directory() upfront helps git://\nproxy specification picked up from the correct place.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n clone-pack.c  |    2 ++\n fetch-pack.c  |    2 ++\n http-fetch.c  |    2 ++\n http-push.c   |    1 +\n local-fetch.c |    2 ++\n send-pack.c   |    1 +\n ssh-fetch.c   |    2 ++\n ssh-upload.c  |    3 +++\n 8 files changed, 15 insertions(+), 0 deletions(-)\n\napplies-to: 40288d9fe5f400d387e29cd7ec2fa4f1ee4eecca\ne01beacec2b24cf1ca59bd8a0fdbe301119ab061\ndiff --git a/clone-pack.c b/clone-pack.c\nindex 9609219..a99a95c 100644\n--- a/clone-pack.c\n+++ b/clone-pack.c\n@@ -271,6 +271,8 @@ int main(int argc, char **argv)\n \tint fd[2];\n \tpid_t pid;\n \n+\tsetup_git_directory();\n+\n \tnr_heads = 0;\n \theads = NULL;\n \tfor (i = 1; i < argc; i++) {\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex 6565982..58ba209 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -424,6 +424,8 @@ int main(int argc, char **argv)\n \tint fd[2];\n \tpid_t pid;\n \n+\tsetup_git_directory();\n+\n \tnr_heads = 0;\n \theads = NULL;\n \tfor (i = 1; i < argc; i++) {\ndiff --git a/http-fetch.c b/http-fetch.c\nindex 4353173..ad59f1c 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -922,6 +922,8 @@ int main(int argc, char **argv)\n \tint arg = 1;\n \tint rc = 0;\n \n+\tsetup_git_directory();\n+\n \twhile (arg < argc && argv[arg][0] == '-') {\n \t\tif (argv[arg][1] == 't') {\n \t\t\tget_tree = 1;\ndiff --git a/http-push.c b/http-push.c\nindex 76c7886..250a9b9 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1239,6 +1239,7 @@ int main(int argc, char **argv)\n \tint rc = 0;\n \tint i;\n \n+\tsetup_git_directory();\n \tsetup_ident();\n \n \tremote = xmalloc(sizeof(*remote));\ndiff --git a/local-fetch.c b/local-fetch.c\nindex 0931109..fa9e697 100644\n--- a/local-fetch.c\n+++ b/local-fetch.c\n@@ -207,6 +207,8 @@ int main(int argc, char **argv)\n \tchar *commit_id;\n \tint arg = 1;\n \n+\tsetup_git_directory();\n+\n \twhile (arg < argc && argv[arg][0] == '-') {\n \t\tif (argv[arg][1] == 't')\n \t\t\tget_tree = 1;\ndiff --git a/send-pack.c b/send-pack.c\nindex 3eeb18f..2a14b00 100644\n--- a/send-pack.c\n+++ b/send-pack.c\n@@ -273,6 +273,7 @@ int main(int argc, char **argv)\n \tint fd[2], ret;\n \tpid_t pid;\n \n+\tsetup_git_directory();\n \targv++;\n \tfor (i = 1; i < argc; i++, argv++) {\n \t\tchar *arg = *argv;\ndiff --git a/ssh-fetch.c b/ssh-fetch.c\nindex bf01fbc..4eb9e04 100644\n--- a/ssh-fetch.c\n+++ b/ssh-fetch.c\n@@ -131,6 +131,8 @@ int main(int argc, char **argv)\n \tprog = getenv(\"GIT_SSH_PUSH\");\n \tif (!prog) prog = \"git-ssh-upload\";\n \n+\tsetup_git_directory();\n+\n \twhile (arg < argc && argv[arg][0] == '-') {\n \t\tif (argv[arg][1] == 't') {\n \t\t\tget_tree = 1;\ndiff --git a/ssh-upload.c b/ssh-upload.c\nindex 603abcc..b675a0b 100644\n--- a/ssh-upload.c\n+++ b/ssh-upload.c\n@@ -121,6 +121,9 @@ int main(int argc, char **argv)\n \n \tprog = getenv(COUNTERPART_ENV_NAME);\n \tif (!prog) prog = COUNTERPART_PROGRAM_NAME;\n+\n+\tsetup_git_directory();\n+\n \twhile (arg < argc && argv[arg][0] == '-') {\n \t\tif (argv[arg][1] == 'w')\n \t\t\targ++;\n---\n0.99.9.GIT\n"},{"id":"12764","messageId":"7vek534tq6.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7vmzjtn3h1.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH 8/8] Make the rest of commands work from a subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T09:57:21Z","receivedAt":"2005-11-26T09:57:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"These commands are converted to run from a subdirectory.\n\n    commit-tree convert-objects merge-base merge-index mktag\n    pack-objects pack-redundant prune-packed read-tree tar-tree\n    unpack-file unpack-objects update-server-info write-tree\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n commit-tree.c        |    2 ++\n convert-objects.c    |    2 ++\n merge-base.c         |    2 ++\n merge-index.c        |    1 +\n mktag.c              |    2 ++\n pack-objects.c       |    2 ++\n pack-redundant.c     |    2 ++\n prune-packed.c       |    2 ++\n read-tree.c          |    2 ++\n tar-tree.c           |    2 ++\n unpack-file.c        |    2 ++\n unpack-objects.c     |    2 ++\n update-server-info.c |    2 ++\n write-tree.c         |    5 ++++-\n 14 files changed, 29 insertions(+), 1 deletions(-)\n\napplies-to: 46e976598ab7b7822d7664fdcc88dc63d2e9cf7a\n87a21588fb4f8ed433364716ccb90ef934a99585\ndiff --git a/commit-tree.c b/commit-tree.c\nindex b60299f..4634b50 100644\n--- a/commit-tree.c\n+++ b/commit-tree.c\n@@ -91,6 +91,8 @@ int main(int argc, char **argv)\n \tif (argc < 2 || get_sha1_hex(argv[1], tree_sha1) < 0)\n \t\tusage(commit_tree_usage);\n \n+\tsetup_git_directory();\n+\n \tcheck_valid(tree_sha1, \"tree\");\n \tfor (i = 2; i < argc; i += 2) {\n \t\tchar *a, *b;\ndiff --git a/convert-objects.c b/convert-objects.c\nindex a892013..d78a8b4 100644\n--- a/convert-objects.c\n+++ b/convert-objects.c\n@@ -316,6 +316,8 @@ int main(int argc, char **argv)\n \tunsigned char sha1[20];\n \tstruct entry *entry;\n \n+\tsetup_git_directory();\n+\n \tif (argc != 2 || get_sha1(argv[1], sha1))\n \t\tusage(\"git-convert-objects <sha1>\");\n \ndiff --git a/merge-base.c b/merge-base.c\nindex 751c3c2..e73fca7 100644\n--- a/merge-base.c\n+++ b/merge-base.c\n@@ -236,6 +236,8 @@ int main(int argc, char **argv)\n \tstruct commit *rev1, *rev2;\n \tunsigned char rev1key[20], rev2key[20];\n \n+\tsetup_git_directory();\n+\n \twhile (1 < argc && argv[1][0] == '-') {\n \t\tchar *arg = argv[1];\n \t\tif (!strcmp(arg, \"-a\") || !strcmp(arg, \"--all\"))\ndiff --git a/merge-index.c b/merge-index.c\nindex 727527f..024196e 100644\n--- a/merge-index.c\n+++ b/merge-index.c\n@@ -102,6 +102,7 @@ int main(int argc, char **argv)\n \tif (argc < 3)\n \t\tusage(\"git-merge-index [-o] [-q] <merge-program> (-a | <filename>*)\");\n \n+\tsetup_git_directory();\n \tread_cache();\n \n \ti = 1;\ndiff --git a/mktag.c b/mktag.c\nindex 585677e..97e270a 100644\n--- a/mktag.c\n+++ b/mktag.c\n@@ -111,6 +111,8 @@ int main(int argc, char **argv)\n \tif (argc != 1)\n \t\tusage(\"cat <signaturefile> | git-mktag\");\n \n+\tsetup_git_directory();\n+\n \t// Read the signature\n \tsize = 0;\n \tfor (;;) {\ndiff --git a/pack-objects.c b/pack-objects.c\nindex 8864a31..a62c9f8 100644\n--- a/pack-objects.c\n+++ b/pack-objects.c\n@@ -473,6 +473,8 @@ int main(int argc, char **argv)\n \tstruct object_entry **list;\n \tint i;\n \n+\tsetup_git_directory();\n+\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \ndiff --git a/pack-redundant.c b/pack-redundant.c\nindex 793fa08..0a43278 100644\n--- a/pack-redundant.c\n+++ b/pack-redundant.c\n@@ -600,6 +600,8 @@ int main(int argc, char **argv)\n \tunsigned char *sha1;\n \tchar buf[42]; /* 40 byte sha1 + \\n + \\0 */\n \n+\tsetup_git_directory();\n+\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \t\tif(!strcmp(arg, \"--\")) {\ndiff --git a/prune-packed.c b/prune-packed.c\nindex 26123f7..d24b097 100644\n--- a/prune-packed.c\n+++ b/prune-packed.c\n@@ -58,6 +58,8 @@ int main(int argc, char **argv)\n {\n \tint i;\n \n+\tsetup_git_directory();\n+\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \ndiff --git a/read-tree.c b/read-tree.c\nindex df156ea..e3b9c0d 100644\n--- a/read-tree.c\n+++ b/read-tree.c\n@@ -629,6 +629,8 @@ int main(int argc, char **argv)\n \tunsigned char sha1[20];\n \tmerge_fn_t fn = NULL;\n \n+\tsetup_git_directory();\n+\n \tnewfd = hold_index_file_for_update(&cache_file, get_index_file());\n \tif (newfd < 0)\n \t\tdie(\"unable to create new cachefile\");\ndiff --git a/tar-tree.c b/tar-tree.c\nindex 970c4bb..bacb23a 100644\n--- a/tar-tree.c\n+++ b/tar-tree.c\n@@ -407,6 +407,8 @@ int main(int argc, char **argv)\n \tvoid *buffer;\n \tunsigned long size;\n \n+\tsetup_git_directory();\n+\n \tswitch (argc) {\n \tcase 3:\n \t\tbasedir = argv[2];\ndiff --git a/unpack-file.c b/unpack-file.c\nindex d4ac3a5..07303f8 100644\n--- a/unpack-file.c\n+++ b/unpack-file.c\n@@ -29,6 +29,8 @@ int main(int argc, char **argv)\n \tif (argc != 2 || get_sha1(argv[1], sha1))\n \t\tusage(\"git-unpack-file <sha1>\");\n \n+\tsetup_git_directory();\n+\n \tputs(create_temp_file(sha1));\n \treturn 0;\n }\ndiff --git a/unpack-objects.c b/unpack-objects.c\nindex 8490895..cfd61ae 100644\n--- a/unpack-objects.c\n+++ b/unpack-objects.c\n@@ -269,6 +269,8 @@ int main(int argc, char **argv)\n \tint i;\n \tunsigned char sha1[20];\n \n+\tsetup_git_directory();\n+\n \tfor (i = 1 ; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \ndiff --git a/update-server-info.c b/update-server-info.c\nindex e824f62..0b6c383 100644\n--- a/update-server-info.c\n+++ b/update-server-info.c\n@@ -19,5 +19,7 @@ int main(int ac, char **av)\n \tif (i != ac)\n \t\tusage(update_server_info_usage);\n \n+\tsetup_git_directory();\n+\n \treturn !!update_server_info(force);\n }\ndiff --git a/write-tree.c b/write-tree.c\nindex 2b2c6b7..0aac32f 100644\n--- a/write-tree.c\n+++ b/write-tree.c\n@@ -86,9 +86,12 @@ static int write_tree(struct cache_entry\n int main(int argc, char **argv)\n {\n \tint i, funny;\n-\tint entries = read_cache();\n+\tint entries;\n \tunsigned char sha1[20];\n \t\n+\tsetup_git_directory();\n+\n+\tentries = read_cache();\n \tif (argc == 2) {\n \t\tif (!strcmp(argv[1], \"--missing-ok\"))\n \t\t\tmissing_ok = 1;\n---\n0.99.9.GIT\n"},{"id":"12769","messageId":"7vzmnr1xp4.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7voe477n4i.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 0/8] Make C-level operable from subdirectories","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T10:59:51Z","receivedAt":"2005-11-26T10:59:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> Linus Torvalds <torvalds@osdl.org> writes:\n>\n>> On Fri, 25 Nov 2005, Junio C Hamano wrote:\n>>>\n>>> I once advocated for an environment to name the top of working\n>>> tree directory --- it might make sense to resurrect that one.\n>>\n>> Please don't. \n>>\n>> We should just make the scripts do it automatically instead.\n>\n> Here comes an 8-patch series.\n>\n>   [PATCH 1/8] git-apply: work from subdirectory.\n>   [PATCH 2/8] peek-remote: honor proxy config even from subdirectory.\n>   [PATCH 3/8] fsck-objects: work from subdirectory.\n>   [PATCH 4/8] checkout-index: work from subdirectory.\n>   [PATCH 5/8] hash-object: work within subdirectory.\n>   [PATCH 6/8] ls-tree: work from subdirectory.\n>   [PATCH 7/8] Make networking commands to work from a subdirectory.\n>   [PATCH 8/8] Make the rest of commands work from a subdirectory.\n\nIn case it was not obvious,...\n\nI think your GIT_DIR=`git-rev-parse --git-dir` patch would make\nthings work better on top of these changes, while making many of\nthem silently do funny things as you warned.\n\nFor example, among the ones I mentioned in my previous message:\n\n - git-checkout with or without -b to switch branches work.\n   This is because \"git-read-tree -u\" is not constrained by the\n   current directory and operates on the whole working tree.\n\n - git-checkout <ent> <path>... works as expected.  It takes cwd\n   relative paths and updates the index and working tree for\n   only specified paths from the named ent.\n\n - git-checkout -f works in a confusing way; only the files\n   under the current directory is updated.  This is because\n   \"git-checkout-index -a\" behaves that way.  git-checkout -f to\n   revert to the current HEAD is probably good to work this way,\n   but doing this while switching branches is too confusing.\n\n - git-reset --hard also works in a funny way.  It leaves paths\n   outside the current directory intact, because ls-tree reports\n   only the files in the current directory while ls-files\n   reports all.\n\n - git-prune works.  git-tag works as before.\n\nIt could be argued that it was a mistake that [PATCH 4/8] and\n[PATCH 6/8] changed checkout-index and ls-tree to limit their\nscope to the current directory, but that is consistent with what\nrev-list (log and whatchanged) and diff do, and might be\ndebatably useful.  Which suggests that things like git-checkout\nand git-reset whose normal mode of operation should be\nwhole-tree should chdir up and do the path prefixing to convert\noriginal cwd relative paths to repository relative.\n"},{"id":"12771","messageId":"Pine.LNX.4.64.0511260932080.13959@g5.osdl.org","threadId":"2615","inReplyTo":"7viruf68bz.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/8] git-apply: work from subdirectory.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-26T17:36:21Z","receivedAt":"2005-11-26T17:36:21Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sat, 26 Nov 2005, Junio C Hamano wrote:\n>\n> This adds three things:\n> \n>  - prefix_filename() is like prefix_path() but can be used to\n>    name any file on the filesystem, not the files that might go\n>    into the index file.\n> \n>  - git-apply uses setup_git_directory() to find out the GIT_DIR\n>    and reads configuration file.  Later this would allow us to\n>    affect the behaviour of the command from the configuration.\n> \n>  - When git-apply is run from a subdirectory, it applies the\n>    given patch only to the files under the current directory and\n>    below.\n> \n> Signed-off-by: Junio C Hamano <junkio@cox.net>\n\nThis breaks git-apply when used to just do a \"diffstat\", or when used on a \nnon-git repository.\n\nFor \"git-apply --stat\", we definitely don't want to force it inside a git \ndirectory. In fact, even _trying_ to find a git directory would be wrong.\n\nThe only case where we care about a git directory is the \"--index\" case. \nIn all other cases we should happily apply it (or stat it).\n\n\t\tLinus\n"},{"id":"12772","messageId":"Pine.LNX.4.64.0511260855560.13959@g5.osdl.org","threadId":"2615","inReplyTo":"7vpson4tqi.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-26T17:38:20Z","receivedAt":"2005-11-26T17:38:20Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sat, 26 Nov 2005, Junio C Hamano wrote:\n> \n> --- a/ls-tree.c\n> +++ b/ls-tree.c\n> @@ -8,6 +8,8 @@\n>  #include \"tree.h\"\n>  #include \"quote.h\"\n>  \n> +static const char *prefix;\n> +\n\nNo need to have this visible outside of \"main()\".\n\n> +\tprefix = setup_git_directory_gently(&nongit);\n> +\tif (prefix)\n> +\t\tpath0[0] = prefix;\n...\n> +\tif (argc == 2)\n> +\t\tpath = path0;\n> +\telse\n> +\t\tpath = get_pathspec(prefix, argv + 2);\n> +\n\nAnd this is just ugly.\n\ngit-ls-tree should be rewritten to use a pathspec the same way everybody \nelse does. Right now it's the odd man out: if you do\n\n\tgit-ls-tree HEAD divers/char drivers/\n\nit will show the same files _twice_, which is not how pathspecs in general \nwork.\n\nHow about this patch? It breaks some of the git-ls-tree tests, but it \nmakes git-ls-tree work a lot more like other git pathspec commands, and it \nremoves more than 150 lines by re-using the recursive tree traversal (but \nthe \"-d\" flag is gone for good, so I'm not pushing this too hard).\n\n\t\tLinus\n\n---\ndiff --git a/ls-tree.c b/ls-tree.c\nindex d9f15e3..598b729 100644\n--- a/ls-tree.c\n+++ b/ls-tree.c\n@@ -13,215 +13,32 @@ static int line_termination = '\\n';\n #define LS_TREE_ONLY 2\n static int ls_options = 0;\n \n-static struct tree_entry_list root_entry;\n-\n-static void prepare_root(unsigned char *sha1)\n-{\n-\tunsigned char rsha[20];\n-\tunsigned long size;\n-\tvoid *buf;\n-\tstruct tree *root_tree;\n-\n-\tbuf = read_object_with_reference(sha1, \"tree\", &size, rsha);\n-\tfree(buf);\n-\tif (!buf)\n-\t\tdie(\"Could not read %s\", sha1_to_hex(sha1));\n-\n-\troot_tree = lookup_tree(rsha);\n-\tif (!root_tree)\n-\t\tdie(\"Could not read %s\", sha1_to_hex(sha1));\n-\n-\t/* Prepare a fake entry */\n-\troot_entry.directory = 1;\n-\troot_entry.executable = root_entry.symlink = 0;\n-\troot_entry.mode = S_IFDIR;\n-\troot_entry.name = \"\";\n-\troot_entry.item.tree = root_tree;\n-\troot_entry.parent = NULL;\n-}\n-\n-static int prepare_children(struct tree_entry_list *elem)\n-{\n-\tif (!elem->directory)\n-\t\treturn -1;\n-\tif (!elem->item.tree->object.parsed) {\n-\t\tstruct tree_entry_list *e;\n-\t\tif (parse_tree(elem->item.tree))\n-\t\t\treturn -1;\n-\t\t/* Set up the parent link */\n-\t\tfor (e = elem->item.tree->entries; e; e = e->next)\n-\t\t\te->parent = elem;\n-\t}\n-\treturn 0;\n-}\n-\n-static struct tree_entry_list *find_entry(const char *path, char *pathbuf)\n-{\n-\tconst char *next, *slash;\n-\tint len;\n-\tstruct tree_entry_list *elem = &root_entry, *oldelem = NULL;\n-\n-\t*(pathbuf) = '\\0';\n-\n-\t/* Find tree element, descending from root, that\n-\t * corresponds to the named path, lazily expanding\n-\t * the tree if possible.\n-\t */\n-\n-\twhile (path) {\n-\t\t/* The fact we still have path means that the caller\n-\t\t * wants us to make sure that elem at this point is a\n-\t\t * directory, and possibly descend into it.  Even what\n-\t\t * is left is just trailing slashes, we loop back to\n-\t\t * here, and this call to prepare_children() will\n-\t\t * catch elem not being a tree.  Nice.\n-\t\t */\n-\t\tif (prepare_children(elem))\n-\t\t\treturn NULL;\n-\n-\t\tslash = strchr(path, '/');\n-\t\tif (!slash) {\n-\t\t\tlen = strlen(path);\n-\t\t\tnext = NULL;\n-\t\t}\n-\t\telse {\n-\t\t\tnext = slash + 1;\n-\t\t\tlen = slash - path;\n-\t\t}\n-\t\tif (len) {\n-\t\t\tif (oldelem) {\n-\t\t\t\tpathbuf += sprintf(pathbuf, \"%s/\", oldelem->name);\n-\t\t\t}\n-\n-\t\t\t/* (len == 0) if the original path was \"drivers/char/\"\n-\t\t\t * and we have run already two rounds, having elem\n-\t\t\t * pointing at the drivers/char directory.\n-\t\t\t */\n-\t\t\telem = elem->item.tree->entries;\n-\t\t\twhile (elem) {\n-\t\t\t\tif ((strlen(elem->name) == len) &&\n-\t\t\t\t    !strncmp(elem->name, path, len)) {\n-\t\t\t\t\t/* found */\n-\t\t\t\t\tbreak;\n-\t\t\t\t}\n-\t\t\t\telem = elem->next;\n-\t\t\t}\n-\t\t\tif (!elem)\n-\t\t\t\treturn NULL;\n-\n-\t\t\toldelem = elem;\n-\t\t}\n-\t\tpath = next;\n-\t}\n-\n-\treturn elem;\n-}\n-\n-static const char *entry_type(struct tree_entry_list *e)\n-{\n-\treturn (e->directory ? \"tree\" : \"blob\");\n-}\n-\n-static const char *entry_hex(struct tree_entry_list *e)\n-{\n-\treturn sha1_to_hex(e->directory\n-\t\t\t   ? e->item.tree->object.sha1\n-\t\t\t   : e->item.blob->object.sha1);\n-}\n-\n-/* forward declaration for mutually recursive routines */\n-static int show_entry(struct tree_entry_list *, int, char *pathbuf);\n-\n-static int show_children(struct tree_entry_list *e, int level, char *pathbuf)\n-{\n-\tint oldlen = strlen(pathbuf);\n-\n-\tif (e != &root_entry)\n-\t\tsprintf(pathbuf + oldlen, \"%s/\", e->name);\n-\n-\tif (prepare_children(e))\n-\t\tdie(\"internal error: ls-tree show_children called with non tree\");\n-\te = e->item.tree->entries;\n-\twhile (e) {\n-\t\tshow_entry(e, level, pathbuf);\n-\t\te = e->next;\n-\t}\n-\n-\tpathbuf[oldlen] = '\\0';\n-\n-\treturn 0;\n-}\n+static const char ls_tree_usage[] =\n+\t\"git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]\";\n \n-static int show_entry(struct tree_entry_list *e, int level, char *pathbuf)\n+static int show_tree(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage)\n {\n-\tint err = 0; \n-\n-\tif (e != &root_entry) {\n-\t\tprintf(\"%06o %s %s\t\",\n-\t\t       e->mode, entry_type(e), entry_hex(e));\n-\t\twrite_name_quoted(pathbuf, e->name, line_termination, stdout);\n-\t\tputchar(line_termination);\n-\t}\n+\tconst char *type = \"blob\";\n+\tint retval = 0;\n \n-\tif (e->directory) {\n-\t\t/* If this is a directory, we have the following cases:\n-\t\t * (1) This is the top-level request (explicit path from the\n-\t\t *     command line, or \"root\" if there is no command line).\n-\t\t *  a. Without any flag.  We show direct children.  We do not \n-\t\t *     recurse into them.\n-\t\t *  b. With -r.  We do recurse into children.\n-\t\t *  c. With -d.  We do not recurse into children.\n-\t\t * (2) We came here because our caller is either (1-a) or\n-\t\t *     (1-b).\n-\t\t *  a. Without any flag.  We do not show our children (which\n-\t\t *     are grandchildren for the original request).\n-\t\t *  b. With -r.  We continue to recurse into our children.\n-\t\t *  c. With -d.  We should not have come here to begin with.\n-\t\t */\n-\t\tif (level == 0 && !(ls_options & LS_TREE_ONLY))\n-\t\t\t/* case (1)-a and (1)-b */\n-\t\t\terr = err | show_children(e, level+1, pathbuf);\n-\t\telse if (level && ls_options & LS_RECURSIVE)\n-\t\t\t/* case (2)-b */\n-\t\t\terr = err | show_children(e, level+1, pathbuf);\n+\tif (S_ISDIR(mode)) {\n+\t\ttype = \"tree\";\n+\t\tif (ls_options & LS_RECURSIVE)\n+\t\t\tretval = READ_TREE_RECURSIVE;\n \t}\n-\treturn err;\n-}\n \n-static int list_one(const char *path)\n-{\n-\tint err = 0;\n-\tchar pathbuf[MAXPATHLEN + 1];\n-\tstruct tree_entry_list *e = find_entry(path, pathbuf);\n-\tif (!e) {\n-\t\t/* traditionally ls-tree does not complain about\n-\t\t * missing path.  We may change this later to match\n-\t\t * what \"/bin/ls -a\" does, which is to complain.\n-\t\t */\n-\t\treturn err;\n-\t}\n-\terr = err | show_entry(e, 0, pathbuf);\n-\treturn err;\n+\tprintf(\"%06o %s %s\\t%.*s%s%c\", mode, type, sha1_to_hex(sha1), baselen, base, pathname, line_termination);\n+\treturn retval;\n }\n \n-static int list(char **path)\n+int main(int argc, const char **argv)\n {\n-\tint i;\n-\tint err = 0;\n-\tfor (i = 0; path[i]; i++)\n-\t\terr = err | list_one(path[i]);\n-\treturn err;\n-}\n-\n-static const char ls_tree_usage[] =\n-\t\"git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]\";\n-\n-int main(int argc, char **argv)\n-{\n-\tstatic char *path0[] = { \"\", NULL };\n-\tchar **path;\n+\tconst char **path, *prefix;\n \tunsigned char sha1[20];\n+\tchar *buf;\n+\tunsigned long size;\n \n+\tprefix = setup_git_directory();\n \twhile (1 < argc && argv[1][0] == '-') {\n \t\tswitch (argv[1][1]) {\n \t\tcase 'z':\n@@ -244,9 +61,11 @@ int main(int argc, char **argv)\n \tif (get_sha1(argv[1], sha1) < 0)\n \t\tusage(ls_tree_usage);\n \n-\tpath = (argc == 2) ? path0 : (argv + 2);\n-\tprepare_root(sha1);\n-\tif (list(path) < 0)\n-\t\tdie(\"list failed\");\n+\tpath = get_pathspec(prefix, argv + 2);\n+\tbuf = read_object_with_reference(sha1, \"tree\", &size, NULL);\n+\tif (!buf)\n+\t\tdie(\"not a tree object\");\n+\tread_tree_recursive(buf, size, \"\", 0, 0, path, show_tree);\n+\n \treturn 0;\n }\ndiff --git a/tree.c b/tree.c\nindex 8b42a07..043f032 100644\n--- a/tree.c\n+++ b/tree.c\n@@ -9,9 +9,16 @@ const char *tree_type = \"tree\";\n \n static int read_one_entry(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage)\n {\n-\tint len = strlen(pathname);\n-\tunsigned int size = cache_entry_size(baselen + len);\n-\tstruct cache_entry *ce = xmalloc(size);\n+\tint len;\n+\tunsigned int size;\n+\tstruct cache_entry *ce;\n+\n+\tif (S_ISDIR(mode))\n+\t\treturn READ_TREE_RECURSIVE;\n+\n+\tlen = strlen(pathname);\n+\tsize = cache_entry_size(baselen + len);\n+\tce = xmalloc(size);\n \n \tmemset(ce, 0, size);\n \n@@ -67,9 +74,10 @@ static int match_tree_entry(const char *\n \treturn 0;\n }\n \n-static int read_tree_recursive(void *buffer, unsigned long size,\n-\t\t\t       const char *base, int baselen,\n-\t\t\t       int stage, const char **match)\n+int read_tree_recursive(void *buffer, unsigned long size,\n+\t\t\tconst char *base, int baselen,\n+\t\t\tint stage, const char **match,\n+\t\t\tread_tree_fn_t fn)\n {\n \twhile (size) {\n \t\tint len = strlen(buffer)+1;\n@@ -86,6 +94,14 @@ static int read_tree_recursive(void *buf\n \t\tif (!match_tree_entry(base, baselen, path, mode, match))\n \t\t\tcontinue;\n \n+\t\tswitch (fn(sha1, base, baselen, path, mode, stage)) {\n+\t\tcase 0:\n+\t\t\tcontinue;\n+\t\tcase READ_TREE_RECURSIVE:\n+\t\t\tbreak;;\n+\t\tdefault:\n+\t\t\treturn -1;\n+\t\t}\n \t\tif (S_ISDIR(mode)) {\n \t\t\tint retval;\n \t\t\tint pathlen = strlen(path);\n@@ -106,22 +122,20 @@ static int read_tree_recursive(void *buf\n \t\t\tretval = read_tree_recursive(eltbuf, eltsize,\n \t\t\t\t\t\t     newbase,\n \t\t\t\t\t\t     baselen + pathlen + 1,\n-\t\t\t\t\t\t     stage, match);\n+\t\t\t\t\t\t     stage, match, fn);\n \t\t\tfree(eltbuf);\n \t\t\tfree(newbase);\n \t\t\tif (retval)\n \t\t\t\treturn -1;\n \t\t\tcontinue;\n \t\t}\n-\t\tif (read_one_entry(sha1, base, baselen, path, mode, stage) < 0)\n-\t\t\treturn -1;\n \t}\n \treturn 0;\n }\n \n int read_tree(void *buffer, unsigned long size, int stage, const char **match)\n {\n-\treturn read_tree_recursive(buffer, size, \"\", 0, stage, match);\n+\treturn read_tree_recursive(buffer, size, \"\", 0, stage, match, read_one_entry);\n }\n \n struct tree *lookup_tree(const unsigned char *sha1)\ndiff --git a/tree.h b/tree.h\nindex 9975e88..768e5e9 100644\n--- a/tree.h\n+++ b/tree.h\n@@ -35,4 +35,13 @@ int parse_tree(struct tree *tree);\n /* Parses and returns the tree in the given ent, chasing tags and commits. */\n struct tree *parse_tree_indirect(const unsigned char *sha1);\n \n+#define READ_TREE_RECURSIVE 1\n+typedef int (*read_tree_fn_t)(unsigned char *, const char *, int, const char *, unsigned int, int);\n+\n+extern int read_tree_recursive(void *buffer, unsigned long size,\n+\t\t\tconst char *base, int baselen,\n+\t\t\tint stage, const char **match,\n+\t\t\tread_tree_fn_t fn);\n+\n+\n #endif /* TREE_H */\n"},{"id":"12773","messageId":"20051126184429.GH16995@mythryan2.michonline.com","threadId":"2615","inReplyTo":"7voe477n4i.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 0/8] Make C-level operable from subdirectories","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2005-11-26T18:44:29Z","receivedAt":"2005-11-26T18:44:29Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"On Sat, Nov 26, 2005 at 01:51:41AM -0800, Junio C Hamano wrote:\n> Linus Torvalds <torvalds@osdl.org> writes:\n> \n> > On Fri, 25 Nov 2005, Junio C Hamano wrote:\n> >>\n> >> I once advocated for an environment to name the top of working\n> >> tree directory --- it might make sense to resurrect that one.\n> >\n> > Please don't. \n> >\n> > We should just make the scripts do it automatically instead.\n> \n> Here comes an 8-patch series.\n\nShould the documentation get an update to mention that using GIT_DIR to\ncreate a totally out-of-tree setup is supported, but not recommended?\n\n-- \n\nRyan Anderson\n  sometimes Pug Majere\n"},{"id":"12774","messageId":"7vveyf1bqc.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511260932080.13959@g5.osdl.org","subject":"Re: [PATCH 1/8] git-apply: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-26T18:54:19Z","receivedAt":"2005-11-26T18:54:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> The only case where we care about a git directory is the \"--index\" case. \n> In all other cases we should happily apply it (or stat it).\n\nTrue.  We should do the same as peek-remote.\n"},{"id":"12782","messageId":"20051126235011.GA22159@pasky.or.cz","threadId":"2615","inReplyTo":"Pine.LNX.4.63.0511202039340.23586@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-11-26T23:50:11Z","receivedAt":"2005-11-26T23:50:11Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Sun, Nov 20, 2005 at 08:50:41PM CET, I got a letter\nwhere Johannes Schindelin <Johannes.Schindelin@gmx.de> said that...\n> > And I'm not 100% convinced that putting these branches in the config file \n> > has any real advantages over keeping them as separate files. Having \n> > everything in one place is nice, of course, and being able to copy just \n> > one file around might be convenient, but it _does_ make the config file \n> > more complicated.\n> \n> And it _does_ make finding the information for less savvy git users more \n> easy.\n\nIs that so?\n\nI'm not 50% convinced, but if people are excited about it, I can live\nwith it; in that case I would like appropriately powerful\ngit-repo-config, though - so that I can say \"list me all branch.*\nsection names\". Surely I could play some ugly grep games, but ideally,\nI would like to avoid peeking into the .git/config file directly\naltogether in Cogito - call that proper layering. ;-)\n\n> I'm not 100% convinced, either, but it could be a better concept than \n> different files in different places and different formats basically doing \n> the same.\n> \n> But my thinking went like this: if Pasky and Junio can not agree on one \n> location and format, and therefore none of the two is deprecated, how \n> about giving them a way out they both might be able to agree to?\n\nNow, those are just different concepts. Cogito's \"branch\" concept maps\nsingle local head to a single remote head, 1:1. GIT's \"remote\" concept\nmaps (possibly not well-defined) bunch of local heads to a remote\nrepository (where they have same or different name) or a piece of it; to\naccomplish this, it introduces a whole new rather complicated concept,\nwhich nevertheless in part shares the namespace with heads (branches).\n\nSurely, remotes are more flexible, but from the end-user perspective\nthey really act just as kind of \"macros\" compared to branches, except\nthat it's faster when you fetch multiple branches at once than when you\ndo it in sequence. I might add support for multibranch fetches to\nCogito, and I still intend to implement \"readonly\" remotes support for\nthe sake of compatibility with GIT, but I plan to stick to branches\notherwise. It's confusing enough to have remote and local heads, and\nactually remotes make it even more confusing since you direct your\n\"direct touch\" with the remote heads, now covered in some more abstract\nentity.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nVI has two modes: the one in which it beeps and the one in which\nit doesn't.\n"},{"id":"12783","messageId":"7vpsomorg9.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"20051126235011.GA22159@pasky.or.cz","subject":"Re: Get rid of .git/branches/ and .git/remotes/?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-27T00:38:30Z","receivedAt":"2005-11-27T00:38:30Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n>> But my thinking went like this: if Pasky and Junio can not agree on one \n>> location and format, and therefore none of the two is deprecated, how \n>> about giving them a way out they both might be able to agree to?\n>\n> Now, those are just different concepts. Cogito's \"branch\" concept maps\n> single local head to a single remote head, 1:1. GIT's \"remote\" concept\n> maps (possibly not well-defined) bunch of local heads to a remote\n> repository (where they have same or different name) or a piece of it...\n\nI agree.  They are simply different things and serve different\naudiences.\n\nWhen you are asked to pull from somebody else (and when you are\nplaying an integrator role, not an individual developer role,\nyou will be asked to pull from different people) you may not\nwant to immediately pull into your master branch.  I usually\neither do \"git checkout -b throwaway master\" and pull into it,\nor run \"git fetch remote master:throwaway\" followed by \"git diff\nmaster throwaway\" to see what I'll be getting.  When you set up\none \"remotes\" file is when you realize that you are pulling this\nway from the same place number of times, to reduce future\ntyping.  So as Pasky says, it is exactly \"macro\" and not \"per\nbranch configuration\".  It is just \"per remote shorthand\".\n\nCogito \"branch\" matches very naturally to what an individual\ndeveloper might want to do.  You have one branch that you use to\ndo your work tracking one upstream.  You can of course have more\nthan one upstream and branch, but the most typical usage would\nbe traditional CVS style setup to get updates from the central\nlocation (described in branches/* file), fetch and merge from\nthere and push your changes back.  It is very well designed to\nsupport this pattern of usage.\n\nIt may not make much sense for an integrator-role person to have\nbranches/master file to configure his \"master\" branch that\npoints at the URL of only one of his subsystem maintainers.  An\nintegrator-role person does not need \"per branch\" configuration\nin that sense.  On the other hand \"remotes\" may help if the\nintegrator-role person regularly pulls from the same set of\nsubsystem maintainers.\n\nOf course, an individual developer can set up a single remotes\nfile that describes the single upstream, fetching\n\"master:origin\" and merging into his \"master\"; what \"remotes\"\nfile used that way does not give us, unlike \"branch\" of Cogito,\nis that it does not say on which local branch that fetching and\nmerging happens.\n"},{"id":"12785","messageId":"7v4q5yohta.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511260932080.13959@g5.osdl.org","subject":"Re: [PATCH 1/8] git-apply: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-27T04:06:41Z","receivedAt":"2005-11-27T04:06:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> This breaks git-apply when used to just do a \"diffstat\", or\n> when used on a non-git repository.\n\nYou are right.  Something like this?\n\n\nAn off-topic note (that's why this message is CC'd to larsi).\nPeople may notice messages in this thread have accumulated a\nmodest number of References: entries.  I read git list via\nnew.gmane.org NNTP server (running fetchnews locally to slurp\nfrom there) and noticed droppage on my end --- whose cause turns\nout to be that gmane NNTP server chops References: entries in\nthe middle and fetchnews rejects such messages, and I am sure I\nam _not_ going to see this message on my local machine.  Has\nanybody else noticed this problem?\n\n-- >8 --\n[PATCH] apply: only do GIT_DIR discovery when running with --index.\n    \nIt does not have to be run in git repository unless we are\napplying or checking the patch to the index file.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\ndiff --git a/apply.c b/apply.c\nindex ae06d41..1742ab2 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -17,7 +17,7 @@\n //  --index-info shows the old and new index info for paths if available.\n //\n static const char *prefix;\n-static int prefix_length;\n+static int prefix_length = -1;\n \n static int allow_binary_replacement = 0;\n static int check_index = 0;\n@@ -1709,7 +1709,7 @@ static int use_patch(struct patch *p)\n \t\t\treturn 0;\n \t\tx = x->next;\n \t}\n-\tif (prefix && *prefix) {\n+\tif (0 < prefix_length) {\n \t\tint pathlen = strlen(pathname);\n \t\tif (pathlen <= prefix_length ||\n \t\t    memcmp(prefix, pathname, prefix_length))\n@@ -1793,10 +1793,6 @@ int main(int argc, char **argv)\n \tint i;\n \tint read_stdin = 1;\n \n-\tprefix = setup_git_directory();\n-\tprefix_length = prefix ? strlen(prefix) : 0;\n-\tgit_config(git_default_config);\n-\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \t\tint fd;\n@@ -1858,7 +1854,14 @@ int main(int argc, char **argv)\n \t\t\tline_termination = 0;\n \t\t\tcontinue;\n \t\t}\n-\t\targ = prefix_filename(prefix, prefix_length, arg);\n+\n+\t\tif (check_index && prefix_length < 0) {\n+\t\t\tprefix = setup_git_directory();\n+\t\t\tprefix_length = prefix ? strlen(prefix) : 0;\n+\t\t\tgit_config(git_default_config);\n+\t\t}\n+\t\tif (0 < prefix_length)\n+\t\t\targ = prefix_filename(prefix, prefix_length, arg);\n \n \t\tfd = open(arg, O_RDONLY);\n \t\tif (fd < 0)\n"},{"id":"12789","messageId":"7vr792fnta.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511251953081.13959@g5.osdl.org","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-27T09:21:53Z","receivedAt":"2005-11-27T09:21:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> And this is just ugly.\n>\n> git-ls-tree should be rewritten to use a pathspec the same way everybody \n> else does. Right now it's the odd man out: if you do\n>\n> \tgit-ls-tree HEAD divers/char drivers/\n>\n> it will show the same files _twice_, which is not how pathspecs in general \n> work.\n\nTrue; that is more or less deliberate.  The behaviour is\nmodelled after what \"/bin/ls -a\" does.\n\n> How about this patch? It breaks some of the git-ls-tree tests, but it \n> makes git-ls-tree work a lot more like other git pathspec commands, and it \n> removes more than 150 lines by re-using the recursive tree traversal (but \n> the \"-d\" flag is gone for good, so I'm not pushing this too hard).\n\nI am all for it if it were just me, and all the more so for its\ncleanup value.  I do not think anybody uses \"-d\" (none of\nCogito, StGIT nor gitweb seems to use it, and I have not seen\nJason McMullan, who wanted to have a way in ls-tree to see just\nthe object name of a subtree, on the list for a while); I\nsuspect that nobody would miss that option.\n\nHowever, this patch changes its behaviour in another way, and\nthat could impact Porcelains more than the removal of the \"-d\"\noption.  Currently, \"git-ls-tree <tree> $dir\" shows what\n\"/bin/ls -a -1 $dir\" would show --- the tree for $dir itself and\nits immediate children.  This patch changes it to show the tree\nfor $dir and nothing else.  In effect, \"-d\" becomes the default\nthat you cannot turn off, except using \"-r\" to allow it go all\nthe way down.\n\nI do not think StGIT is affected; it does not use ls-tree at all.\ngitweb is not affected either.  It does not use paths specifier.\n\nCogito might need a slight adjustment.\n\n - cg-admin-cat may want to use -r for the first one (${ARGS[@]}\n   may name a directory), but that also would change the\n   behaviour.  The current one shows only one level, instead of\n   going all the way down.\n\n - cg-log:117 uses ls-tree without -r, but I have a feeling that\n   it might be just a bug, even with the current ls-tree; I\n   suspect the user would not see things in subdirectories.\n   This is only for the initial commit so it may or may not\n   matter much.\n\n - cg-restore already uses ls-tree -r so that would not be\n   affected.\n"},{"id":"12791","messageId":"20051127110800.GE10680@pasky.or.cz","threadId":"2615","inReplyTo":"7vr792fnta.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-11-27T11:08:00Z","receivedAt":"2005-11-27T11:08:00Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Sun, Nov 27, 2005 at 10:21:53AM CET, I got a letter\nwhere Junio C Hamano <junkio@cox.net> said that...\n>  - cg-admin-cat may want to use -r for the first one (${ARGS[@]}\n>    may name a directory), but that also would change the\n>    behaviour.  The current one shows only one level, instead of\n>    going all the way down.\n\nI think the current behaviour is nonsensical, since it cats all the\nfiles in the subdirectory, instead of just listing it. Didn't\ngit-ls-tree already have the -d implicit sometime in the past? At any\nrate, the change to git-ls-tree would fix this. :-)\n\n>  - cg-log:117 uses ls-tree without -r, but I have a feeling that\n>    it might be just a bug, even with the current ls-tree; I\n>    suspect the user would not see things in subdirectories.\n>    This is only for the initial commit so it may or may not\n>    matter much.\n\nThanks, fixed. It uses -r now.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nVI has two modes: the one in which it beeps and the one in which\nit doesn't.\n"},{"id":"12799","messageId":"m364qef93a.fsf@quimbies.gnus.org","threadId":"2615","inReplyTo":"7v4q5yohta.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/8] git-apply: work from subdirectory.","fromName":"Lars Magne Ingebrigtsen","fromEmail":"larsi@gnus.org","sentAt":"2005-11-27T14:39:53Z","receivedAt":"2005-11-27T14:39:53Z","isPatch":true,"sender":{"key":"larsi@gnus.org","avatar":null},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> I read git list via new.gmane.org NNTP server (running fetchnews\n> locally to slurp from there) and noticed droppage on my end ---\n> whose cause turns out to be that gmane NNTP server chops References:\n> entries in the middle and fetchnews rejects such messages, and I am\n> sure I am _not_ going to see this message on my local machine.\n\nNo, news.gmane.org doesn't chop any references.  But if you happen to\nuse a news reader that takes rfc1036bis and rfc2822 seriously (like,\nahem, Gnus), it'll chop the References header to get the size under\n1024 octets.\n\nIf this gives fetchnews problems, then, er, fetchnews has problems.\nSerious problems.  \n\n-- \n(domestic pets only, the antidote for overdose, milk.)\n  larsi@gnus.org * Lars Magne Ingebrigtsen\n"},{"id":"12805","messageId":"Pine.LNX.4.64.0511270949540.13959@g5.osdl.org","threadId":"2615","inReplyTo":"7vr792fnta.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-27T18:01:37Z","receivedAt":"2005-11-27T18:01:37Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 27 Nov 2005, Junio C Hamano wrote:\n> \n> True; that is more or less deliberate.  The behaviour is\n> modelled after what \"/bin/ls -a\" does.\n\nYes, I did realize, and maybe it's fine. It's just that right now, \ngit-ls-tree doesn't work like git-ls-files, which is kind of sad.\n\nI suspect not a lot of people use git-ls-tree, and that's probably why it \nnever was updated to match anything else.\n\nIt would be nice (I think) if git-ls-tree matched git-ls-files the same \nway git-diff-tree matches git-diff-files: exact same behaviour, except one \nworks on a tree and another on the index. And like the git-diff-*, the \nindex would always default to \"-r\", while for the tree version you would \nhave to specify it.\n\n(Yeah, there are differences. git-ls-files has the \"--others\" etc logic, \nbut I think there are more similarities than differences).\n\n> However, this patch changes its behaviour in another way, and\n> that could impact Porcelains more than the removal of the \"-d\"\n> option.  Currently, \"git-ls-tree <tree> $dir\" shows what\n> \"/bin/ls -a -1 $dir\" would show --- the tree for $dir itself and\n> its immediate children.  This patch changes it to show the tree\n> for $dir and nothing else.  In effect, \"-d\" becomes the default\n> that you cannot turn off, except using \"-r\" to allow it go all\n> the way down.\n\nNo, actually, it's even stranger than that.\n\nIf you use \"-r\", it acts the way you'd expect. If you _don't_ use \"-r\", it \nacts strangely, but very consistently with git-diff-tree: it only ever \nshows the _first_ part of a pathname. So\n\n\tgit-ls-tree HEAD drivers/char/\n\nshould show just one entry: \"drivers\". While adding a \"-r\" should show all \nfiles under drivers (and the trees leading up to it).\n\nAnd yes, you're right. That's a much bigger change by my suggested diff, \nand more likely to cause confusion.\n\n\t\t\tLinus\n"},{"id":"12806","messageId":"20051127182244.GK22159@pasky.or.cz","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511270949540.13959@g5.osdl.org","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-11-27T18:22:44Z","receivedAt":"2005-11-27T18:22:44Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Sun, Nov 27, 2005 at 07:01:37PM CET, I got a letter\nwhere Linus Torvalds <torvalds@osdl.org> said that...\n> If you use \"-r\", it acts the way you'd expect. If you _don't_ use \"-r\", it \n> acts strangely, but very consistently with git-diff-tree: it only ever \n> shows the _first_ part of a pathname. So\n> \n> \tgit-ls-tree HEAD drivers/char/\n> \n> should show just one entry: \"drivers\". While adding a \"-r\" should show all \n> files under drivers (and the trees leading up to it).\n> \n> And yes, you're right. That's a much bigger change by my suggested diff, \n> and more likely to cause confusion.\n\nUgh. That's really weird. Wouldn't a better approach be to fix\ngit-ls-files to behave more sanely? (That is, listing the entry for\ndrivers/char instead of drivers?)\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nVI has two modes: the one in which it beeps and the one in which\nit doesn't.\n"},{"id":"12807","messageId":"Pine.LNX.4.64.0511271049090.13959@g5.osdl.org","threadId":"2615","inReplyTo":"20051127182244.GK22159@pasky.or.cz","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-27T19:00:09Z","receivedAt":"2005-11-27T19:00:09Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 27 Nov 2005, Petr Baudis wrote:\n\n> Dear diary, on Sun, Nov 27, 2005 at 07:01:37PM CET, I got a letter\n> where Linus Torvalds <torvalds@osdl.org> said that...\n> > If you use \"-r\", it acts the way you'd expect. If you _don't_ use \"-r\", it \n> > acts strangely, but very consistently with git-diff-tree: it only ever \n> > shows the _first_ part of a pathname. So\n> > \n> > \tgit-ls-tree HEAD drivers/char/\n> > \n> > should show just one entry: \"drivers\". While adding a \"-r\" should show all \n> > files under drivers (and the trees leading up to it).\n> > \n> > And yes, you're right. That's a much bigger change by my suggested diff, \n> > and more likely to cause confusion.\n> \n> Ugh. That's really weird. Wouldn't a better approach be to fix\n> git-ls-files to behave more sanely? (That is, listing the entry for\n> drivers/char instead of drivers?)\n\nWell, it's not actually confusing if you see a path spec for what it is: \nit's not a filename, it's a _pattern_.\n\nSo you should always do\n\n\tgit-ls-tree -r pattern\n\n(and yes, we could even hardcode \"-r\", because git-ls-tree without it \nreally is a pretty strange thing).\n\nThe _real_ strangeness in \"git-ls-tree\" is that it shows the tree nodes at \nall, which no other git tool does when it recurses. \n\nTo get more a \"git-ls-files\" approach, this trivial patch (on top of my \nprevious one) enables recursion (and right now you can't disable it any \nway), and doesn't show partial trees.\n\nI could make it work much more like git-ls-files, in that it could accept \nwildcards. Something like\n\n\tgit-ls-tree HEAD '*.c'\n\nwould show all C files (recursively), the same way git-ls-files does for \nthe index.\n\nHmm?\n\n\t\tLinus\n\n----\ndiff --git a/ls-tree.c b/ls-tree.c\nindex 598b729..cf0dbbc 100644\n--- a/ls-tree.c\n+++ b/ls-tree.c\n@@ -11,7 +11,7 @@\n static int line_termination = '\\n';\n #define LS_RECURSIVE 1\n #define LS_TREE_ONLY 2\n-static int ls_options = 0;\n+static int ls_options = LS_RECURSIVE;\n \n static const char ls_tree_usage[] =\n \t\"git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]\";\n@@ -19,16 +19,15 @@ static const char ls_tree_usage[] =\n static int show_tree(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage)\n {\n \tconst char *type = \"blob\";\n-\tint retval = 0;\n \n \tif (S_ISDIR(mode)) {\n-\t\ttype = \"tree\";\n \t\tif (ls_options & LS_RECURSIVE)\n-\t\t\tretval = READ_TREE_RECURSIVE;\n+\t\t\treturn READ_TREE_RECURSIVE;\n+\t\ttype = \"tree\";\n \t}\n \n \tprintf(\"%06o %s %s\\t%.*s%s%c\", mode, type, sha1_to_hex(sha1), baselen, base, pathname, line_termination);\n-\treturn retval;\n+\treturn 0;\n }\n \n int main(int argc, const char **argv)\n"},{"id":"12816","messageId":"m3fyph7q14.fsf@quimbies.gnus.org","threadId":"2615","inReplyTo":"7vy839dfzk.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/8] git-apply: work from subdirectory.","fromName":"Lars Magne Ingebrigtsen","fromEmail":"larsi@gnus.org","sentAt":"2005-11-27T21:13:27Z","receivedAt":"2005-11-27T21:13:27Z","isPatch":true,"sender":{"key":"larsi@gnus.org","avatar":null},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> It may be that news.gmane.org doesn't chop, but somebody between\n> vger.kernel.org mailing list manager and what comes out of the\n> newsserver does. \n\nEgads!  It's all my fault -- there's some code in the mail-to-news\nscript that's truncating long header lines, and nobody's noticed up\n'till now.  I've now twiddled it slightly; it should stop mangling\nReferences headers now...\n\n-- \n(domestic pets only, the antidote for overdose, milk.)\n  larsi@gnus.org * Lars Magne Ingebrigtsen\n"},{"id":"12820","messageId":"7voe45agfc.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"m3fyph7q14.fsf@quimbies.gnus.org","subject":"Re: [PATCH 1/8] git-apply: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-27T22:12:39Z","receivedAt":"2005-11-27T22:12:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lars Magne Ingebrigtsen <larsi@gnus.org> writes:\n\n> Egads!  It's all my fault -- there's some code in the mail-to-news\n> script that's truncating long header lines, and nobody's noticed up\n> 'till now.  I've now twiddled it slightly; it should stop mangling\n> References headers now...\n\nThanks, it looks good now --- checked with your message I am\nresponding to ;-).\n"},{"id":"12832","messageId":"7vveyd37ic.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511271049090.13959@g5.osdl.org","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-28T01:07:07Z","receivedAt":"2005-11-28T01:07:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> On Sun, 27 Nov 2005, Petr Baudis wrote:\n>> Ugh. That's really weird. Wouldn't a better approach be to fix\n>> git-ls-files to behave more sanely? (That is, listing the entry for\n>> drivers/char instead of drivers?)\n\nIt behaves sanely, just not in the way you are expecting.\n\n> Well, it's not actually confusing if you see a path spec for\n> what it is: it's not a filename, it's a _pattern_.\n\nWell, that is confusing, although it may be sane.\n\n> So you should always do\n>\n> \tgit-ls-tree -r pattern\n>\n> (and yes, we could even hardcode \"-r\", because git-ls-tree without it \n> really is a pretty strange thing).\n\nIf you mean \"in the presense of pathspec, default to -r\", I\n*might* agree, but I am not convinced yet.\n\nWithout pathspec, ls-tree is a pretty-printing version of\n\"git-cat-file tree\", and that is how the command is used by the\ngit browsers like gitweb.  I have never looked at qgit source,\nbut I'd be surprised if it did not depend on the single-level\nbehaviour of ls-tree for that purpose.\n\nIt *is* \"/bin/ls\" after all, and you _would_ get annoyed if your\n/bin/ls always recursed if you gave an argument.  Imagine going\nto the kernel source and try \"/bin/ls arch\" with your version of\n/bin/ls that always recurses, when you only wanted to get the\nlist of architectures you are supporting ;-).\n\n> The _real_ strangeness in \"git-ls-tree\" is that it shows the tree nodes at \n> all, which no other git tool does when it recurses. \n\nVery true.  I do not think even git browsers need that but I may\nbe mistaken.\n\nHaving said all of the above, I do understand why we would\n_also_ want the behaviour parallel to ls-files, not /bin/ls\nbehaviour.  Maybe we should have both?  Either rename the\ncurrent ls-tree to browse-tree, and make the one that parallels\nls-files the new ls-tree?\n"},{"id":"12833","messageId":"Pine.LNX.4.64.0511271742520.13959@g5.osdl.org","threadId":"2615","inReplyTo":"7vveyd37ic.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-28T01:46:33Z","receivedAt":"2005-11-28T01:46:33Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 27 Nov 2005, Junio C Hamano wrote:\n> \n> Without pathspec, ls-tree is a pretty-printing version of\n> \"git-cat-file tree\", and that is how the command is used by the\n> git browsers like gitweb.  I have never looked at qgit source,\n> but I'd be surprised if it did not depend on the single-level\n> behaviour of ls-tree for that purpose.\n\nYou're right, we need to keep the \"-r\" behaviour. \n\n> Having said all of the above, I do understand why we would\n> _also_ want the behaviour parallel to ls-files, not /bin/ls\n> behaviour.  Maybe we should have both?  Either rename the\n> current ls-tree to browse-tree, and make the one that parallels\n> ls-files the new ls-tree?\n\nIf you take my last patch and make \"ls_flags\" default to 0 again, it \nshould work correctly.\n\nThe way to traverse into directories (a la qgit/webgit) is to just give \nthe SHA1 name of the directory. Ie\n\n\tgit-ls-tree HEAD\n\ngives us a single level, we see:\n\n\t...\n\t040000 tree b2d1264f85148d18c5ae9864d73d65737b0a1734    t\n\t...\n\nand then we can just do\n\n\tgit-ls-tree b2d1264f85148d18c5ae9864d73d65737b0a1734\n\nto get that level. I assume that that is what qgit/webgit already does (I \nsure hope so, otherwise they're just wasting time, making the tools \nre-parse the trees over and over again for no gain).\n\n\t\t\tLinus\n"},{"id":"12840","messageId":"7vpsol1ett.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511271742520.13959@g5.osdl.org","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-28T06:11:58Z","receivedAt":"2005-11-28T06:11:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> You're right, we need to keep the \"-r\" behaviour. \n> If you take my last patch and make \"ls_flags\" default to 0 again, it \n> should work correctly.\n\nMaybe making \"-r\" the default and resurrecting \"-d\" to turn it\noff would be the approach of least impact (-r becomes a\nnoiseword), if we take this \"ls-tree should parallel ls-files\"\nidea.\n\nThe merge-recursive strategy uses ls-tree without -r with path\nspecifier to grab the sha1/mode of the three trees involved.\ngit-cvsexportcommit has the same assumption on how ls-tree\nworks.  It extracts a single SHA1 for the blob from the commit\nobject by \"ls-tree $commit $blob_path\".\n\nWith your two patches, they need to do this with \"-r\".\n\ngit-checkout and git-reset use -r to grab the whole tree, so\nthey are fine either way.  git-svnimport uses -r to read from a\ntree (potentially a subtree) all the way down, so this one is\nalso fine.\n\nSo it probably is safer to default ls_options to LS_RECURSIVE,\nand use \"-d\" to restrict it not to recurse.\n\nBut after seeing some more examples, I tend to think the current\none that models after how \"/bin/ls -a\" works in a way that is a\nlot easier to understand.  For example, with your two patches\n(defaulting to recursive)\n\n\tgit-ls-tree HEAD\n\nshows everything from the tree.  In order to get prettyprint of\nHEAD tree (i.e. single level listing):\n\n\tgit-ls-tree -d HEAD\n\nis needed.  But there is no way to get the single level with\npathspec with these patches, so:\n\n\tcd Documentation && git-ls-tree -d HEAD\n\nwould not show the single level of Documentation tree, but just\na single line \"tree\" object of Documentation tree.  Which means\nthe way it works from the top and the way it works in a\nsubdirectory is quite different.\n\nI'll throw in your two patches to the proposed updates branch so\nthat Porcelain/Browser people can play with it and decide.  I\nreally love the decrease of number of lines of code, but I am\nafraid this would end up breaking things without real merit.\n"},{"id":"12844","messageId":"Pine.LNX.4.64.0511272219420.13959@g5.osdl.org","threadId":"2615","inReplyTo":"7vpsol1ett.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-28T06:48:08Z","receivedAt":"2005-11-28T06:48:08Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 27 Nov 2005, Junio C Hamano wrote:\n> \n> So it probably is safer to default ls_options to LS_RECURSIVE,\n> and use \"-d\" to restrict it not to recurse.\n\nI have a patch that solves all the problems, I think.\n\nIt modifies the selection a bit, so that a pathspec that is a superset of \na particular tree path will always cause it to recurse into that tree.\n\nAs an example, let's say that we do\n\n\tgit-ls-tree HEAD drivers/char\n\n_without_ the \"-r\". What will happen is that it will start out doing all \nthe base tree, and for \"drivers\" it will notice that it's a proper subset \nof \"drivers/char\", so it will always recurse into _that_ tree (but not \ninto other trees).\n\nThen, it will not match anything else than \"char\" in that subdirectory, \nand because that's not a proper superset (it's an exact match), it will \n_not_ recurse into it, so you get:\n\n\t[torvalds@g5 linux]$ ~/git/git-ls-tree HEAD drivers/char\n\t040000 tree 9568cda453aae205bb58983747fa73b9696d9d51    drivers/char\n\nwhich is what you got with the old git-ls-tree too.\n\nBut interestingly, if you add the slash, it will become a proper superset \nand it will recurse into _that_ subdirectory (but no deeper: so if you \nwant all subdirectories _below_ drivers/char/, you still need to give \n\"-r\"):\n\n\t[torvalds@g5 linux]$ ~/git/git-ls-tree HEAD drivers/char/\n\t100644 blob 2b6b1d772ed776fff87927fc34adc2e40500218e    drivers/char/.gitignore\n\t100644 blob 56b8a2e76ab10a5c21787cb7068a846075cbaffd    drivers/char/ChangeLog\n\t100644 blob 970f70d498f4c814e1cf3362e33d7e23ac53c299    drivers/char/Kconfig\n\t...\n\nSee? This is on top of the previous two diffs, holler if you want a whole \nnew \"everything combined\" version..\n\nIt hasn't gotten lots of testing, but it should work.\n\nBTW! It fails a few of the tests, but it does so because now, with \"-r\", \nit will never show the tree entries, and because of the difference between\n\n\tgit-ls-tree $tree path\n\nand\n\n\tgit-ls-tree $tree path/\n\nthat it didn't use to have (oh, and if you give multiple paths, it will \nnow always consider them a \"union pathspec\", not an \"iteration of paths\"). \nBut I _think_ the new behaviour is pretty useful and while not the same as \n\"ls\", it's perhaps still intuitive enough..\n\n\t\tLinus\n\n---\ndiff --git a/ls-tree.c b/ls-tree.c\nindex cf0dbbc..4df5830 100644\n--- a/ls-tree.c\n+++ b/ls-tree.c\n@@ -11,7 +11,8 @@\n static int line_termination = '\\n';\n #define LS_RECURSIVE 1\n #define LS_TREE_ONLY 2\n-static int ls_options = LS_RECURSIVE;\n+static int ls_options = 0;\n+const char **pathspec;\n \n static const char ls_tree_usage[] =\n \t\"git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]\";\n@@ -21,8 +22,29 @@ static int show_tree(unsigned char *sha1\n \tconst char *type = \"blob\";\n \n \tif (S_ISDIR(mode)) {\n+\t\tconst char **s;\n \t\tif (ls_options & LS_RECURSIVE)\n \t\t\treturn READ_TREE_RECURSIVE;\n+\t\ts = pathspec;\n+\t\tif (s) {\n+\t\t\tfor (;;) {\n+\t\t\t\tconst char *spec = *s++;\n+\t\t\t\tint len, speclen;\n+\n+\t\t\t\tif (!spec)\n+\t\t\t\t\tbreak;\n+\t\t\t\tif (strncmp(base, spec, baselen))\n+\t\t\t\t\tcontinue;\n+\t\t\t\tlen = strlen(pathname);\n+\t\t\t\tspec += baselen;\n+\t\t\t\tspeclen = strlen(spec);\n+\t\t\t\tif (speclen <= len)\n+\t\t\t\t\tcontinue;\n+\t\t\t\tif (memcmp(pathname, spec, len))\n+\t\t\t\t\tcontinue;\n+\t\t\t\treturn READ_TREE_RECURSIVE;\n+\t\t\t}\n+\t\t}\n \t\ttype = \"tree\";\n \t}\n \n@@ -32,7 +54,7 @@ static int show_tree(unsigned char *sha1\n \n int main(int argc, const char **argv)\n {\n-\tconst char **path, *prefix;\n+\tconst char *prefix;\n \tunsigned char sha1[20];\n \tchar *buf;\n \tunsigned long size;\n@@ -60,11 +82,11 @@ int main(int argc, const char **argv)\n \tif (get_sha1(argv[1], sha1) < 0)\n \t\tusage(ls_tree_usage);\n \n-\tpath = get_pathspec(prefix, argv + 2);\n+\tpathspec = get_pathspec(prefix, argv + 2);\n \tbuf = read_object_with_reference(sha1, \"tree\", &size, NULL);\n \tif (!buf)\n \t\tdie(\"not a tree object\");\n-\tread_tree_recursive(buf, size, \"\", 0, 0, path, show_tree);\n+\tread_tree_recursive(buf, size, \"\", 0, 0, pathspec, show_tree);\n \n \treturn 0;\n }\n"},{"id":"12849","messageId":"7v64qdyxxx.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511272219420.13959@g5.osdl.org","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-28T08:32:42Z","receivedAt":"2005-11-28T08:32:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> BTW! It fails a few of the tests, but it does so because now, with \"-r\", \n> it will never show the tree entries, and because of the difference between\n>\n> \tgit-ls-tree $tree path\n>\n> and\n>\n> \tgit-ls-tree $tree path/\n>\n> that it didn't use to have (oh, and if you give multiple paths, it will \n> now always consider them a \"union pathspec\", not an \"iteration of paths\"). \n> But I _think_ the new behaviour is pretty useful and while not the same as \n> \"ls\", it's perhaps still intuitive enough..\n\nThe difference between path and path/ is very cute ;-).  I do\nnot do Porcelain myself, so I am OK with this change, but this\nwould involve some changes to the Porcelain.\n\nSo let's cook this for a while and have Porcelain people holler\nif they find something lacking.  I'll put this in the proposed\nupdates tonight, and we will plan to push everything in the\nproposed updates branch to the master branch on Wednesday, with\nany fixes and updates necessary.\n"},{"id":"12860","messageId":"7v3blhvye8.fsf@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"7v64qdyxxx.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 6/8] ls-tree: work from subdirectory.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-28T10:51:11Z","receivedAt":"2005-11-28T10:51:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> So let's cook this for a while and have Porcelain people holler\n> if they find something lacking.  I'll put this in the proposed\n> updates tonight, and we will plan to push everything in the\n> proposed updates branch to the master branch on Wednesday, with\n> any fixes and updates necessary.\n\nOK, so I did some tests adjustments (they are in \"pu\").  Most\ndifferences are easily explained but some are not.\n\nEasy ones:\n\n    - With -r, tree entries are not shown.\n\n    - Unlike /bin/ls arguments, the paths are now filters, so\n      no duplicates on the output, nor the output order does not\n      depend on command line argument order.\n\n    - \"path\" shows the tree if path corresponds to a directory;\n      say \"path/\" to get its contents.\n\nHowever I do not have an easy way to explain how these two work\nthe way they do.  Taken from t/t3101 test.\n\nThe first one has both path0/a/b/c and path0/a in the filter,\nand path0/a tree entry itself is not shown because it \"recurses\nthrough it\".\n\n+# I am not so sure about this one after ls-tree doing pathspec match.\n+# Having both path0/a and path0/a/b/c makes path0/a redundant, and\n+# it behaves as if path0/a/b/c, path1/b/c, path2 and path3 are specified.\n test_expect_success \\\n     'ls-tree filter directories' \\\n     'git-ls-tree $tree path3 path2 path0/a/b/c path1/b/c path0/a >current &&\n      cat >expected <<\\EOF &&\n-040000 tree X\tpath3\n-100644 blob X\tpath3/1.txt\n-100644 blob X\tpath3/2.txt\n-040000 tree X\tpath2\n-100644 blob X\tpath2/1.txt\n 040000 tree X\tpath0/a/b/c\n-100644 blob X\tpath0/a/b/c/1.txt\n 040000 tree X\tpath1/b/c\n-100644 blob X\tpath1/b/c/1.txt\n-040000 tree X\tpath0/a\n-040000 tree X\tpath0/a/b\n+040000 tree X\tpath2\n+040000 tree X\tpath3\n EOF\n      test_output'\n\nThe second one is the same; since there is path3/, it recurses\nthrough it and path3 itself is not shown but its contents are.\nIt is showing both path3/1.txt and path3/2.txt not because\npath3/1.txt is specified but path3/ was specified.\n\n+# Again, duplicates are filtered away so this is equivalent to\n+# having 1.txt and path3/\n test_expect_success \\\n     'ls-tree filter odd names' \\\n     'git-ls-tree $tree 1.txt /1.txt //1.txt path3/1.txt /path3/1.txt //path3//1.txt path3 /path3/ path3// >current &&\n      cat >expected <<\\EOF &&\n 100644 blob X\t1.txt\n-100644 blob X\t1.txt\n-100644 blob X\t1.txt\n-100644 blob X\tpath3/1.txt\n-100644 blob X\tpath3/1.txt\n-100644 blob X\tpath3/1.txt\n-040000 tree X\tpath3\n-100644 blob X\tpath3/1.txt\n-100644 blob X\tpath3/2.txt\n-040000 tree X\tpath3\n-100644 blob X\tpath3/1.txt\n-100644 blob X\tpath3/2.txt\n-040000 tree X\tpath3\n 100644 blob X\tpath3/1.txt\n 100644 blob X\tpath3/2.txt\n EOF\n"},{"id":"12861","messageId":"7vwtitujso.fsf_-_@assigned-by-dhcp.cox.net","threadId":"2615","inReplyTo":"Pine.LNX.4.64.0511272219420.13959@g5.osdl.org","subject":"[PATCH] ls-tree: Resurrect funny name quoting lost during rewrite.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-28T10:51:51Z","receivedAt":"2005-11-28T10:51:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The rewrite to match ls-files/diff-tree behaviour accidentally\nlost the name quoting.  I am not proud about this code, but this\nwould get the test going.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n ls-tree.c |   10 +++++++++-\n 1 files changed, 9 insertions(+), 1 deletions(-)\n\napplies-to: 4db95789ce3af40091ead2a97a72e75f9a0b8384\ne7cdcbbbbd2fd2848244f998a0b92338fc68fe78\ndiff --git a/ls-tree.c b/ls-tree.c\nindex 4df5830..df3bcec 100644\n--- a/ls-tree.c\n+++ b/ls-tree.c\n@@ -48,7 +48,15 @@ static int show_tree(unsigned char *sha1\n \t\ttype = \"tree\";\n \t}\n \n-\tprintf(\"%06o %s %s\\t%.*s%s%c\", mode, type, sha1_to_hex(sha1), baselen, base, pathname, line_termination);\n+\tprintf(\"%06o %s %s\\t\", mode, type, sha1_to_hex(sha1));\n+\tif (1) {\n+\t\t/* NEEDSWORK: */\n+\t\tchar base_[baselen + 1];\n+\t\tmemcpy(base_, base, baselen);\n+\t\tbase_[baselen] = 0;\n+\t\twrite_name_quoted(base_, pathname, line_termination, stdout);\n+\t}\n+\tputchar(line_termination);\n \treturn 0;\n }\n \n---\n0.99.9.GIT\n"}]}