Skip to content

Commit 57f0188

Browse files
kbleesdscho
authored andcommitted
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 ... Signed-off-by: Karsten Blees <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 393c2b5 commit 57f0188

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
@@ -1943,6 +1943,24 @@ int git_config_key_is_valid(const char *key)
19431943
return !git_config_parse_key_1(key, NULL, NULL, 1);
19441944
}
19451945

1946+
static int lock_config_file(const char *config_filename,
1947+
struct lock_file **result)
1948+
{
1949+
int fd;
1950+
1951+
/* make sure the parent directory exists */
1952+
if (safe_create_leading_directories_const(config_filename))
1953+
return error("could not create parent directory of %s",
1954+
config_filename);
1955+
*result = xcalloc(1, sizeof(struct lock_file));
1956+
fd = hold_lock_file_for_update(*result, config_filename, 0);
1957+
if (fd < 0)
1958+
error("could not lock config file %s: %s", config_filename,
1959+
strerror(errno));
1960+
1961+
return fd;
1962+
}
1963+
19461964
/*
19471965
* If value==NULL, unset in (remove from) config,
19481966
* if value_regex!=NULL, disregard key/value pairs where value does not match.
@@ -1993,10 +2011,8 @@ int git_config_set_multivar_in_file(const char *config_filename,
19932011
* The lock serves a purpose in addition to locking: the new
19942012
* contents of .git/config will be written into it.
19952013
*/
1996-
lock = xcalloc(1, sizeof(struct lock_file));
1997-
fd = hold_lock_file_for_update(lock, config_filename, 0);
2014+
fd = lock_config_file(config_filename, &lock);
19982015
if (fd < 0) {
1999-
error("could not lock config file %s: %s", config_filename, strerror(errno));
20002016
free(store.key);
20012017
ret = CONFIG_NO_LOCK;
20022018
goto out_free;
@@ -2278,12 +2294,9 @@ int git_config_rename_section_in_file(const char *config_filename,
22782294
if (!config_filename)
22792295
config_filename = filename_buf = git_pathdup("config");
22802296

2281-
lock = xcalloc(1, sizeof(struct lock_file));
2282-
out_fd = hold_lock_file_for_update(lock, config_filename, 0);
2283-
if (out_fd < 0) {
2284-
ret = error("could not lock config file %s", config_filename);
2297+
out_fd = lock_config_file(config_filename, &lock);
2298+
if (out_fd < 0)
22852299
goto out;
2286-
}
22872300

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

0 commit comments

Comments
 (0)