mirror of
https://github.com/git/git.git
synced 2026-01-27 02:48:32 +00:00
config.c: create missing parent directories when modifying config files
'git config' (--add / --unset etc.) automatically creates missing config files. However, it fails with a misleading error message "could not lock config file" if the parent directory doesn't exist. Also create missing parent directories. This is particularly important when calling git config -f /non/existing/directory/config ... We *must not* create the leading directories when locking a config file. It is the caller's responsibility to ensure that the directory exists, just like it is the caller's responsibility to call `git init` before running repository operations. Point in case: if we simply create all leading directories, calling `git config user.name me` *outside* of a Git worktree will *create* .git/! This fixes https://github.com/git-for-windows/git/issues/643 and https://groups.google.com/forum/#!topic/git-for-windows/fVRdnDIKVuw [jes: prevented bogus .git/ directories from being created] Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
committed by
Johannes Schindelin
parent
3fc028717e
commit
77f28237c1
24
config.c
24
config.c
@@ -2041,6 +2041,20 @@ int git_config_key_is_valid(const char *key)
|
||||
return !git_config_parse_key_1(key, NULL, NULL, 1);
|
||||
}
|
||||
|
||||
static int lock_config_file(const char *config_filename,
|
||||
struct lock_file **result)
|
||||
{
|
||||
int fd;
|
||||
|
||||
*result = xcalloc(1, sizeof(struct lock_file));
|
||||
fd = hold_lock_file_for_update(*result, config_filename, 0);
|
||||
if (fd < 0)
|
||||
error("could not lock config file %s: %s", config_filename,
|
||||
strerror(errno));
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* If value==NULL, unset in (remove from) config,
|
||||
* if value_regex!=NULL, disregard key/value pairs where value does not match.
|
||||
@@ -2092,8 +2106,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
|
||||
* The lock serves a purpose in addition to locking: the new
|
||||
* contents of .git/config will be written into it.
|
||||
*/
|
||||
lock = xcalloc(1, sizeof(struct lock_file));
|
||||
fd = hold_lock_file_for_update(lock, config_filename, 0);
|
||||
fd = lock_config_file(config_filename, &lock);
|
||||
if (fd < 0) {
|
||||
error_errno("could not lock config file %s", config_filename);
|
||||
free(store.key);
|
||||
@@ -2394,12 +2407,9 @@ int git_config_rename_section_in_file(const char *config_filename,
|
||||
if (!config_filename)
|
||||
config_filename = filename_buf = git_pathdup("config");
|
||||
|
||||
lock = xcalloc(1, sizeof(struct lock_file));
|
||||
out_fd = hold_lock_file_for_update(lock, config_filename, 0);
|
||||
if (out_fd < 0) {
|
||||
ret = error("could not lock config file %s", config_filename);
|
||||
out_fd = lock_config_file(config_filename, &lock);
|
||||
if (out_fd < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(config_file = fopen(config_filename, "rb"))) {
|
||||
/* no config file means nothing to rename, no error */
|
||||
|
||||
Reference in New Issue
Block a user