{"thread":{"id":"64012","subject":"[PATCH] config: add \"hostname\" condition to includeIf","startedAt":"2025-08-22T08:49:17Z","lastAt":"2025-08-27T20:54:50Z","messageCount":3,"participants":["monarch","Ayush Sharma","Eric Sunshine"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"524705","messageId":"20250822084910.98308-1-ayushoffinfo17@gmail.com","threadId":"64012","inReplyTo":null,"subject":"[PATCH] config: add \"hostname\" condition to includeIf","fromName":"monarch","fromEmail":"ayushoffinfo17@gmail.com","sentAt":"2025-08-22T08:49:09Z","receivedAt":"2025-08-22T08:49:17Z","isPatch":true,"sender":{"key":"ayushoffinfo17@gmail.com","avatar":null},"body":"Teach \"includeIf\" to include configuration based on the machine's hostname,\nas returned by gethostname(2).\n\nExample:\n\n    [includeIf \"hostname:work-laptop\"]\n        path = ~/.gitconfig.work\n\n    [includeIf \"hostname:home-pc\"]\n        path = ~/.gitconfig.home\n\nThis allows users to write host-specific configuration without separate branches.\n\nSigned-off-by: monarch <ayushoffinfo17@gmail.com>\n---\n config.c | 37 +++++++++++++++++++++++++++++++------\n 1 file changed, 31 insertions(+), 6 deletions(-)\n\ndiff --git a/config.c b/config.c\nindex e0ff35d426..dbc1a2bc75 100644\n--- a/config.c\n+++ b/config.c\n@@ -7,6 +7,7 @@\n  */\n \n #include \"git-compat-util.h\"\n+#include <unistd.h>\n #include \"abspath.h\"\n #include \"date.h\"\n #include \"branch.h\"\n@@ -391,23 +392,47 @@ static int include_by_remote_url(struct config_include_data *inc,\n \t\t\t\t\t     inc->remote_urls);\n }\n \n+static int include_by_hostname(const char *cond, size_t cond_len)\n+{\n+    char actual_hostname[1024];\n+    struct strbuf target_hostname = STRBUF_INIT;\n+    int ret = 0;\n+\n+    // Make sure the call to gethostname is correct and its return value is checked.\n+    if (gethostname(actual_hostname, sizeof(actual_hostname)) != 0)\n+        return 0; // If it fails, the condition is false.\n+\n+    strbuf_add(&target_hostname, cond, cond_len);\n+\n+    // The core of the logic: strcmp returns 0 when strings are equal.\n+    if (strcmp(actual_hostname, target_hostname.buf) == 0)\n+        ret = 1; // Success, the hostnames match!\n+\n+    strbuf_release(&target_hostname);\n+    return ret;\n+}\n+\n static int include_condition_is_true(const struct key_value_info *kvi,\n-\t\t\t\t     struct config_include_data *inc,\n-\t\t\t\t     const char *cond, size_t cond_len)\n+\tstruct config_include_data *inc,\n+\tconst char *cond, size_t cond_len)\n {\n-\tconst struct config_options *opts = inc->opts;\n+const struct config_options *opts = inc->opts;\n+\n+\n \n \tif (skip_prefix_mem(cond, cond_len, \"gitdir:\", &cond, &cond_len))\n \t\treturn include_by_gitdir(kvi, opts, cond, cond_len, 0);\n \telse if (skip_prefix_mem(cond, cond_len, \"gitdir/i:\", &cond, &cond_len))\n \t\treturn include_by_gitdir(kvi, opts, cond, cond_len, 1);\n-\telse if (skip_prefix_mem(cond, cond_len, \"onbranch:\", &cond, &cond_len))\n+\telse if (skip_prefix_mem(cond, cond_len, \"onbranch:\", &cond, cond_len))\n \t\treturn include_by_branch(inc, cond, cond_len);\n \telse if (skip_prefix_mem(cond, cond_len, \"hasconfig:remote.*.url:\", &cond,\n-\t\t\t\t   &cond_len))\n+  &cond_len))\n \t\treturn include_by_remote_url(inc, cond, cond_len);\n+\telse if (skip_prefix_mem(cond, cond_len, \"hostname:\", &cond, &cond_len))\n+\t\treturn include_by_hostname(cond, cond_len);\n \n-\t/* unknown conditionals are always false */\n+/* unknown conditionals are always false */\n \treturn 0;\n }\n \n-- \n2.43.0\n\n"},{"id":"525037","messageId":"CABV7AFFLF6SJEk92Kr9x9z2sOk5nZ7Q0gx=GKR+-JNxSkju=RA@mail.gmail.com","threadId":"64012","inReplyTo":"20250822084910.98308-1-ayushoffinfo17@gmail.com","subject":"Re: [PATCH] config: add \"hostname\" condition to includeIf","fromName":"Ayush Sharma","fromEmail":"ayushoffinfo17@gmail.com","sentAt":"2025-08-27T19:23:36Z","receivedAt":"2025-08-27T13:53:48Z","isPatch":true,"sender":{"key":"ayushoffinfo17@gmail.com","avatar":null},"body":"Hi,\n\nJust a gentle ping to see if there is any feedback on this patch.\n\nThanks,\nAyush Sharma\n\n\nOn Fri, Aug 22, 2025 at 2:19 PM monarch <ayushoffinfo17@gmail.com> wrote:\n>\n> Teach \"includeIf\" to include configuration based on the machine's hostname,\n> as returned by gethostname(2).\n>\n> Example:\n>\n>     [includeIf \"hostname:work-laptop\"]\n>         path = ~/.gitconfig.work\n>\n>     [includeIf \"hostname:home-pc\"]\n>         path = ~/.gitconfig.home\n>\n> This allows users to write host-specific configuration without separate branches.\n>\n> Signed-off-by: monarch <ayushoffinfo17@gmail.com>\n> ---\n>  config.c | 37 +++++++++++++++++++++++++++++++------\n>  1 file changed, 31 insertions(+), 6 deletions(-)\n>\n> diff --git a/config.c b/config.c\n> index e0ff35d426..dbc1a2bc75 100644\n> --- a/config.c\n> +++ b/config.c\n> @@ -7,6 +7,7 @@\n>   */\n>\n>  #include \"git-compat-util.h\"\n> +#include <unistd.h>\n>  #include \"abspath.h\"\n>  #include \"date.h\"\n>  #include \"branch.h\"\n> @@ -391,23 +392,47 @@ static int include_by_remote_url(struct config_include_data *inc,\n>                                              inc->remote_urls);\n>  }\n>\n> +static int include_by_hostname(const char *cond, size_t cond_len)\n> +{\n> +    char actual_hostname[1024];\n> +    struct strbuf target_hostname = STRBUF_INIT;\n> +    int ret = 0;\n> +\n> +    // Make sure the call to gethostname is correct and its return value is checked.\n> +    if (gethostname(actual_hostname, sizeof(actual_hostname)) != 0)\n> +        return 0; // If it fails, the condition is false.\n> +\n> +    strbuf_add(&target_hostname, cond, cond_len);\n> +\n> +    // The core of the logic: strcmp returns 0 when strings are equal.\n> +    if (strcmp(actual_hostname, target_hostname.buf) == 0)\n> +        ret = 1; // Success, the hostnames match!\n> +\n> +    strbuf_release(&target_hostname);\n> +    return ret;\n> +}\n> +\n>  static int include_condition_is_true(const struct key_value_info *kvi,\n> -                                    struct config_include_data *inc,\n> -                                    const char *cond, size_t cond_len)\n> +       struct config_include_data *inc,\n> +       const char *cond, size_t cond_len)\n>  {\n> -       const struct config_options *opts = inc->opts;\n> +const struct config_options *opts = inc->opts;\n> +\n> +\n>\n>         if (skip_prefix_mem(cond, cond_len, \"gitdir:\", &cond, &cond_len))\n>                 return include_by_gitdir(kvi, opts, cond, cond_len, 0);\n>         else if (skip_prefix_mem(cond, cond_len, \"gitdir/i:\", &cond, &cond_len))\n>                 return include_by_gitdir(kvi, opts, cond, cond_len, 1);\n> -       else if (skip_prefix_mem(cond, cond_len, \"onbranch:\", &cond, &cond_len))\n> +       else if (skip_prefix_mem(cond, cond_len, \"onbranch:\", &cond, cond_len))\n>                 return include_by_branch(inc, cond, cond_len);\n>         else if (skip_prefix_mem(cond, cond_len, \"hasconfig:remote.*.url:\", &cond,\n> -                                  &cond_len))\n> +  &cond_len))\n>                 return include_by_remote_url(inc, cond, cond_len);\n> +       else if (skip_prefix_mem(cond, cond_len, \"hostname:\", &cond, &cond_len))\n> +               return include_by_hostname(cond, cond_len);\n>\n> -       /* unknown conditionals are always false */\n> +/* unknown conditionals are always false */\n>         return 0;\n>  }\n>\n> --\n> 2.43.0\n>\n"},{"id":"525075","messageId":"CAPig+cQ8whwjyuLkUgnxrr4U2F9zm3vitL3gwopniTNXRUqtHA@mail.gmail.com","threadId":"64012","inReplyTo":"CABV7AFFLF6SJEk92Kr9x9z2sOk5nZ7Q0gx=GKR+-JNxSkju=RA@mail.gmail.com","subject":"Re: [PATCH] config: add \"hostname\" condition to includeIf","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2025-08-27T20:54:38Z","receivedAt":"2025-08-27T20:54:50Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Aug 27, 2025 at 9:53 AM Ayush Sharma <ayushoffinfo17@gmail.com> wrote:\n> On Fri, Aug 22, 2025 at 2:19 PM monarch <ayushoffinfo17@gmail.com> wrote:\n> > Teach \"includeIf\" to include configuration based on the machine's hostname,\n> > as returned by gethostname(2).\n> >\n> > Example:\n> >     [includeIf \"hostname:work-laptop\"]\n> >         path = ~/.gitconfig.work\n> >     [includeIf \"hostname:home-pc\"]\n> >         path = ~/.gitconfig.home\n> >\n> > This allows users to write host-specific configuration without separate branches.\n> >\n> > Signed-off-by: monarch <ayushoffinfo17@gmail.com>\n> > ---\n> > +static int include_by_hostname(const char *cond, size_t cond_len)\n> > +{\n> > +    char actual_hostname[1024];\n> > +    struct strbuf target_hostname = STRBUF_INIT;\n> > +    int ret = 0;\n> > +\n> > +    // Make sure the call to gethostname is correct and its return value is checked.\n> > +    if (gethostname(actual_hostname, sizeof(actual_hostname)) != 0)\n> > +        return 0; // If it fails, the condition is false.\n> > +\n> > +    strbuf_add(&target_hostname, cond, cond_len);\n> > +\n> > +    // The core of the logic: strcmp returns 0 when strings are equal.\n> > +    if (strcmp(actual_hostname, target_hostname.buf) == 0)\n> > +        ret = 1; // Success, the hostnames match!\n> > +\n> > +    strbuf_release(&target_hostname);\n> > +    return ret;\n> > +}\n>\n> Just a gentle ping to see if there is any feedback on this patch.\n\nYou can increase the likelihood of feedback by:\n\n* Studying the related email thread pointed out by Junio in his\nresponse[1] to your initial inquiry, and taking all the open\ndiscussion points into consideration and providing answers for them in\nyour proposed submission. (For instance, one of the open discussion\npoints[2] was how a user would know the exact hostname to use with\n`includeIf [hostname \"...\"]`; a solution needs to be provided in order\nto move forward with the proposal.)\n\n* Including with your patch the necessary documentation update (so\nusers will be able to discover this new capability), as well as new\ntests.\n\n* Studying Documentation/CodingGuidelines (for instance, this project\nuses `/*...*/` comments, not `//`), and\nDocumentation/SubmittingPatches (for instance, avoid changes, such as\ninserting unnecessary blank lines or arbitrarily reformatting code,\nunrelated to the purpose of your patch; use your proper name in the\nSigned-off-by: footer).\n\n* Consult the Git source code to see whether there is a better way to\nobtain the hostname than rolling your own (for instance, don't fall\nprey to gethostname() potentially omitting the terminating NUL from\nthe buffer; instead use xgethostname() from Git's wrapper.c).\n\n[1]: https://lore.kernel.org/git/xmqqqzx8k258.fsf@gitster.g/\n[2]: https://lore.kernel.org/git/CAPig+cT4fpX7Kczu0+H5TZnmpVqqq0h8nBafj4UqDs7Xv2Nf4A@mail.gmail.com/\n"}]}