Skip to content

Commit 3f7ec02

Browse files
committed
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. Signed-off-by: Karsten Blees <[email protected]>
1 parent 3a15b17 commit 3f7ec02

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

config.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,6 +1909,24 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
19091909
return -CONFIG_INVALID_KEY;
19101910
}
19111911

1912+
1913+
static int lock_config_file(const char *config_filename,
1914+
struct lock_file **result)
1915+
{
1916+
int fd;
1917+
/* make sure the parent directory exists */
1918+
if (safe_create_leading_directories_const(config_filename)) {
1919+
error("could not create parent directory of %s", config_filename);
1920+
return -1;
1921+
}
1922+
*result = xcalloc(1, sizeof(struct lock_file));
1923+
fd = hold_lock_file_for_update(*result, config_filename, 0);
1924+
if (fd < 0)
1925+
error("could not lock config file %s: %s", config_filename,
1926+
strerror(errno));
1927+
return fd;
1928+
}
1929+
19121930
/*
19131931
* If value==NULL, unset in (remove from) config,
19141932
* if value_regex!=NULL, disregard key/value pairs where value does not match.
@@ -1957,10 +1975,8 @@ int git_config_set_multivar_in_file(const char *config_filename,
19571975
* The lock serves a purpose in addition to locking: the new
19581976
* contents of .git/config will be written into it.
19591977
*/
1960-
lock = xcalloc(1, sizeof(struct lock_file));
1961-
fd = hold_lock_file_for_update(lock, config_filename, 0);
1978+
fd = lock_config_file(config_filename, &lock);
19621979
if (fd < 0) {
1963-
error("could not lock config file %s: %s", config_filename, strerror(errno));
19641980
free(store.key);
19651981
ret = CONFIG_NO_LOCK;
19661982
goto out_free;
@@ -2228,12 +2244,9 @@ int git_config_rename_section_in_file(const char *config_filename,
22282244
if (!config_filename)
22292245
config_filename = filename_buf = git_pathdup("config");
22302246

2231-
lock = xcalloc(1, sizeof(struct lock_file));
2232-
out_fd = hold_lock_file_for_update(lock, config_filename, 0);
2233-
if (out_fd < 0) {
2234-
ret = error("could not lock config file %s", config_filename);
2247+
out_fd = lock_config_file(config_filename, &lock);
2248+
if (out_fd < 0)
22352249
goto out;
2236-
}
22372250

22382251
if (!(config_file = fopen(config_filename, "rb"))) {
22392252
/* no config file means nothing to rename, no error */

0 commit comments

Comments
 (0)