{"thread":{"id":"41529","subject":"Fwd: git clone does not respect command line options","startedAt":"2016-02-26T06:47:49Z","lastAt":"2016-02-28T05:01:13Z","messageCount":12,"participants":["Guilherme","Jeff King","Jacob Keller","Duy Nguyen","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"279485","messageId":"CAMDzUtxQPMty0Nncr7Yj3up6Zb6F-E0QudOMOZO_jG-Goq0YBg@mail.gmail.com","threadId":"41529","inReplyTo":"CAMDzUtzoiJWzckTX818HJV=su0eEP35gsNDJ=+k_me08EDvxRg@mail.gmail.com","subject":"Fwd: git clone does not respect command line options","fromName":"Guilherme","fromEmail":"guibufolo@gmail.com","sentAt":"2016-02-26T06:47:49Z","receivedAt":"2016-02-26T06:47:49Z","isPatch":false,"sender":{"key":"guibufolo@gmail.com","avatar":null},"body":"Hi!\n\nI'm trying to use git in an integration test and i'm having trouble\nwith configuration options.\n\nOn windows developer machines we use wincred as our credenital helper\nand thus have it set in ~/.gitconfig\n\nFor the integration test that is no use as it will make testing\nunauthorized logging in impossible.\n\nSince there is no way of disabling configuration options on the\ncommand line i tried setting it to store with a file I could delete.\nSo in front of every command we insert `-c credential.helper=\"store\n--file=creds.txt\"`. In the end the command line looks like:\n\ngit -c credential.helper=\"store --file=creds.txt\" clone\nhttp://admin:admin@oururl@20000/TestRepo.git\n\nI see the file creds.txt being created containing only\nhttp://admin:admin@oururl@20000/TestRepo.git but the credenital at the\nsame time appears in the windows credential store.\n\nCan anybody else confirm this?\n\nThank you.\n"},{"id":"279489","messageId":"20160226073444.GA26340@sigill.intra.peff.net","threadId":"41529","inReplyTo":"CAMDzUtxQPMty0Nncr7Yj3up6Zb6F-E0QudOMOZO_jG-Goq0YBg@mail.gmail.com","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-26T07:34:44Z","receivedAt":"2016-02-26T07:34:44Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Feb 26, 2016 at 12:17:49PM +0530, Guilherme wrote:\n\n> I'm trying to use git in an integration test and i'm having trouble\n> with configuration options.\n> \n> On windows developer machines we use wincred as our credenital helper\n> and thus have it set in ~/.gitconfig\n> \n> For the integration test that is no use as it will make testing\n> unauthorized logging in impossible.\n> \n> Since there is no way of disabling configuration options on the\n> command line i tried setting it to store with a file I could delete.\n> So in front of every command we insert `-c credential.helper=\"store\n> --file=creds.txt\"`. In the end the command line looks like:\n> \n> git -c credential.helper=\"store --file=creds.txt\" clone\n> http://admin:admin@oururl@20000/TestRepo.git\n> \n> I see the file creds.txt being created containing only\n> http://admin:admin@oururl@20000/TestRepo.git but the credenital at the\n> same time appears in the windows credential store.\n> \n> Can anybody else confirm this?\n\nThat's behaving as expected. Unfortunately, you cannot currently do what\nyou want easily; there is no way to \"unset\" a multi-valued config\nvariable (like credential.helper) with a later one. Git will ask both\nconfigured helpers for the password, and will store a successful result\nin both.\n\nThe simplest way I can think of to work around it is to point your $HOME\nelsewhere[1] during the integration test, so that it does not read your\nregular ~/gitconfig.\n\n-Peff\n\n[1] Actually, that is what I would do on a Unix system. I have no idea\n    how the home directory is determined on Windows.\n"},{"id":"279490","messageId":"CAMDzUty5oWjS=4kvvYL7XNCY=xHm3N=+kaeT_zTtpkaMakMrmA@mail.gmail.com","threadId":"41529","inReplyTo":"20160226073444.GA26340@sigill.intra.peff.net","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Guilherme","fromEmail":"guibufolo@gmail.com","sentAt":"2016-02-26T07:46:39Z","receivedAt":"2016-02-26T07:46:39Z","isPatch":false,"sender":{"key":"guibufolo@gmail.com","avatar":null},"body":"Thanks for the quick reply.\n\nIs there any documentation on which variables are muli-valued?\n\ngit -c credential.helper=\"store --file=creds\" config --get credential.helper\n\nonly returns one value.\n\nHow can i even know if there are multiple set. I mean someone might\nhave just created an extra credential.helper in `--system` that I'm\nnot expecting...\n\n\n\n\nOn Fri, Feb 26, 2016 at 1:04 PM, Jeff King <peff@peff.net> wrote:\n> On Fri, Feb 26, 2016 at 12:17:49PM +0530, Guilherme wrote:\n>\n>> I'm trying to use git in an integration test and i'm having trouble\n>> with configuration options.\n>>\n>> On windows developer machines we use wincred as our credenital helper\n>> and thus have it set in ~/.gitconfig\n>>\n>> For the integration test that is no use as it will make testing\n>> unauthorized logging in impossible.\n>>\n>> Since there is no way of disabling configuration options on the\n>> command line i tried setting it to store with a file I could delete.\n>> So in front of every command we insert `-c credential.helper=\"store\n>> --file=creds.txt\"`. In the end the command line looks like:\n>>\n>> git -c credential.helper=\"store --file=creds.txt\" clone\n>> http://admin:admin@oururl@20000/TestRepo.git\n>>\n>> I see the file creds.txt being created containing only\n>> http://admin:admin@oururl@20000/TestRepo.git but the credenital at the\n>> same time appears in the windows credential store.\n>>\n>> Can anybody else confirm this?\n>\n> That's behaving as expected. Unfortunately, you cannot currently do what\n> you want easily; there is no way to \"unset\" a multi-valued config\n> variable (like credential.helper) with a later one. Git will ask both\n> configured helpers for the password, and will store a successful result\n> in both.\n>\n> The simplest way I can think of to work around it is to point your $HOME\n> elsewhere[1] during the integration test, so that it does not read your\n> regular ~/gitconfig.\n>\n> -Peff\n>\n> [1] Actually, that is what I would do on a Unix system. I have no idea\n>     how the home directory is determined on Windows.\n"},{"id":"279492","messageId":"20160226075948.GA26994@sigill.intra.peff.net","threadId":"41529","inReplyTo":"CAMDzUty5oWjS=4kvvYL7XNCY=xHm3N=+kaeT_zTtpkaMakMrmA@mail.gmail.com","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-26T07:59:48Z","receivedAt":"2016-02-26T07:59:48Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Feb 26, 2016 at 01:16:39PM +0530, Guilherme wrote:\n\n> Is there any documentation on which variables are muli-valued?\n\nThere's no central registry. It's often mentioned in the documentation\nfor a particular config option, but it looks like the credential.*\nconfig is not very clear about this.\n\nThere aren't very many of them. I think credential.* is one set. The\nremote.*.fetch/push refspecs are another. I don't think there are any\nothers used by git itself, but I may just be forgetting them.\n\n> git -c credential.helper=\"store --file=creds\" config --get credential.helper\n> \n> only returns one value.\n> \n> How can i even know if there are multiple set. I mean someone might\n> have just created an extra credential.helper in `--system` that I'm\n> not expecting...\n\nRight. The \"git-config\" program doesn't know about the semantics of\nparticular values (remember that in the early days, there were many\nporcelains which built on top of git, and they could all store their own\nconfig). Using \"--get\" implements \"last one wins\" semantics, which\nis what most config variables want. You can use \"--get-all\" to see all\ninstances of a multi-valued variable.\n\nThe usability on all of this is obviously pretty horrible, but it's hard\nto change at this point without breaking backwards compatibility.\n\n-Peff\n"},{"id":"279496","messageId":"CA+P7+xpuiUQgWYRgVrwKkv27KiJGQ0COrR93cFzQzn2uVA6ypQ@mail.gmail.com","threadId":"41529","inReplyTo":"20160226075948.GA26994@sigill.intra.peff.net","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2016-02-26T08:15:46Z","receivedAt":"2016-02-26T08:15:46Z","isPatch":false,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Thu, Feb 25, 2016 at 11:59 PM, Jeff King <peff@peff.net> wrote:\n> Right. The \"git-config\" program doesn't know about the semantics of\n> particular values (remember that in the early days, there were many\n> porcelains which built on top of git, and they could all store their own\n> config). Using \"--get\" implements \"last one wins\" semantics, which\n> is what most config variables want. You can use \"--get-all\" to see all\n> instances of a multi-valued variable.\n>\n\nAnd note that several libraries of hooks and git extensions store\nconfiguration there as well, not just traditional porcelain. (Though\nmaybe that is considered porcelain? Not really sure on the term here).\nI do this myself for several custom git hooks.\n\nThanks,\nJake\n"},{"id":"279498","messageId":"20160226082437.GB26994@sigill.intra.peff.net","threadId":"41529","inReplyTo":"CA+P7+xpuiUQgWYRgVrwKkv27KiJGQ0COrR93cFzQzn2uVA6ypQ@mail.gmail.com","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-26T08:24:38Z","receivedAt":"2016-02-26T08:24:38Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Feb 26, 2016 at 12:15:46AM -0800, Jacob Keller wrote:\n\n> On Thu, Feb 25, 2016 at 11:59 PM, Jeff King <peff@peff.net> wrote:\n> > Right. The \"git-config\" program doesn't know about the semantics of\n> > particular values (remember that in the early days, there were many\n> > porcelains which built on top of git, and they could all store their own\n> > config). Using \"--get\" implements \"last one wins\" semantics, which\n> > is what most config variables want. You can use \"--get-all\" to see all\n> > instances of a multi-valued variable.\n> \n> And note that several libraries of hooks and git extensions store\n> configuration there as well, not just traditional porcelain. (Though\n> maybe that is considered porcelain? Not really sure on the term here).\n> I do this myself for several custom git hooks.\n\nThanks, I meant to add \"and it is unclear these days how many addons are\nstill using this feature\".\n\nI mentioned ugliness and backwards compatibility earlier.  I think\nhaving a meaning-agnostic git-config command is still a reasonable thing\nthese days. But given how few multi-valued variables there are, it might\nhave been worth designing them differently, so that everything is\nlast-one-wins.\n\nAs an alternative, it would be nice to have some config syntax for\n\"clear the list\". Maybe something like an empty string, which I think\nhas no meaning for the current multi-valued variables (at least not for\ncredential helpers or refspecs). That would allow something like:\n\n  git -c credential.helper= clone ...\n\nto do what you'd expect.\n\n-Peff\n"},{"id":"279500","messageId":"CACsJy8BK=2aKg68msH9vawHrXr=PsQYgs6sGXy0koy459MYfSA@mail.gmail.com","threadId":"41529","inReplyTo":"20160226082437.GB26994@sigill.intra.peff.net","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-02-26T08:34:53Z","receivedAt":"2016-02-26T08:34:53Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Feb 26, 2016 at 3:24 PM, Jeff King <peff@peff.net> wrote:\n> As an alternative, it would be nice to have some config syntax for\n> \"clear the list\". Maybe something like an empty string, which I think\n> has no meaning for the current multi-valued variables (at least not for\n> credential helpers or refspecs). That would allow something like:\n>\n>   git -c credential.helper= clone ...\n>\n> to do what you'd expect.\n\nI've been thinking of -= instead. It's unambiguous. And you can use\nwildcards on both sides. \"credential.helper -= *\" means delete that\nkey, \"credential.* -= *\" deletes all credential.* keys.\ncredential.helper -= abc only deletes it if the previous value is abc.\n-- \nDuy\n"},{"id":"279503","messageId":"20160226084514.GA28898@sigill.intra.peff.net","threadId":"41529","inReplyTo":"CACsJy8BK=2aKg68msH9vawHrXr=PsQYgs6sGXy0koy459MYfSA@mail.gmail.com","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-26T08:45:15Z","receivedAt":"2016-02-26T08:45:15Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Feb 26, 2016 at 03:34:53PM +0700, Duy Nguyen wrote:\n\n> On Fri, Feb 26, 2016 at 3:24 PM, Jeff King <peff@peff.net> wrote:\n> > As an alternative, it would be nice to have some config syntax for\n> > \"clear the list\". Maybe something like an empty string, which I think\n> > has no meaning for the current multi-valued variables (at least not for\n> > credential helpers or refspecs). That would allow something like:\n> >\n> >   git -c credential.helper= clone ...\n> >\n> > to do what you'd expect.\n> \n> I've been thinking of -= instead. It's unambiguous. And you can use\n> wildcards on both sides. \"credential.helper -= *\" means delete that\n> key, \"credential.* -= *\" deletes all credential.* keys.\n> credential.helper -= abc only deletes it if the previous value is abc.\n\nBut there you're inventing new syntax, so you'd need to invent new\nsyntax inside the config file, too. And you'd need to somehow\ncommunicate to the consumers of the config values that the value is\n\"unset\". So for config callbacks inside of git, they need to take more\nthan just the key/value pair (or we'd have to read all of the config and\npre-process it). Ditto for git-config. How do we show in the output of\n--get-all that the list was reset? Or again, we could pre-process\ncompletely in git-config (which would probably mean using a new option,\n--get-list or something, instead of --get-all).\n\nBy contrast, I think my suggestion can be implemented as:\n\ndiff --git a/credential.c b/credential.c\nindex 7d6501d..aa99666 100644\n--- a/credential.c\n+++ b/credential.c\n@@ -63,9 +63,12 @@ static int credential_config_callback(const char *var, const char *value,\n \t\tkey = dot + 1;\n \t}\n \n-\tif (!strcmp(key, \"helper\"))\n-\t\tstring_list_append(&c->helpers, value);\n-\telse if (!strcmp(key, \"username\")) {\n+\tif (!strcmp(key, \"helper\")) {\n+\t\tif (*value)\n+\t\t\tstring_list_append(&c->helpers, value);\n+\t\telse\n+\t\t\tstring_list_clear(&c->helpers, 0);\n+\t} else if (!strcmp(key, \"username\")) {\n \t\tif (!c->username)\n \t\t\tc->username = xstrdup(value);\n \t}\n\nThe big downside is that each consumer of the value needs to learn this\ntrick. But as I said, I think there aren't very many.\n\nDon't get me wrong; I think your suggestion is a little cleaner. If we\nwere designing the config system from scratch, I'd probably favor a\nsingle query-able tree rather than the callback system, and do things\nlike list-processing centrally. But given the history, I'm not sure if\nit's worth it now.\n\n-Peff\n"},{"id":"279509","messageId":"20160226095755.GA4361@sigill.intra.peff.net","threadId":"41529","inReplyTo":"CAMDzUtwG9pLz6CqxVEaw5xcZwQ2Ni37h_R45+frzJrRshgpZQg@mail.gmail.com","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-26T09:57:55Z","receivedAt":"2016-02-26T09:57:55Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Feb 26, 2016 at 03:23:58PM +0530, Guilherme wrote:\n\n> I did try -c credential.helper= and there was a second problem with that\n> because an unset credential.helper is not the same as an empty\n> credential.helper. An empty one printed an error because it tried to invoke\n> 'git-credential-'.\n\nExactly. That's why I say that we can take over the empty string to mean\n\"clear the list\"; it's currently nonsensical.\n\n-Peff\n"},{"id":"279536","messageId":"xmqqegbzl86d.fsf@gitster.mtv.corp.google.com","threadId":"41529","inReplyTo":"20160226073444.GA26340@sigill.intra.peff.net","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-26T16:59:06Z","receivedAt":"2016-02-26T16:59:06Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> That's behaving as expected. Unfortunately, you cannot currently do what\n> you want easily; there is no way to \"unset\" a multi-valued config\n> variable (like credential.helper) with a later one. Git will ask both\n> configured helpers for the password, and will store a successful result\n> in both.\n>\n> The simplest way I can think of to work around it is to point your $HOME\n> elsewhere[1] during the integration test, so that it does not read your\n> regular ~/gitconfig.\n\nYup, that was the reaction I initially had.  I saw your \"setting\nhelper to an empty string does not mean anything sensible, so let's\nuse it as a signal to clear the list\" patch and I think that is a\nreasonable workaround.\n\nThanks.\n"},{"id":"279679","messageId":"CAMDzUtyjf2LwYJTYcY588LgrSNfusX=L09oFeS4UhLjH+WpEOQ@mail.gmail.com","threadId":"41529","inReplyTo":"xmqqegbzl86d.fsf@gitster.mtv.corp.google.com","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Guilherme","fromEmail":"guibufolo@gmail.com","sentAt":"2016-02-28T03:37:23Z","receivedAt":"2016-02-28T03:37:23Z","isPatch":false,"sender":{"key":"guibufolo@gmail.com","avatar":null},"body":"What is the current situation if credential.helper is set twice in the\nsame config file.\n\nEither\n[credential]\n  helper = first\n  helper = second\n\nor with\n[credential]\n  helper = first\n\n[credenital]\n  helper = second\n\nWill both be used by git clone?\n\nHow do i remove these from the command line?\nI tried git config --unset credential.helper but that only gives you a\nwarning and does not remove any.\n\nWorse is that if second is the empty string there is no way for one to\nknow there is a second set unless he tries to delete the first one.\nBut one still cannot query the value of the second.\n"},{"id":"279683","messageId":"20160228050113.GA19131@sigill.intra.peff.net","threadId":"41529","inReplyTo":"CAMDzUtxnSeTrfBWWqeOVQm30x5nE6fC9LSx=YNSws2h24TmchQ@mail.gmail.com","subject":"Re: Fwd: git clone does not respect command line options","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-28T05:01:13Z","receivedAt":"2016-02-28T05:01:13Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Feb 28, 2016 at 09:03:43AM +0530, Guilherme wrote:\n\n> What is the current situation if credential.helper is set twice in the same\n> config file.\n> \n> Either\n> [credential]\n>   helper = first\n>   helper = second\n> \n> or with\n> [credential]\n>   helper = first\n> \n> [credenital]\n>   helper = second\n> \n> Will both be used by git clone?\n\nYes, both are used, as documented in gitcredentials(7).\n\n> How do i remove these from the command line?\n> I tried git config --unset credential.helper but that only gives you a\n> warning and does not remove any.\n\nTry --unset-all.\n\nAlso make sure you tell \"git config\" to operate on the file that\nactually contains them. In v2.8.0-rc0 (but not in any released version),\nwe have --show-origin, and you can do:\n\n  $ git config --show-origin --get-all credential.helper\n  file:/home/peff/.gitconfig      cache\n  file:.git/config        first\n  file:.git/config        second\n\nWrite operations work on .git/config by default; if the entries are in\nyour ~/.gitconfig, use \"--global --unset-all\".\n\n> Worse is that if second is the empty string there is no way for one to know\n> there is a second set unless he tries to delete the first one. But one\n> still cannot query the value of the second.\n\nTry --get-all, which will print all values for a key (you can also use\n--get-regexp if you want to find other credential.* keys).\n\n-Peff\n"}]}