{"thread":{"id":"14159","subject":"[Bug?] git submodule add doesn't respect core.autocrlf","startedAt":"2008-06-26T05:43:48Z","lastAt":"2008-06-26T11:58:20Z","messageCount":3,"participants":["Edward Z. Yang","Lars Hjemli","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"81237","messageId":"g3vaaq$pm1$1@ger.gmane.org","threadId":"14159","inReplyTo":null,"subject":"[Bug?] git submodule add doesn't respect core.autocrlf","fromName":"Edward Z. Yang","fromEmail":"edwardzyang@thewritingpot.com","sentAt":"2008-06-26T05:43:48Z","receivedAt":"2008-06-26T05:43:48Z","isPatch":false,"sender":{"key":"edwardzyang@thewritingpot.com","avatar":"https://gravatar.com/avatar/a805a0a3c1d7d36e7fe22270596e4d812723652933c59cac267e67c79126fdd0?d=mp&s=160"},"body":"It doesn't appear that git-submodule add respects crlf, as evidenced by \nthis set of commands on Windows:\n\nmkdir test\ncd test\ngit init\ngit config core.safecrlf true\ngit config core.autocrlf true\ngit submodule add http://repo.or.cz/w/htmlpurifier.git htmlpurifier\n\nYou get: \"fatal: LF would be replaced by CRLF in .gitmodules\" and \ninspecting .gitmodules reveals that it uses LF, instead of CRLF.\n\nCan anyone reproduce? Thanks.\n"},{"id":"81255","messageId":"8c5c35580806260140g3133817ele6683d56699a9199@mail.gmail.com","threadId":"14159","inReplyTo":"g3vaaq$pm1$1@ger.gmane.org","subject":"Re: [Bug?] git submodule add doesn't respect core.autocrlf","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2008-06-26T08:40:16Z","receivedAt":"2008-06-26T08:40:16Z","isPatch":false,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On Thu, Jun 26, 2008 at 7:43 AM, Edward Z. Yang\n<edwardzyang@thewritingpot.com> wrote:\n> mkdir test\n> cd test\n> git init\n> git config core.safecrlf true\n> git config core.autocrlf true\n\nYou can work around the problem by issuing the following commands at this point:\n\necho \".gitattributes -crlf\" >> .gitattributes\necho \".gitmodules -crlf\" >> .gitattributes\ngit add .gitattributes\n\n> git submodule add http://repo.or.cz/w/htmlpurifier.git htmlpurifier\n>\n> You get: \"fatal: LF would be replaced by CRLF in .gitmodules\" and inspecting .gitmodules reveals that it uses LF, instead of CRLF.\n>\n> Can anyone reproduce? Thanks.\n\nYes, this also fails on linux (without the workaround).\n\nTo fix it \"properly\", git-config needs to choose between lf and crlf\n(git-submodule uses git-config to write .gitmodules). But this depends\non\n* whether the 'configfile' is (or will be!) tracked by git (e.g. .gitmodules)\n* whether a crlf-attribute is specified for the 'configfile'\n* the setting of core.autocrlf\n\nA simpler solution might be to treat .gitmodules specially in\ncheck_safe_crlf(), maybe something like this (possibly wrapped by\ngmail...):\n\ndiff --git a/convert.c b/convert.c\nindex 1c66844..254a99b 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -91,6 +91,15 @@ static void check_safe_crlf(const char *path, int action,\n        if (!checksafe)\n                return;\n\n+       /* Dirty hack: git-submodule uses git-config to update .gitmodules, and\n+        * there's no reasonable way for git-config to know if the user prefers\n+        * crlf or lf line endings for this file. And since it really doesn't\n+        * matter, lets just ignore that the line endings might be modified by\n+        * a later checkout.\n+        */\n+       if (!strcmp(path, \".gitmodules\"))\n+               return;\n+\n        if (action == CRLF_INPUT || auto_crlf <= 0) {\n                /*\n                 * CRLFs would not be restored by checkout:\n\n--\nlarsh\n"},{"id":"81278","messageId":"alpine.DEB.1.00.0806261257460.9925@racer","threadId":"14159","inReplyTo":"g3vaaq$pm1$1@ger.gmane.org","subject":"[TEASER PATCH] write .gitmodules according to core.autocrlf","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-06-26T11:58:20Z","receivedAt":"2008-06-26T11:58:20Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nThis patch introduces the option \"--crlf=<bool>\" to git-config, which\ntells git-config to write with or without CR/LF line endings.  (Empty\nmeans 'false'.)\n\nThis option is then used by git-submodule to write .gitmodules with\nthe correct line-endings according to core.autocrlf.\n\nNOTE: this patch is _not_ meant for inclusion, but as a starting point.\nI have _no_ desire to continue working on this topic.  It is just a\nproof of concept, and it is _your_ responsibility to get it into\nsubmittable form.\n\nThis would involve:\n\n\t- giving the option a better name (--crlf does not imply that\n\t  it is only for writing),\n\n\t- move the declaration of the config_endl variable to somewhere\n\t  more public, such as cache.h,\n\n\t- possibly even move the definition of config_endl to\n\t  environment.c,\n\n\t- split the patch into the config-related and the\n\t  submodule-related part,\n\n\t- add documentation both for the config-related as well as for\n\t  the submodule-related part,\n\n\t- add tests,\n\n\t- submit it, and be quick to fix whatever is criticized on the\n\t  Git mailing list.\n\nIf you do that, would be nice to give me some credit, too.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin-config.c |    5 +++++\n config.c         |   14 +++++++++-----\n git-submodule.sh |   15 ++++++++++-----\n 3 files changed, 24 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin-config.c b/builtin-config.c\nindex 3a441ef..6ab191f 100644\n--- a/builtin-config.c\n+++ b/builtin-config.c\n@@ -17,6 +17,7 @@ static char delim = '=';\n static char key_delim = ' ';\n static char term = '\\n';\n static enum { T_RAW, T_INT, T_BOOL, T_BOOL_OR_INT } type = T_RAW;\n+extern const char *config_endl;\n \n static int show_all_config(const char *key_, const char *value_, void *cb)\n {\n@@ -334,6 +335,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \t\t\tdelim = '\\n';\n \t\t\tkey_delim = '\\n';\n \t\t}\n+\t\telse if (!prefixcmp(argv[1], \"--crlf=\"))\n+\t\t\tconfig_endl = argv[1][7] &&\n+\t\t\t\tgit_config_bool(\"crlf\", argv[1] + 7) ?\n+\t\t\t\t\"\\r\\n\" : \"\\n\";\n \t\telse if (!strcmp(argv[1], \"--rename-section\")) {\n \t\t\tint ret;\n \t\t\tif (argc != 4)\ndiff --git a/config.c b/config.c\nindex 58749bf..da9213e 100644\n--- a/config.c\n+++ b/config.c\n@@ -15,6 +15,7 @@ static const char *config_file_name;\n static int config_linenr;\n static int config_file_eof;\n static int zlib_compression_seen;\n+const char *config_endl = \"\\n\";\n \n static int get_next_char(void)\n {\n@@ -749,9 +750,10 @@ static int store_write_section(int fd, const char* key)\n \t\t\t\tstrbuf_addch(&sb, '\\\\');\n \t\t\tstrbuf_addch(&sb, key[i]);\n \t\t}\n-\t\tstrbuf_addstr(&sb, \"\\\"]\\n\");\n+\t\tstrbuf_addstr(&sb, \"\\\"]\");\n+\t\tstrbuf_addstr(&sb, config_endl);\n \t} else {\n-\t\tstrbuf_addf(&sb, \"[%.*s]\\n\", store.baselen, key);\n+\t\tstrbuf_addf(&sb, \"[%.*s]%s\", store.baselen, key, config_endl);\n \t}\n \n \tsuccess = write_in_full(fd, sb.buf, sb.len) == sb.len;\n@@ -789,7 +791,7 @@ static int store_write_pair(int fd, const char* key, const char* value)\n \tfor (i = 0; value[i]; i++)\n \t\tswitch (value[i]) {\n \t\tcase '\\n':\n-\t\t\tstrbuf_addstr(&sb, \"\\\\n\");\n+\t\t\tstrbuf_addstr(&sb, config_endl);\n \t\t\tbreak;\n \t\tcase '\\t':\n \t\t\tstrbuf_addstr(&sb, \"\\\\t\");\n@@ -801,7 +803,7 @@ static int store_write_pair(int fd, const char* key, const char* value)\n \t\t\tstrbuf_addch(&sb, value[i]);\n \t\t\tbreak;\n \t\t}\n-\tstrbuf_addf(&sb, \"%s\\n\", quote);\n+\tstrbuf_addf(&sb, \"%s%s\", quote, config_endl);\n \n \tsuccess = write_in_full(fd, sb.buf, sb.len) == sb.len;\n \tstrbuf_release(&sb);\n@@ -1047,7 +1049,9 @@ int git_config_set_multivar(const char* key, const char* value,\n \t\t\t\t    copy_end - copy_begin)\n \t\t\t\t\tgoto write_err_out;\n \t\t\t\tif (new_line &&\n-\t\t\t\t    write_in_full(fd, \"\\n\", 1) != 1)\n+\t\t\t\t    write_in_full(fd, config_endl,\n+\t\t\t\t\t    strlen(config_endl)) !=\n+\t\t\t\t    strlen(config_endl))\n \t\t\t\t\tgoto write_err_out;\n \t\t\t}\n \t\t\tcopy_begin = store.offset[i];\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 3eb78cc..c551c74 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -27,6 +27,11 @@ say()\n \tfi\n }\n \n+gitmodules_config ()\n+{\n+\tgit config -f .gitmodules --crlf=$(git config --bool core.autocrlf) \"$@\"\n+}\n+\n # NEEDSWORK: identical function exists in get_repo_base in clone.sh\n get_repo_base() {\n \t(\n@@ -74,8 +79,8 @@ module_name()\n {\n \t# Do we have \"submodule.<something>.path = $1\" defined in .gitmodules file?\n \tre=$(printf '%s\\n' \"$1\" | sed -e 's/[].[^$\\\\*]/\\\\&/g')\n-\tname=$( git config -f .gitmodules --get-regexp '^submodule\\..*\\.path$' |\n-\t\tsed -n -e 's|^submodule\\.\\(.*\\)\\.path '\"$re\"'$|\\1|p' )\n+\tname=$(gitmodules_config '^submodule\\..*\\.path$' |\n+\t\tsed -n -e 's|^submodule\\.\\(.*\\)\\.path '\"$re\"'$|\\1|p')\n        test -z \"$name\" &&\n        die \"No submodule mapping found in .gitmodules for path '$path'\"\n        echo \"$name\"\n@@ -198,8 +203,8 @@ cmd_add()\n \tgit add \"$path\" ||\n \tdie \"Failed to add submodule '$path'\"\n \n-\tgit config -f .gitmodules submodule.\"$path\".path \"$path\" &&\n-\tgit config -f .gitmodules submodule.\"$path\".url \"$repo\" &&\n+\tgitmodules_config submodule.\"$path\".path \"$path\" &&\n+\tgitmodules_config submodule.\"$path\".url \"$repo\" &&\n \tgit add .gitmodules ||\n \tdie \"Failed to register submodule '$path'\"\n }\n@@ -240,7 +245,7 @@ cmd_init()\n \t\turl=$(git config submodule.\"$name\".url)\n \t\ttest -z \"$url\" || continue\n \n-\t\turl=$(git config -f .gitmodules submodule.\"$name\".url)\n+\t\turl=$(gitmodules_config submodule.\"$name\".url)\n \t\ttest -z \"$url\" &&\n \t\tdie \"No url found for submodule path '$path' in .gitmodules\"\n \n-- \n1.5.6.173.gde14c\n"}]}