{"thread":{"id":"64011","subject":"[PATCH] config: add \"hostname\" condition to includeIf","startedAt":"2025-08-22T08:35:34Z","lastAt":"2025-08-22T08:35:34Z","messageCount":1,"participants":["monarch"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"524704","messageId":"20250822083505.96187-1-ayushoffinfo17@gmail.com","threadId":"64011","inReplyTo":null,"subject":"[PATCH] config: add \"hostname\" condition to includeIf","fromName":"monarch","fromEmail":"ayusharmagsoccontri@gmail.com","sentAt":"2025-08-22T08:35:05Z","receivedAt":"2025-08-22T08:35:34Z","isPatch":true,"sender":{"key":"ayusharmagsoccontri@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"}]}