There is no reason for $GIT_DIR/config to be executable, plus there used to be a bug (fixed by the previous commit) that caused "git init" to set the u+x bit on that file. So whenever rewriting the config file, take the opportunity to remove any executable bits that the file might have. Signed-off-by: Michael Haggerty <mhagger@xxxxxxxxxxxx> --- builtin/config.c | 21 ++++++++++++++++++--- config.c | 12 ++++++++++-- t/t1300-repo-config.sh | 13 +++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/builtin/config.c b/builtin/config.c index 7bba516..1a7c17e 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -551,6 +551,9 @@ int cmd_config(int argc, const char **argv, const char *prefix) } } else if (actions == ACTION_EDIT) { + char *config_file; + struct stat st; + check_argc(argc, 0, 0); if (!given_config_source.file && nongit) die("not in a git directory"); @@ -559,9 +562,21 @@ int cmd_config(int argc, const char **argv, const char *prefix) if (given_config_source.blob) die("editing blobs is not supported"); git_config(git_default_config, NULL); - launch_editor(given_config_source.file ? - given_config_source.file : git_path("config"), - NULL, NULL); + config_file = xstrdup(given_config_source.file ? + given_config_source.file : git_path("config")); + launch_editor(config_file, NULL, NULL); + + /* + * In git 2.1, there was a bug in "git init" that left + * the u+x bit set on the config file. To clean up any + * repositories affected by that bug, and just because + * it doesn't make sense for a config file to be + * executable anyway, clear any executable bits from + * the file (on a "best effort" basis): + */ + if (!lstat(config_file, &st) && (st.st_mode & 0111)) + chmod(config_file, st.st_mode & 07666); + free(config_file); } else if (actions == ACTION_SET) { int ret; diff --git a/config.c b/config.c index 9e42d38..47eaef4 100644 --- a/config.c +++ b/config.c @@ -1653,7 +1653,15 @@ int git_config_set_multivar_in_file(const char *config_filename, MAP_PRIVATE, in_fd, 0); close(in_fd); - if (chmod(lock->filename, st.st_mode & 07777) < 0) { + /* + * We mask off the executable bits because (a) it + * doesn't make sense to have executable bits set on + * the config file, and (b) there was a bug in git 2.1 + * which caused the config file to be created with u+x + * set, so this will help repair repositories created + * with that version. + */ + if (chmod(lock->filename, st.st_mode & 07666) < 0) { error("chmod on %s failed: %s", lock->filename, strerror(errno)); ret = CONFIG_NO_WRITE; @@ -1832,7 +1840,7 @@ int git_config_rename_section_in_file(const char *config_filename, fstat(fileno(config_file), &st); - if (chmod(lock->filename, st.st_mode & 07777) < 0) { + if (chmod(lock->filename, st.st_mode & 07666) < 0) { ret = error("chmod on %s failed: %s", lock->filename, strerror(errno)); goto out; diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 46f6ae2..7637701 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -7,6 +7,12 @@ test_description='Test git config in different settings' . ./test-lib.sh +test_expect_success POSIXPERM 'any executable bits cleared' ' + chmod u+x .git/config && + git config test.me foo && + test ! -x .git/config +' + test_expect_success 'clear default config' ' rm -f .git/config ' @@ -1078,6 +1084,13 @@ test_expect_success 'git config --edit respects core.editor' ' test_cmp expect actual ' +test_expect_success POSIXPERM 'git config --edit clears executable bits' ' + git config -f tmp test.value no && + chmod u+x tmp && + GIT_EDITOR="echo [test]value=yes >" git config -f tmp --edit && + test ! -x tmp +' + # malformed configuration files test_expect_success 'barf on syntax error' ' cat >.git/config <<-\EOF && -- 2.1.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html