{"thread":{"id":"26006","subject":"[RFC/WIP 0/3] Shared config","startedAt":"2010-12-09T15:09:45Z","lastAt":"2010-12-10T01:53:23Z","messageCount":11,"participants":["Nguyễn Thái Ngọc Duy","Thiago Farina","Jonathan Nieder","Junio C Hamano","Nguyen Thai Ngoc Duy"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"157691","messageId":"1291907388-9068-1-git-send-email-pclouds@gmail.com","threadId":"26006","inReplyTo":null,"subject":"[RFC/WIP 0/3] Shared config","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-12-09T15:09:45Z","receivedAt":"2010-12-09T15:09:45Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Another approach is [1]. I think this one is somewhat simpler and\nexposes less risk by putting the shared config under version control.\n\nThis is not complete (for example, git-prune should learn about this),\nbut is there any serious flaw that I missed?\n\nOne thing that I haven't thought of is the shared config between\nsubprojects. Maybe there's a better approach for subprojects.\n\n(The resistance to nd/struct-pathspec seems great. This is the second\ntime I come to address it and end up with something else)\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/162309\n\nNguyễn Thái Ngọc Duy (3):\n  config: read full file content before parsing\n  config: add git_config_from_sha1() to read from a blob\n  config: add core.sharedconfig\n\n cache.h       |    1 +\n config.c      |  110 +++++++++++++++++++++++++++++++++++++++++++--------------\n environment.c |    1 +\n 3 files changed, 85 insertions(+), 27 deletions(-)\n\n-- \n1.7.3.3.476.g893a9\n"},{"id":"157692","messageId":"1291907388-9068-2-git-send-email-pclouds@gmail.com","threadId":"26006","inReplyTo":"1291907388-9068-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 1/3] config: read full file content before parsing","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-12-09T15:09:46Z","receivedAt":"2010-12-09T15:09:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"config files are usually short enough that we can read in full. This\nallows the parser to parse in-memory config, for example from a blob.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n config.c |   62 +++++++++++++++++++++++++++++++++++---------------------------\n 1 files changed, 35 insertions(+), 27 deletions(-)\n\ndiff --git a/config.c b/config.c\nindex f138c34..c8bf46f 100644\n--- a/config.c\n+++ b/config.c\n@@ -12,7 +12,8 @@\n \n #define MAXNAME (256)\n \n-static FILE *config_file;\n+static char *config_file;\n+static size_t config_file_size, config_file_pos;\n static const char *config_file_name;\n static int config_linenr;\n static int config_file_eof;\n@@ -108,28 +109,26 @@ int git_config_parse_environment(void) {\n \n static int get_next_char(void)\n {\n-\tint c;\n-\tFILE *f;\n+\tsize_t unread = config_file_size - config_file_pos;\n+\n+\tif (config_file == NULL)\n+\t\treturn '\\n';\n \n-\tc = '\\n';\n-\tif ((f = config_file) != NULL) {\n-\t\tc = fgetc(f);\n+\tif (unread) {\n+\t\tchar c = config_file[config_file_pos++];\n \t\tif (c == '\\r') {\n \t\t\t/* DOS like systems */\n-\t\t\tc = fgetc(f);\n-\t\t\tif (c != '\\n') {\n-\t\t\t\tungetc(c, f);\n-\t\t\t\tc = '\\r';\n-\t\t\t}\n+\t\t\tif (unread > 1 &&\n+\t\t\t    config_file[config_file_pos] == '\\n')\n+\t\t\t\tc = config_file[config_file_pos++];\n \t\t}\n \t\tif (c == '\\n')\n \t\t\tconfig_linenr++;\n-\t\tif (c == EOF) {\n-\t\t\tconfig_file_eof = 1;\n-\t\t\tc = '\\n';\n-\t\t}\n+\t\treturn c;\n \t}\n-\treturn c;\n+\n+\tconfig_file_eof = 1;\n+\treturn '\\n';\n }\n \n static char *parse_value(void)\n@@ -786,19 +785,27 @@ int git_default_config(const char *var, const char *value, void *dummy)\n \n int git_config_from_file(config_fn_t fn, const char *filename, void *data)\n {\n-\tint ret;\n-\tFILE *f = fopen(filename, \"r\");\n+\tstruct stat st;\n+\tint ret = -1, fd;\n+\n+\tif (lstat(filename, &st))\n+\t\treturn -1;\n+\tfd = open(filename, O_RDONLY);\n+\tif (fd == -1)\n+\t\treturn -1;\n \n-\tret = -1;\n-\tif (f) {\n-\t\tconfig_file = f;\n+\tconfig_file = xmalloc(st.st_size);\n+\tif (read_in_full(fd, config_file, st.st_size) == st.st_size) {\n+\t\tconfig_file_pos = 0;\n+\t\tconfig_file_size = st.st_size;\n \t\tconfig_file_name = filename;\n \t\tconfig_linenr = 1;\n \t\tconfig_file_eof = 0;\n \t\tret = git_parse_file(fn, data);\n-\t\tfclose(f);\n-\t\tconfig_file_name = NULL;\n \t}\n+\tclose(fd);\n+\tfree(config_file);\n+\tconfig_file_name = NULL;\n \treturn ret;\n }\n \n@@ -921,7 +928,7 @@ static int store_aux(const char *key, const char *value, void *cb)\n \t\t\t\treturn 1;\n \t\t\t}\n \n-\t\t\tstore.offset[store.seen] = ftell(config_file);\n+\t\t\tstore.offset[store.seen] = config_file_pos;\n \t\t\tstore.seen++;\n \t\t}\n \t\tbreak;\n@@ -948,19 +955,19 @@ static int store_aux(const char *key, const char *value, void *cb)\n \t\t * Do not increment matches: this is no match, but we\n \t\t * just made sure we are in the desired section.\n \t\t */\n-\t\tstore.offset[store.seen] = ftell(config_file);\n+\t\tstore.offset[store.seen] = config_file_pos;\n \t\t/* fallthru */\n \tcase SECTION_END_SEEN:\n \tcase START:\n \t\tif (matches(key, value)) {\n-\t\t\tstore.offset[store.seen] = ftell(config_file);\n+\t\t\tstore.offset[store.seen] = config_file_pos;\n \t\t\tstore.state = KEY_SEEN;\n \t\t\tstore.seen++;\n \t\t} else {\n \t\t\tif (strrchr(key, '.') - key == store.baselen &&\n \t\t\t      !strncmp(key, store.key, store.baselen)) {\n \t\t\t\t\tstore.state = SECTION_SEEN;\n-\t\t\t\t\tstore.offset[store.seen] = ftell(config_file);\n+\t\t\t\t\tstore.offset[store.seen] = config_file_pos;\n \t\t\t}\n \t\t}\n \t}\n@@ -1380,6 +1387,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)\n {\n \tint ret = 0, remove = 0;\n \tchar *config_filename;\n+\tFILE *config_file;\n \tstruct lock_file *lock = xcalloc(sizeof(struct lock_file), 1);\n \tint out_fd;\n \tchar buf[1024];\n-- \n1.7.3.3.476.g893a9\n"},{"id":"157693","messageId":"1291907388-9068-3-git-send-email-pclouds@gmail.com","threadId":"26006","inReplyTo":"1291907388-9068-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 2/3] config: add git_config_from_sha1() to read from a blob","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-12-09T15:09:47Z","receivedAt":"2010-12-09T15:09:47Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n config.c |   34 ++++++++++++++++++++++++++++++++++\n 1 files changed, 34 insertions(+), 0 deletions(-)\n\ndiff --git a/config.c b/config.c\nindex c8bf46f..e7a9ff4 100644\n--- a/config.c\n+++ b/config.c\n@@ -809,6 +809,40 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)\n \treturn ret;\n }\n \n+static int git_config_from_sha1(config_fn_t fn, const char *sha1_name, void *data)\n+{\n+\tunsigned char sha1[20];\n+\tenum object_type type;\n+\tunsigned long size;\n+\tint ret;\n+\n+\tif (get_sha1(sha1_name, sha1)) {\n+\t\terror(\"bad shared config reference '%s'\", sha1_name);\n+\t\treturn -1;\n+\t}\n+\n+\tconfig_file = read_sha1_file(sha1, &type, &size);\n+\tif (!config_file) {\n+\t\terror(\"bad shared config '%s'\", sha1_name);\n+\t\treturn -1;\n+\t}\n+\tif (type == OBJ_BLOB) {\n+\t\tconfig_file_pos = 0;\n+\t\tconfig_file_size = size;\n+\t\tconfig_file_name = sha1_name;\n+\t\tconfig_linenr = 1;\n+\t\tconfig_file_eof = 0;\n+\t\tret = git_parse_file(fn, data);\n+\t}\n+\telse {\n+\t\terror(\"shared config '%s' is not a blob\", sha1_name);\n+\t\treturn -1;\n+\t}\n+\tfree(config_file);\n+\tconfig_file_name = NULL;\n+\treturn ret;\n+}\n+\n const char *git_etc_gitconfig(void)\n {\n \tstatic const char *system_wide;\n-- \n1.7.3.3.476.g893a9\n"},{"id":"157694","messageId":"1291907388-9068-4-git-send-email-pclouds@gmail.com","threadId":"26006","inReplyTo":"1291907388-9068-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 3/3] config: add core.sharedconfig","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-12-09T15:09:48Z","receivedAt":"2010-12-09T15:09:48Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"core.sharedconfig can take anything that resolves to a blob.\n$GIT_DIR/config will override the shared config. Nested shared\nconfig is not allowed.\n\nNo protection is provided. It's up to the project to maintain good\nconfig. The config could be in a separate branch that only a few\npeople are allowed to push, for example. To be safest, just put SHA-1\nthere.\n\ngit-fsck and git-prune should learn about this key and protect it from\nbeing pruned.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Hopefully nobody sets core.sharedconfig = :path/to/config or similar\n\n And I should not open $GIT_DIR/config twice. Well, it does not hurt\n much.\n\n cache.h       |    1 +\n config.c      |   14 ++++++++++++++\n environment.c |    1 +\n 3 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex e83bc2d..e91ce35 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -559,6 +559,7 @@ extern int read_replace_refs;\n extern int fsync_object_files;\n extern int core_preload_index;\n extern int core_apply_sparse_checkout;\n+extern const char *core_shared_config;\n \n enum safe_crlf {\n \tSAFE_CRLF_FALSE = 0,\ndiff --git a/config.c b/config.c\nindex e7a9ff4..735b3f4 100644\n--- a/config.c\n+++ b/config.c\n@@ -883,6 +883,14 @@ int git_config_from_parameters(config_fn_t fn, void *data)\n \treturn 0;\n }\n \n+static int get_shared_config(const char *var, const char *value, void *dummy)\n+{\n+\tif (!strcmp(var, \"core.sharedconfig\"))\n+\t\treturn git_config_string(&core_shared_config, var, value);\n+\n+\treturn 0;\n+}\n+\n int git_config(config_fn_t fn, void *data)\n {\n \tint ret = 0, found = 0;\n@@ -910,6 +918,12 @@ int git_config(config_fn_t fn, void *data)\n \n \trepo_config = git_pathdup(\"config\");\n \tif (!access(repo_config, R_OK)) {\n+\t\tgit_config_from_file(get_shared_config, repo_config, NULL);\n+\t\tif (core_shared_config) {\n+\t\t\tret += git_config_from_sha1(fn, core_shared_config, data);\n+\t\t\tfound += 1;\n+\t\t}\n+\n \t\tret += git_config_from_file(fn, repo_config, data);\n \t\tfound += 1;\n \t}\ndiff --git a/environment.c b/environment.c\nindex 913b058..8bfb548 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -55,6 +55,7 @@ enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;\n char *notes_ref_name;\n int grafts_replace_parents = 1;\n int core_apply_sparse_checkout;\n+const char *core_shared_config;\n struct startup_info *startup_info;\n \n /* Parallel index stat data preload? */\n-- \n1.7.3.3.476.g893a9\n"},{"id":"157696","messageId":"AANLkTi=qt-uwXdUquRAv_1VpMUQuUR+aNMuxSHdpMhXd@mail.gmail.com","threadId":"26006","inReplyTo":"1291907388-9068-3-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 2/3] config: add git_config_from_sha1() to read from a blob","fromName":"Thiago Farina","fromEmail":"tfransosi@gmail.com","sentAt":"2010-12-09T15:58:28Z","receivedAt":"2010-12-09T15:58:28Z","isPatch":true,"sender":{"key":"tfransosi@gmail.com","avatar":"https://avatars.githubusercontent.com/u/970071?v=4"},"body":"2010/12/9 Nguyễn Thái Ngọc Duy <pclouds@gmail.com>:\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  config.c |   34 ++++++++++++++++++++++++++++++++++\n>  1 files changed, 34 insertions(+), 0 deletions(-)\n>\n> diff --git a/config.c b/config.c\n> index c8bf46f..e7a9ff4 100644\n> --- a/config.c\n> +++ b/config.c\n> @@ -809,6 +809,40 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)\n>        return ret;\n>  }\n>\n\n> +static int git_config_from_sha1(config_fn_t fn, const char *sha1_name, void *data)\n> +{\n\nIs worth documenting the return value of this function and what it\ndoes? It returns 0 on success otherwise returns -1.\n\n> +       unsigned char sha1[20];\n> +       enum object_type type;\n> +       unsigned long size;\n> +       int ret;\n> +\n> +       if (get_sha1(sha1_name, sha1)) {\n> +               error(\"bad shared config reference '%s'\", sha1_name);\n> +               return -1;\n> +       }\n> +\n> +       config_file = read_sha1_file(sha1, &type, &size);\n> +       if (!config_file) {\n> +               error(\"bad shared config '%s'\", sha1_name);\n> +               return -1;\n> +       }\n> +       if (type == OBJ_BLOB) {\n> +               config_file_pos = 0;\n> +               config_file_size = size;\n> +               config_file_name = sha1_name;\n> +               config_linenr = 1;\n> +               config_file_eof = 0;\n> +               ret = git_parse_file(fn, data);\n> +       }\n> +       else {\n\nstyle nit: Shouldn't this else be on the end of the previous line?\n"},{"id":"157697","messageId":"AANLkTinVw+H1OsdJVofiGMkpNAdOjS5n0-HZCGCg3f5g@mail.gmail.com","threadId":"26006","inReplyTo":"1291907388-9068-4-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 3/3] config: add core.sharedconfig","fromName":"Thiago Farina","fromEmail":"tfransosi@gmail.com","sentAt":"2010-12-09T16:00:54Z","receivedAt":"2010-12-09T16:00:54Z","isPatch":true,"sender":{"key":"tfransosi@gmail.com","avatar":"https://avatars.githubusercontent.com/u/970071?v=4"},"body":"2010/12/9 Nguyễn Thái Ngọc Duy <pclouds@gmail.com>:\n> core.sharedconfig can take anything that resolves to a blob.\n> $GIT_DIR/config will override the shared config. Nested shared\n> config is not allowed.\n>\n> No protection is provided. It's up to the project to maintain good\n> config. The config could be in a separate branch that only a few\n> people are allowed to push, for example. To be safest, just put SHA-1\n> there.\n>\n> git-fsck and git-prune should learn about this key and protect it from\n> being pruned.\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  Hopefully nobody sets core.sharedconfig = :path/to/config or similar\n>\n>  And I should not open $GIT_DIR/config twice. Well, it does not hurt\n>  much.\n>\n>  cache.h       |    1 +\n>  config.c      |   14 ++++++++++++++\n>  environment.c |    1 +\n>  3 files changed, 16 insertions(+), 0 deletions(-)\n>\n> diff --git a/cache.h b/cache.h\n> index e83bc2d..e91ce35 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -559,6 +559,7 @@ extern int read_replace_refs;\n>  extern int fsync_object_files;\n>  extern int core_preload_index;\n>  extern int core_apply_sparse_checkout;\n> +extern const char *core_shared_config;\n>\n\nWhy you need to export this string? Isn't it used only in config.c?\n"},{"id":"157700","messageId":"20101209170228.GC5974@burratino","threadId":"26006","inReplyTo":"AANLkTi=qt-uwXdUquRAv_1VpMUQuUR+aNMuxSHdpMhXd@mail.gmail.com","subject":"Re: [PATCH 2/3] config: add git_config_from_sha1() to read from a blob","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-09T17:02:28Z","receivedAt":"2010-12-09T17:02:28Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Thiago Farina wrote:\n> 2010/12/9 Nguyễn Thái Ngọc Duy <pclouds@gmail.com>:\n\n>> +static int git_config_from_sha1(config_fn_t fn, const char *sha1_name, void *data)\n>> +{\n>\n> Is worth documenting the return value of this function and what it\n> does? It returns 0 on success otherwise returns -1.\n\nIf that is the return value, then no.  It is the usual in git (and\nother C programs that follow libc conventions).\n"},{"id":"157707","messageId":"7vwrnig6gr.fsf@alter.siamese.dyndns.org","threadId":"26006","inReplyTo":"1291907388-9068-4-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 3/3] config: add core.sharedconfig","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-12-09T18:13:24Z","receivedAt":"2010-12-09T18:13:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> core.sharedconfig can take anything that resolves to a blob.\n> $GIT_DIR/config will override the shared config. Nested shared\n> config is not allowed.\n>\n> No protection is provided. It's up to the project to maintain good\n> config. The config could be in a separate branch that only a few\n> people are allowed to push, for example. To be safest, just put SHA-1\n> there.\n>\n> git-fsck and git-prune should learn about this key and protect it from\n> being pruned.\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  Hopefully nobody sets core.sharedconfig = :path/to/config or similar\n>\n>  And I should not open $GIT_DIR/config twice. Well, it does not hurt\n>  much.\n\nThat kind of sloppy thinking adds up, though.\n\n> @@ -910,6 +918,12 @@ int git_config(config_fn_t fn, void *data)\n>  \n>  \trepo_config = git_pathdup(\"config\");\n>  \tif (!access(repo_config, R_OK)) {\n> +\t\tgit_config_from_file(get_shared_config, repo_config, NULL);\n> +\t\tif (core_shared_config) {\n> +\t\t\tret += git_config_from_sha1(fn, core_shared_config, data);\n> +\t\t\tfound += 1;\n> +\t\t}\n> +\n\nWhat is the point of this \"found++\" when you will increment it for finding\nthe repository-local configuration anyway?\n\n>  \t\tret += git_config_from_file(fn, repo_config, data);\n>  \t\tfound += 1;\n>  \t}\n\nI originally liked what the first two tried to do, but think about the use\ncase.  How would this whole thing work?\n\n - The user clones from the project to get a repository with a working\n   tree;\n\n - The user somehow learns that s/he can run one command to get\n   project-wide preference of the project:\n\n     $ git config core.sharedconfig refs/remotes/origin/config:git.config\n\n - Everything hopefully should work the way project wishes in that blob,\n   unless the end user later overrides them by adding different settings\n   to .git/config.\n\nHow is that different from:\n\n - The user clones from the project to get a repository with a working\n   tree;\n\n - The user somehow learns that s/he can run one command to get\n   project-wide preference of the project:\n\n     $ ./setup-project-preference.sh\n\n   Typically, such a ./setup-project-preference.sh script would only\n   consist of a series of \"git config $foo $bar\", so any user who can say\n   \"git config core.sharedconfig $foo\" should be able to use it as well.\n\n - Everything should work the way project wishes with the settings made to\n   .git/config by the script, unless the end user later overrides them by\n   modifying settings in .git/config.\n\nOne minor difference is that some configuration variables are additive,\nand you cannot subtract from them with your approach.\n"},{"id":"157709","messageId":"20101209181924.GD5974@burratino","threadId":"26006","inReplyTo":"7vwrnig6gr.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 3/3] config: add core.sharedconfig","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-12-09T18:19:24Z","receivedAt":"2010-12-09T18:19:24Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n\n> I originally liked what the first two tried to do, but think about the use\n> case.  How would this whole thing work?\n> \n>  - The user clones from the project to get a repository with a working\n>    tree;\n> \n>  - The user somehow learns that s/he can run one command to get\n>    project-wide preference of the project:\n> \n>      $ git config core.sharedconfig refs/remotes/origin/config:git.config\n> \n>  - Everything hopefully should work the way project wishes in that blob,\n>    unless the end user later overrides them by adding different settings\n>    to .git/config.\n> \n> How is that different from:\n> \n>  - The user clones from the project to get a repository with a working\n>    tree;\n> \n>  - The user somehow learns that s/he can run one command to get\n>    project-wide preference of the project:\n> \n>      $ ./setup-project-preference.sh\n> \n>    Typically, such a ./setup-project-preference.sh script would only\n>    consist of a series of \"git config $foo $bar\", so any user who can say\n>    \"git config core.sharedconfig $foo\" should be able to use it as well.\n\nWouldn't this ./setup-project-preference.sh have to set up a post-fetch hook\nto update the configuration when the project's preferences change?\n"},{"id":"157781","messageId":"AANLkTikAwvsb_rLc45ZTuTHEqYV78dAZCdgw-1f+D1+B@mail.gmail.com","threadId":"26006","inReplyTo":"7vwrnig6gr.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 3/3] config: add core.sharedconfig","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-12-10T01:29:55Z","receivedAt":"2010-12-10T01:29:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2010/12/10 Junio C Hamano <gitster@pobox.com>:\n>> @@ -910,6 +918,12 @@ int git_config(config_fn_t fn, void *data)\n>>\n>>       repo_config = git_pathdup(\"config\");\n>>       if (!access(repo_config, R_OK)) {\n>> +             git_config_from_file(get_shared_config, repo_config, NULL);\n>> +             if (core_shared_config) {\n>> +                     ret += git_config_from_sha1(fn, core_shared_config, data);\n>> +                     found += 1;\n>> +             }\n>> +\n>\n> What is the point of this \"found++\" when you will increment it for finding\n> the repository-local configuration anyway?\n\nIt seems that every time a config source is used, found++. So I\nincrease it because there's is another source used, a blob.\n\n> I originally liked what the first two tried to do, but think about the use\n> case.  How would this whole thing work?\n>\n>  - The user clones from the project to get a repository with a working\n>   tree;\n>\n>  - The user somehow learns that s/he can run one command to get\n>   project-wide preference of the project:\n>\n>     $ git config core.sharedconfig refs/remotes/origin/config:git.config\n>\n>  - Everything hopefully should work the way project wishes in that blob,\n>   unless the end user later overrides them by adding different settings\n>   to .git/config.\n>\n> How is that different from:\n>\n>  - The user clones from the project to get a repository with a working\n>   tree;\n>\n>  - The user somehow learns that s/he can run one command to get\n>   project-wide preference of the project:\n>\n>     $ ./setup-project-preference.sh\n>\n>   Typically, such a ./setup-project-preference.sh script would only\n>   consist of a series of \"git config $foo $bar\", so any user who can say\n>   \"git config core.sharedconfig $foo\" should be able to use it as well.\n>\n>  - Everything should work the way project wishes with the settings made to\n>   .git/config by the script, unless the end user later overrides them by\n>   modifying settings in .git/config.\n\nThe shared config can be updated automatically (after fetching, of\ncourse). Remote setup for a small team, for example, can benefit from\nthis. Every time a new member joins, somebody adds new remote to the\nshared config and pushes out. Everybody else will have it.\n\n> One minor difference is that some configuration variables are additive,\n> and you cannot subtract from them with your approach.\n\nYou can't subtract some keys from $HOME/.gitconfig by modifying\n$GIT_DIR/config either. I mean, that could be addressed in a general\nway, not specific to shared config.\n-- \nDuy\n"},{"id":"157786","messageId":"AANLkTikqW5Z2YQw7Yjy6jERpsdFXSO06W=MSi8iyKDkx@mail.gmail.com","threadId":"26006","inReplyTo":"AANLkTinVw+H1OsdJVofiGMkpNAdOjS5n0-HZCGCg3f5g@mail.gmail.com","subject":"Re: [PATCH 3/3] config: add core.sharedconfig","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-12-10T01:53:23Z","receivedAt":"2010-12-10T01:53:23Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2010/12/9 Thiago Farina <tfransosi@gmail.com>:\n>> diff --git a/cache.h b/cache.h\n>> index e83bc2d..e91ce35 100644\n>> --- a/cache.h\n>> +++ b/cache.h\n>> @@ -559,6 +559,7 @@ extern int read_replace_refs;\n>>  extern int fsync_object_files;\n>>  extern int core_preload_index;\n>>  extern int core_apply_sparse_checkout;\n>> +extern const char *core_shared_config;\n>>\n>\n> Why you need to export this string? Isn't it used only in config.c?\n>\n\ngit-prune should know about this but I haven't got that far.\n-- \nDuy\n"}]}