{"thread":{"id":"30622","subject":"[PATCH 2/2] Test File Name: t1306-second-config-file.sh","startedAt":"2012-05-25T19:47:18Z","lastAt":"2012-05-28T21:05:39Z","messageCount":12,"participants":["NGUYEN Huynh Khoi Nguyen","Jeff King","Junio C Hamano","jaseem abid","Matthieu Moy","Nguyen Thai Ngoc Duy","David Aguilar"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"192203","messageId":"1337975239-17169-1-git-send-email-nguyenhu@ensibm.imag.fr","threadId":"30622","inReplyTo":null,"subject":"[PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"NGUYEN Huynh Khoi Nguyen","fromEmail":"nguyenhu@ensimag.imag.fr","sentAt":"2012-05-25T19:47:18Z","receivedAt":"2012-05-25T19:47:18Z","isPatch":true,"sender":{"key":"nguyenhu@ensimag.imag.fr","avatar":null},"body":"git will store its configuration in ~/.config/git/config file if this file\nexists and ~/.gitconfig file doesn't, otherwise git store its configuration\nin ~/.gitconfig as usual\n---\n builtin/config.c |   31 ++++++++++++++++++++++++++++---\n config.c         |   15 ++++++++++++++-\n 2 files changed, 42 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/config.c b/builtin/config.c\nindex 33c8820..dc890d5 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -171,8 +171,20 @@ static int get_value(const char *key_, const char *regex_)\n \tif (!local) {\n \t\tconst char *home = getenv(\"HOME\");\n \t\tlocal = repo_config = git_pathdup(\"config\");\n-\t\tif (home)\n-\t\t\tglobal = xstrdup(mkpath(\"%s/.gitconfig\", home));\n+\t\tif (home) {\n+\t\t\tchar gitconfig_path[PATH_MAX], config_path[PATH_MAX];\n+\t\t\tFILE *gitconfig_file, *config_file;\n+\n+\t\t\tsprintf(gitconfig_path, \"%s/.gitconfig\", home);\n+\t\t\tsprintf(config_path, \"%s/.config/git/config\", home);\n+\t\t\tgitconfig_file = fopen(gitconfig_path, \"r\");\n+\t\t\tconfig_file = fopen(config_path, \"r\");\n+\n+\t\t\tif (gitconfig_file==NULL && config_file!=NULL)\n+\t\t\t\tglobal = xstrdup(mkpath(\"%s/.config/git/config\", home));\n+\t\t\telse\n+\t\t\t\tglobal = xstrdup(mkpath(\"%s/.gitconfig\", home));\n+\t\t}\n \t\tif (git_config_system())\n \t\t\tsystem_wide = git_etc_gitconfig();\n \t}\n@@ -381,7 +393,20 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \tif (use_global_config) {\n \t\tchar *home = getenv(\"HOME\");\n \t\tif (home) {\n-\t\t\tchar *user_config = xstrdup(mkpath(\"%s/.gitconfig\", home));\n+\t\t\tchar gitconfig_path[PATH_MAX], config_path[PATH_MAX];\n+\t\t\tFILE *gitconfig_file, *config_file;\n+\t\t\tchar *user_config;\n+\n+\t\t\tsprintf(gitconfig_path, \"%s/.gitconfig\", home);\n+\t\t\tsprintf(config_path, \"%s/.config/git/config\", home);\n+\t\t\tgitconfig_file = fopen(gitconfig_path, \"r\");\n+\t\t\tconfig_file = fopen(config_path, \"r\");\n+\n+\t\t\tif (gitconfig_file==NULL && config_file!=NULL)\n+\t\t\t\tuser_config = xstrdup(mkpath(\"%s/.config/git/config\", home));\n+\t\t\telse\n+\t\t\t\tuser_config = xstrdup(mkpath(\"%s/.gitconfig\", home));\n+\n \t\t\tgiven_config_file = user_config;\n \t\t} else {\n \t\t\tdie(\"$HOME not set\");\ndiff --git a/config.c b/config.c\nindex eeee986..998dbbc 100644\n--- a/config.c\n+++ b/config.c\n@@ -962,7 +962,20 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)\n \thome = getenv(\"HOME\");\n \tif (home) {\n \t\tchar buf[PATH_MAX];\n-\t\tchar *user_config = mksnpath(buf, sizeof(buf), \"%s/.gitconfig\", home);\n+\t\tchar gitconfig_path[PATH_MAX], config_path[PATH_MAX];\n+\t\tFILE *gitconfig_file, *config_file;\n+\t\tchar *user_config;\n+\n+\t\tsprintf(gitconfig_path, \"%s/.gitconfig\", home);\n+\t\tsprintf(config_path, \"%s/.config/git/config\", home);\n+\t\tgitconfig_file = fopen(gitconfig_path, \"r\");\n+\t\tconfig_file = fopen(config_path, \"r\");\n+\n+\t\tif (gitconfig_file==NULL && config_file!=NULL)\n+\t\t\tuser_config = mksnpath(buf, sizeof(buf), \"%s/.config/git/config\", home);\n+\t\telse\n+\t\t\tuser_config = mksnpath(buf, sizeof(buf), \"%s/.gitconfig\", home);\n+\n \t\tif (!access(user_config, R_OK)) {\n \t\t\tret += git_config_from_file(fn, user_config, data);\n \t\t\tfound += 1;\n-- \n1.7.0.4\n"},{"id":"192201","messageId":"1337975239-17169-2-git-send-email-nguyenhu@ensibm.imag.fr","threadId":"30622","inReplyTo":"1337975239-17169-1-git-send-email-nguyenhu@ensibm.imag.fr","subject":"[PATCH 2/2] Test File Name: t1306-second-config-file.sh","fromName":"NGUYEN Huynh Khoi Nguyen","fromEmail":"nguyenhu@ensimag.imag.fr","sentAt":"2012-05-25T19:47:19Z","receivedAt":"2012-05-25T19:47:19Z","isPatch":true,"sender":{"key":"nguyenhu@ensimag.imag.fr","avatar":null},"body":"There are 4 tests:\ntest1 and test2: read tests\ntest1: ~/.config/git/config exists and ~/.gitconfig doesn't\ngit reads ~/.config/git/config\ntest2: ~/.config/git/config exists and ~/.gitconfig exists\ngit reads ~/.gitconfig\ntest3 and test4: write tests\ntest3: ~/.config/git/config exists and ~/.gitconfig doesn't\ngit writes in ~/.config/git/config\ntest4: ~/.config/git/config exists and ~/.gitconfig exists\ngit writes in ~/.gitconfig\n---\n t/t1306-second-config-file.sh |   47 +++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 47 insertions(+), 0 deletions(-)\n create mode 100755 t/t1306-second-config-file.sh\n\ndiff --git a/t/t1306-second-config-file.sh b/t/t1306-second-config-file.sh\nnew file mode 100755\nindex 0000000..5406456\n--- /dev/null\n+++ b/t/t1306-second-config-file.sh\n@@ -0,0 +1,47 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='~/.config/git/config instead of ~/.gitconfig'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'read: ~/.config/git/config exists and ~/.gitconfig doesn'\\''t' '\n+\tmkdir .config &&\n+\tmkdir .config/git &&\n+\techo \"[user]\" >.config/git/config &&\n+\techo \"\tname = read_config\" >>.config/git/config &&\n+\techo read_config >expect &&\n+\tgit config --global --get user.name >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success 'read: ~/.config/git/config exists and ~/.gitconfig exists' '\n+\t>.gitconfig &&\n+\techo \"[user]\" >.gitconfig &&\n+\techo \"\tname = read_gitconfig\" >>.gitconfig &&\n+\techo read_gitconfig >expect &&\n+\tgit config --global --get user.name >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success 'write: ~/.config/git/config exists and ~/.gitconfig doesn'\\''t' '\n+\trm .gitconfig &&\n+\tgit config --global user.name \"write_config\" &&\n+\techo \"[user]\" >expect &&\n+\techo \"\tname = write_config\" >>expect &&\n+\ttest_cmp expect .config/git/config\n+'\n+\n+test_expect_success 'write: ~/.config/git/config exists and ~/.gitconfig exists' '\n+\t>.gitconfig &&\n+\tgit config --global user.name \"write_gitconfig\" &&\n+\techo \"[user]\" >expect &&\n+\techo \"\tname = write_gitconfig\" >>expect &&\n+\ttest_cmp expect .gitconfig\n+'\n+\n+test_done\n-- \n1.7.0.4\n"},{"id":"192206","messageId":"20120525203056.GC4364@sigill.intra.peff.net","threadId":"30622","inReplyTo":"1337975239-17169-1-git-send-email-nguyenhu@ensibm.imag.fr","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-25T20:30:56Z","receivedAt":"2012-05-25T20:30:56Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, May 25, 2012 at 09:47:18PM +0200, NGUYEN Huynh Khoi Nguyen wrote:\n\n> git will store its configuration in ~/.config/git/config file if this file\n> exists and ~/.gitconfig file doesn't, otherwise git store its configuration\n> in ~/.gitconfig as usual\n\nWhat about reading? For maximum compatibility, we should always read\nfrom _both_ of them, and choose between them only when writing, no? It\nlooks like your patch will only read from one or the other.\n\nAt first people will have only one or the other, but people using\nmultiple versions of git, or people following already-written\ninstructions on the web about modifying ~/.gitconfig could end up with\nboth.\n\n> --- a/builtin/config.c\n> +++ b/builtin/config.c\n> @@ -171,8 +171,20 @@ static int get_value(const char *key_, const char *regex_)\n>  \tif (!local) {\n>  \t\tconst char *home = getenv(\"HOME\");\n>  \t\tlocal = repo_config = git_pathdup(\"config\");\n> -\t\tif (home)\n> -\t\t\tglobal = xstrdup(mkpath(\"%s/.gitconfig\", home));\n> +\t\tif (home) {\n> +\t\t\tchar gitconfig_path[PATH_MAX], config_path[PATH_MAX];\n> +\t\t\tFILE *gitconfig_file, *config_file;\n> +\n> +\t\t\tsprintf(gitconfig_path, \"%s/.gitconfig\", home);\n> +\t\t\tsprintf(config_path, \"%s/.config/git/config\", home);\n\nThese are both exploitable buffer overflows. Why not use mkpath?\n\n> +\t\t\tgitconfig_file = fopen(gitconfig_path, \"r\");\n> +\t\t\tconfig_file = fopen(config_path, \"r\");\n\nSo we open both files. It looks like in an attempt to see if they are\nreadable. But:\n\n  1. No need to go to that much work. You can just call access(R_OK).\n\n  2. You never close the files, so you are leaking memory and file\n     descriptors.\n\n> +\t\t\tif (gitconfig_file==NULL && config_file!=NULL)\n\nStyle. We put whitespace around comparison operators, and we usually\ndon't refer to NULL specifically, like:\n\n  if (!gitconfig_file && config_file)\n\n\nSo a simpler way to write this section would be something like:\n\n  if (home) {\n          const char *path = mkpath(\"%s/.config/git/config\", home);\n\n          if (!access(path, R_OK))\n                  global = xstrdup(path);\n          else\n                  global = xstrdup(mkpath(\"%s/.gitconfig\", home));\n  }\n\nBut like I said earlier, I think this should really be reading from\n_both_, which is a different change altogether.\n\nI won't go through the other two hunks individually, but my comments are\nsimilar.\n\n-Peff\n"},{"id":"192210","messageId":"7vd35sq7fx.fsf@alter.siamese.dyndns.org","threadId":"30622","inReplyTo":"20120525203056.GC4364@sigill.intra.peff.net","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-25T21:25:38Z","receivedAt":"2012-05-25T21:25:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Fri, May 25, 2012 at 09:47:18PM +0200, NGUYEN Huynh Khoi Nguyen wrote:\n>\n>> git will store its configuration in ~/.config/git/config file if this file\n>> exists and ~/.gitconfig file doesn't, otherwise git store its configuration\n>> in ~/.gitconfig as usual\n>\n> What about reading? For maximum compatibility, we should always read\n> from _both_ of them, and choose between them only when writing, no? It\n> looks like your patch will only read from one or the other.\n>\n> At first people will have only one or the other, but people using\n> multiple versions of git, or people following already-written\n> instructions on the web about modifying ~/.gitconfig could end up with\n> both.\n\nIsn't it actually much worse than that?\n\nIf you read from .gitconfig and also from the new location, but update\nonly the new location, people who use two versions of git will be in a\nvery confusing situation.  Randomly, some of their updates are always in\neffect, and others only appear sometimes, and after wasting a lot of time\nand hair scratching their heads, they will realize that writing with old\nversions of Git will store values to a place visible to both versions,\nwhile writing with new versions will store values to a place visible only\nto new versions.\n\nI'd rather see it ignore the new location as long as ~/.gitconfig exists\n(and if only the new location exists, read from and write to it), and have\nusers make a conscious decision to transition.  That is:\n\n - If ~/.gitconfig exists, do not do anything new.  Just exercise the\n   original code.  For these users, ~/.config/ does _not_ exist as far as\n   Git is concerned.\n\n - (optional) If ~/.gitconfig exists, offer _moving_ it to the new\n   location after telling the user to make sure that the user will never\n   use older version of git again, and move it if the user agrees.\n\n - Otherwise, read from and write to the new location.\n"},{"id":"192211","messageId":"CAH-tXsC6Z21YunJwb5oYQfcmC3LMeRpNtwdLvS_P5tuB8WY=Kg@mail.gmail.com","threadId":"30622","inReplyTo":"1337975239-17169-1-git-send-email-nguyenhu@ensibm.imag.fr","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"jaseem abid","fromEmail":"jaseemabid@gmail.com","sentAt":"2012-05-25T21:26:49Z","receivedAt":"2012-05-25T21:26:49Z","isPatch":true,"sender":{"key":"jaseemabid@gmail.com","avatar":"https://gravatar.com/avatar/8b0432c96e4d3c8a9a96c9961ee842df7b7a869744da9c25187a51a992eabd81?d=mp&s=160"},"body":"On Sat, May 26, 2012 at 1:17 AM, NGUYEN Huynh Khoi Nguyen\n<nguyenhu@ensimag.imag.fr> wrote:\n> git will store its configuration in ~/.config/git/config file if this file\n> exists and ~/.gitconfig file doesn't, otherwise git store its configuration\n> in ~/.gitconfig as usual\n\n\nIf a new config file gets introduced at `~/.config/git/config`, what\nwill be the new order of config file precedence?\n\n`/etc/gitconfig` > `~/.gitconfig` > `~/.config/git/config`  > `.git/config` or\n`/etc/gitconfig` >  `~/.config/git/config` > `~/.gitconfig` > `.git/config` ?\n\nWhat will be the new flag to access it? I mean anything new like\n--system / --global going to be introduced?\n\n-- \nJaseem Abid\nhttp://jaseemabid.github.com\n"},{"id":"192212","messageId":"20120525214406.GA10064@sigill.intra.peff.net","threadId":"30622","inReplyTo":"7vd35sq7fx.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-25T21:44:07Z","receivedAt":"2012-05-25T21:44:07Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, May 25, 2012 at 02:25:38PM -0700, Junio C Hamano wrote:\n\n> > At first people will have only one or the other, but people using\n> > multiple versions of git, or people following already-written\n> > instructions on the web about modifying ~/.gitconfig could end up with\n> > both.\n> \n> Isn't it actually much worse than that?\n> \n> If you read from .gitconfig and also from the new location, but update\n> only the new location, people who use two versions of git will be in a\n> very confusing situation.  Randomly, some of their updates are always in\n> effect, and others only appear sometimes, and after wasting a lot of time\n> and hair scratching their heads, they will realize that writing with old\n> versions of Git will store values to a place visible to both versions,\n> while writing with new versions will store values to a place visible only\n> to new versions.\n\nThat's true, but...\n\n> I'd rather see it ignore the new location as long as ~/.gitconfig exists\n> (and if only the new location exists, read from and write to it), and have\n> users make a conscious decision to transition.  That is:\n> \n>  - If ~/.gitconfig exists, do not do anything new.  Just exercise the\n>    original code.  For these users, ~/.config/ does _not_ exist as far as\n>    Git is concerned.\n> \n>  - (optional) If ~/.gitconfig exists, offer _moving_ it to the new\n>    location after telling the user to make sure that the user will never\n>    use older version of git again, and move it if the user agrees.\n> \n>  - Otherwise, read from and write to the new location.\n\nThat doesn't solve all problems with multiple versions, though. For\nexample, this sequence:\n\n  1. User consciously moves to new location, moving ~/.gitconfig to\n     ~/.config/git/config (or perhaps they do not do so consciously, but\n     do not have a ~/.gitconfig at all, and run \"git config --global\"\n     with the new version.\n\n  2. User runs \"git config --global\" with an old version of git, which\n     writes to ~/.gitconfig.\n\nAfter step 1, old versions of git will not respect the user's config at\nall. This is unavoidable; the old version does not know about the new\nlocation.\n\nBut after step 2, _all_ versions of git have stopped respecting the new\nlocation (because ~/.gitconfig takes precedence). Whereas if we read\nfrom everywhere, then it is broken only in older versions (which are\nbroken anyway).\n\nSo I consider it the lesser of two evils. The rule is much simpler: \"old\nversions of git do not know about this new location\". Which is\nunavoidable, and easier to explain than \"Old versions of git do not know\nabout this location. New versions do, but will sometimes ignore\ndepending on whether this other file exists, which might have been\ncreated by an old version\".\n\nHowever, let's take a step back for a minute. I think the real issue is\nwriting to the XDG location without the user knowing about it. So a\nbetter transition plan would be:\n\n  1. Start reading from the XDG location in addition to the old\n     location. Always write to the old location.\n\n  2. Wait N time units until everybody reasonable has a version that\n     does (1).\n\n  3. Start writing to the XDG location by default. Keep reading from the\n     old version for compatibility.\n\nPeople who want to start using the new location after step 1 are free to\ndo so; they just shouldn't expect git to write to it, and they should\naccept the obvious caveat that older versions of git will not understand\nit. An optional addendum is that we could start writing to the XDG\nlocation after step 1 only if it exists, which implies that the user has\ndecided it's OK to do so (which is still a guess; they might have wanted\nto split their config intentionally).\n\n-Peff\n"},{"id":"192225","messageId":"vpq62bjnx14.fsf@bauges.imag.fr","threadId":"30622","inReplyTo":"1337975239-17169-1-git-send-email-nguyenhu@ensibm.imag.fr","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-26T08:53:27Z","receivedAt":"2012-05-26T08:53:27Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"NGUYEN Huynh Khoi Nguyen <nguyenhu@ensimag.imag.fr> writes:\n\n> +\t\t\tsprintf(config_path, \"%s/.config/git/config\", home);\n\nIt's not terribly important, but if we are to use something that looks\nlike XDG, I'd rather have a real support for it. ~/.config/ is the\ndefault, but the spec\nhttp://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html\nalso define $XDG_CONFIG_HOME that may override the default and we may\nwant to support $XDG_CONFIG_DIRS too.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192226","messageId":"vpqtxz3mhx8.fsf@bauges.imag.fr","threadId":"30622","inReplyTo":"7vd35sq7fx.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-26T09:05:07Z","receivedAt":"2012-05-26T09:05:07Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> If you read from .gitconfig and also from the new location, but update\n> only the new location,\n\nThat's not exactly the proposal. First, I agree that the first questions\nto be answered is what happens on reading. About writing, I don't feel\nvery strongly about it, but I think it's reasonable to write to the new\nlocation if the old location doesn't exist, and the new one does. This\nway, ~/.gitconfig haters will create their ~/.config/git/config, and\nwon't be bothered with the former.\n\nObviously, trying too hard to write to the new location would harm old\nversions users, so for example, it would be unreasonable to write to the\nnew location unconditionally.\n\n> people who use two versions of git will be in a very confusing\n> situation. Randomly, some of their updates are always in effect,\n\nOnly if they created manually the new file. People unaware of the change\nwon't be affected at all.\n\nSince most people don't read the docs, most people will be\nunaffected ;-).\n\n>  - If ~/.gitconfig exists, do not do anything new.  Just exercise the\n>    original code.  For these users, ~/.config/ does _not_ exist as far as\n>    Git is concerned.\n\nAs Jeff already pointed out, this would be very confusing for a user\nhaving the new file, since running once \"git config --global\" with an\nold version would shadow the whole configuration by creating an almost\nempty ~/.gitconfig file.\n\nWe clearly want to read both. I'm not sure which should take precedence\nwhen the same variable is defined in both.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192231","messageId":"CACsJy8BD_=6PtQeuDGEt2mee9tMWZB1hL2obu2f2KUmAENTEzA@mail.gmail.com","threadId":"30622","inReplyTo":"20120525214406.GA10064@sigill.intra.peff.net","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-05-26T10:15:13Z","receivedAt":"2012-05-26T10:15:13Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, May 26, 2012 at 4:44 AM, Jeff King <peff@peff.net> wrote:\n>> I'd rather see it ignore the new location as long as ~/.gitconfig exists\n>> (and if only the new location exists, read from and write to it), and have\n>> users make a conscious decision to transition.  That is:\n>>\n>>  - If ~/.gitconfig exists, do not do anything new.  Just exercise the\n>>    original code.  For these users, ~/.config/ does _not_ exist as far as\n>>    Git is concerned.\n>>\n>>  - (optional) If ~/.gitconfig exists, offer _moving_ it to the new\n>>    location after telling the user to make sure that the user will never\n>>    use older version of git again, and move it if the user agrees.\n>>\n>>  - Otherwise, read from and write to the new location.\n>\n> That doesn't solve all problems with multiple versions, though. For\n> example, this sequence:\n>\n>  1. User consciously moves to new location, moving ~/.gitconfig to\n>     ~/.config/git/config (or perhaps they do not do so consciously, but\n>     do not have a ~/.gitconfig at all, and run \"git config --global\"\n>     with the new version.\n>\n>  2. User runs \"git config --global\" with an old version of git, which\n>     writes to ~/.gitconfig.\n>\n> After step 1, old versions of git will not respect the user's config at\n> all. This is unavoidable; the old version does not know about the new\n> location.\n>\n> But after step 2, _all_ versions of git have stopped respecting the new\n> location (because ~/.gitconfig takes precedence). Whereas if we read\n> from everywhere, then it is broken only in older versions (which are\n> broken anyway).\n>\n> So I consider it the lesser of two evils. The rule is much simpler: \"old\n> versions of git do not know about this new location\". Which is\n> unavoidable, and easier to explain than \"Old versions of git do not know\n> about this location. New versions do, but will sometimes ignore\n> depending on whether this other file exists, which might have been\n> created by an old version\".\n\nWe could amend Junio's version a bit:\n\n - if both versions exist, warn loudly (optionally refuse to work) and\nsuggest to symlink .gitconfig to .config/git/config\n\n\n> However, let's take a step back for a minute. I think the real issue is\n> writing to the XDG location without the user knowing about it. So a\n> better transition plan would be:\n>\n>  1. Start reading from the XDG location in addition to the old\n>     location. Always write to the old location.\n>\n>  2. Wait N time units until everybody reasonable has a version that\n>     does (1).\n>\n>  3. Start writing to the XDG location by default. Keep reading from the\n>     old version for compatibility.\n\nHang on.. this \"by default\" is only for Linux, or for every other OS too?\n\n\n> People who want to start using the new location after step 1 are free to\n> do so; they just shouldn't expect git to write to it, and they should\n> accept the obvious caveat that older versions of git will not understand\n> it. An optional addendum is that we could start writing to the XDG\n> location after step 1 only if it exists, which implies that the user has\n> decided it's OK to do so (which is still a guess; they might have wanted\n> to split their config intentionally).\n-- \nDuy\n"},{"id":"192251","messageId":"20120526214904.GB29463@sigill.intra.peff.net","threadId":"30622","inReplyTo":"vpq62bjnx14.fsf@bauges.imag.fr","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-26T21:49:04Z","receivedAt":"2012-05-26T21:49:04Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, May 26, 2012 at 10:53:27AM +0200, Matthieu Moy wrote:\n\n> NGUYEN Huynh Khoi Nguyen <nguyenhu@ensimag.imag.fr> writes:\n> \n> > +\t\t\tsprintf(config_path, \"%s/.config/git/config\", home);\n> \n> It's not terribly important, but if we are to use something that looks\n> like XDG, I'd rather have a real support for it. ~/.config/ is the\n> default, but the spec\n> http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html\n> also define $XDG_CONFIG_HOME that may override the default and we may\n> want to support $XDG_CONFIG_DIRS too.\n\nI agree. This series is much less appealing as \"put the config in some\nother place\" and much more appealing as \"conform to an existing standard\nabout dot-file locations\". And if we are going to follow the standard,\nthen we should do all parts of it.\n\n-Peff\n"},{"id":"192252","messageId":"20120526215405.GC29463@sigill.intra.peff.net","threadId":"30622","inReplyTo":"CACsJy8BD_=6PtQeuDGEt2mee9tMWZB1hL2obu2f2KUmAENTEzA@mail.gmail.com","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-26T21:54:05Z","receivedAt":"2012-05-26T21:54:05Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, May 26, 2012 at 05:15:13PM +0700, Nguyen Thai Ngoc Duy wrote:\n\n> > So I consider it the lesser of two evils. The rule is much simpler: \"old\n> > versions of git do not know about this new location\". Which is\n> > unavoidable, and easier to explain than \"Old versions of git do not know\n> > about this location. New versions do, but will sometimes ignore\n> > depending on whether this other file exists, which might have been\n> > created by an old version\".\n> \n> We could amend Junio's version a bit:\n> \n>  - if both versions exist, warn loudly (optionally refuse to work) and\n> suggest to symlink .gitconfig to .config/git/config\n\nYeah, that might help. At the same time, it is not necessarily an error\ncondition (e.g., if I track my ~/.config directory, but want to put\none-offs in ~/.gitconfig. On the other hand, you can set that up\nmanually with include.path = ~/.some-not-tracked-file, so maybe it is\nnot a use case worth worrying about).\n\n> >  1. Start reading from the XDG location in addition to the old\n> >     location. Always write to the old location.\n> >\n> >  2. Wait N time units until everybody reasonable has a version that\n> >     does (1).\n> >\n> >  3. Start writing to the XDG location by default. Keep reading from the\n> >     old version for compatibility.\n> \n> Hang on.. this \"by default\" is only for Linux, or for every other OS too?\n\nSorry, I overstated a bit. It would be _safe_ to do step 3 like that\nafter waiting N time units, but we could also do something much less\ndrastic (like only writing to it when it exists, or when ~/.gitconfig\ndoes not exist, or whatever). And no, I wouldn't think following XDG on\nnon-Linux machines would make much sense if no other programs on that\nplatform do so (I don't know what OS X is like, but I can imagine nobody\nuses XDG paths on Windows).\n\n-Peff\n"},{"id":"192399","messageId":"CAJDDKr63QET=Dn4hV1Q-=xGJ3p1up5ohDsDGcuyrPC43Jvohug@mail.gmail.com","threadId":"30622","inReplyTo":"20120526215405.GC29463@sigill.intra.peff.net","subject":"Re: [PATCH 1/2] Add possibility to store configuration in ~/.config/git/config file","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2012-05-28T21:05:39Z","receivedAt":"2012-05-28T21:05:39Z","isPatch":true,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"On Sat, May 26, 2012 at 2:54 PM, Jeff King <peff@peff.net> wrote:\n> On Sat, May 26, 2012 at 05:15:13PM +0700, Nguyen Thai Ngoc Duy wrote:\n>\n>> > So I consider it the lesser of two evils. The rule is much simpler: \"old\n>> > versions of git do not know about this new location\". Which is\n>> > unavoidable, and easier to explain than \"Old versions of git do not know\n>> > about this location. New versions do, but will sometimes ignore\n>> > depending on whether this other file exists, which might have been\n>> > created by an old version\".\n>>\n>> We could amend Junio's version a bit:\n>>\n>>  - if both versions exist, warn loudly (optionally refuse to work) and\n>> suggest to symlink .gitconfig to .config/git/config\n>\n> Yeah, that might help. At the same time, it is not necessarily an error\n> condition (e.g., if I track my ~/.config directory, but want to put\n> one-offs in ~/.gitconfig. On the other hand, you can set that up\n> manually with include.path = ~/.some-not-tracked-file, so maybe it is\n> not a use case worth worrying about).\n>\n>> >  1. Start reading from the XDG location in addition to the old\n>> >     location. Always write to the old location.\n>> >\n>> >  2. Wait N time units until everybody reasonable has a version that\n>> >     does (1).\n>> >\n>> >  3. Start writing to the XDG location by default. Keep reading from the\n>> >     old version for compatibility.\n>>\n>> Hang on.. this \"by default\" is only for Linux, or for every other OS too?\n>\n> Sorry, I overstated a bit. It would be _safe_ to do step 3 like that\n> after waiting N time units, but we could also do something much less\n> drastic (like only writing to it when it exists, or when ~/.gitconfig\n> does not exist, or whatever). And no, I wouldn't think following XDG on\n> non-Linux machines would make much sense if no other programs on that\n> platform do so (I don't know what OS X is like, but I can imagine nobody\n> uses XDG paths on Windows).\n\nI completely disagree about the OS X thing.  We have shared home\ndirectories across OS X and Linux.  There are many OS X apps that do\nrespect XDG because they use Qt.  Git configuration is core to the\nsystem; I think we should avoid fragmentation.\n\nReal-word scenario: At disney animation studio (and probably pixar\ntoo) OS X is (thankfully) a 2nd-class citizen to Linux.  We would very\nmuch appreciate the ability to have the OS X git behave exactly like\nthe Linux version, even if that means a Makefile switch.  IMO it\nshould do so by default, though; there's little to gain otherwise.\n\nI would even suggest that windows should do the same.  .dotfiles are\nnot a regular windows thing in the first place.  It's the simplest and\neasiest-to-explain thing to do, too.  Otherwise it means more\nplatform-specific documentation.  Less documentation is better\ndocumentation (especially since no one reads it ;p)\n\nSo I think having OS X git follow XDG makes a lot of sense.  I don't\nknow of any alternatives short of adding something like an OS\nX-specific System Preferences pane or some insane OS X `defaults`\n.plist-integrated thing ;-)\n-- \nDavid\n"}]}