Skip to content

Commit 270a344

Browse files
peffgitster
authored andcommitted
config: stop using config_exclusive_filename
The git-config command sometimes operates on the default set of config files (either reading from all, or writing to repo config), and sometimes operates on a specific file. In the latter case, we set the magic global config_exclusive_filename, and the code in config.c does the right thing. Instead, let's have git-config use the "advanced" variants of config.c's functions which let it specify an individual filename (or NULL for the default). This makes the code a lot more obvious, and fixes two small bugs: 1. A relative path specified by GIT_CONFIG=foo will look in the wrong directory if we have to chdir as part of repository setup. We already handle this properly for "git config -f foo", but the GIT_CONFIG lookup used config_exclusive_filename directly. By dropping to a single magic variable, the GIT_CONFIG case now just works. 2. Calling "git config -f foo --edit" would not respect core.editor. This is because just before editing, we called git_config, which would respect the config_exclusive_filename setting, even though this particular git_config call was not about looking in the user's specified file, but rather about loading actual git config, just as any other git program would. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c9b5e2a commit 270a344

File tree

2 files changed

+60
-24
lines changed

2 files changed

+60
-24
lines changed

builtin/config.c

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ static int get_value(const char *key_, const char *regex_)
162162
char *global = NULL, *repo_config = NULL;
163163
const char *system_wide = NULL, *local;
164164

165-
local = config_exclusive_filename;
165+
local = given_config_file;
166166
if (!local) {
167167
const char *home = getenv("HOME");
168168
local = repo_config = git_pathdup("config");
@@ -301,7 +301,8 @@ static void get_color(const char *def_color)
301301
{
302302
get_color_found = 0;
303303
parsed_color[0] = '\0';
304-
git_config(git_get_color_config, NULL);
304+
git_config_with_options(git_get_color_config, NULL,
305+
given_config_file);
305306

306307
if (!get_color_found && def_color)
307308
color_parse(def_color, "command line", parsed_color);
@@ -328,7 +329,8 @@ static int get_colorbool(int print)
328329
{
329330
get_colorbool_found = -1;
330331
get_diff_color_found = -1;
331-
git_config(git_get_colorbool_config, NULL);
332+
git_config_with_options(git_get_colorbool_config, NULL,
333+
given_config_file);
332334

333335
if (get_colorbool_found < 0) {
334336
if (!strcmp(get_colorbool_slot, "color.diff"))
@@ -351,7 +353,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
351353
int nongit = !startup_info->have_repository;
352354
char *value;
353355

354-
config_exclusive_filename = getenv(CONFIG_ENVIRONMENT);
356+
given_config_file = getenv(CONFIG_ENVIRONMENT);
355357

356358
argc = parse_options(argc, argv, prefix, builtin_config_options,
357359
builtin_config_usage,
@@ -366,23 +368,23 @@ int cmd_config(int argc, const char **argv, const char *prefix)
366368
char *home = getenv("HOME");
367369
if (home) {
368370
char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
369-
config_exclusive_filename = user_config;
371+
given_config_file = user_config;
370372
} else {
371373
die("$HOME not set");
372374
}
373375
}
374376
else if (use_system_config)
375-
config_exclusive_filename = git_etc_gitconfig();
377+
given_config_file = git_etc_gitconfig();
376378
else if (use_local_config)
377-
config_exclusive_filename = git_pathdup("config");
379+
given_config_file = git_pathdup("config");
378380
else if (given_config_file) {
379381
if (!is_absolute_path(given_config_file) && prefix)
380-
config_exclusive_filename =
382+
given_config_file =
381383
xstrdup(prefix_filename(prefix,
382384
strlen(prefix),
383385
given_config_file));
384386
else
385-
config_exclusive_filename = given_config_file;
387+
given_config_file = given_config_file;
386388
}
387389

388390
if (end_null) {
@@ -421,28 +423,29 @@ int cmd_config(int argc, const char **argv, const char *prefix)
421423

422424
if (actions == ACTION_LIST) {
423425
check_argc(argc, 0, 0);
424-
if (git_config(show_all_config, NULL) < 0) {
425-
if (config_exclusive_filename)
426+
if (git_config_with_options(show_all_config, NULL,
427+
given_config_file) < 0) {
428+
if (given_config_file)
426429
die_errno("unable to read config file '%s'",
427-
config_exclusive_filename);
430+
given_config_file);
428431
else
429432
die("error processing config file(s)");
430433
}
431434
}
432435
else if (actions == ACTION_EDIT) {
433436
check_argc(argc, 0, 0);
434-
if (!config_exclusive_filename && nongit)
437+
if (!given_config_file && nongit)
435438
die("not in a git directory");
436439
git_config(git_default_config, NULL);
437-
launch_editor(config_exclusive_filename ?
438-
config_exclusive_filename : git_path("config"),
440+
launch_editor(given_config_file ?
441+
given_config_file : git_path("config"),
439442
NULL, NULL);
440443
}
441444
else if (actions == ACTION_SET) {
442445
int ret;
443446
check_argc(argc, 2, 2);
444447
value = normalize_value(argv[0], argv[1]);
445-
ret = git_config_set(argv[0], value);
448+
ret = git_config_set_in_file(given_config_file, argv[0], value);
446449
if (ret == CONFIG_NOTHING_SET)
447450
error("cannot overwrite multiple values with a single value\n"
448451
" Use a regexp, --add or --replace-all to change %s.", argv[0]);
@@ -451,17 +454,20 @@ int cmd_config(int argc, const char **argv, const char *prefix)
451454
else if (actions == ACTION_SET_ALL) {
452455
check_argc(argc, 2, 3);
453456
value = normalize_value(argv[0], argv[1]);
454-
return git_config_set_multivar(argv[0], value, argv[2], 0);
457+
return git_config_set_multivar_in_file(given_config_file,
458+
argv[0], value, argv[2], 0);
455459
}
456460
else if (actions == ACTION_ADD) {
457461
check_argc(argc, 2, 2);
458462
value = normalize_value(argv[0], argv[1]);
459-
return git_config_set_multivar(argv[0], value, "^$", 0);
463+
return git_config_set_multivar_in_file(given_config_file,
464+
argv[0], value, "^$", 0);
460465
}
461466
else if (actions == ACTION_REPLACE_ALL) {
462467
check_argc(argc, 2, 3);
463468
value = normalize_value(argv[0], argv[1]);
464-
return git_config_set_multivar(argv[0], value, argv[2], 1);
469+
return git_config_set_multivar_in_file(given_config_file,
470+
argv[0], value, argv[2], 1);
465471
}
466472
else if (actions == ACTION_GET) {
467473
check_argc(argc, 1, 2);
@@ -482,18 +488,22 @@ int cmd_config(int argc, const char **argv, const char *prefix)
482488
else if (actions == ACTION_UNSET) {
483489
check_argc(argc, 1, 2);
484490
if (argc == 2)
485-
return git_config_set_multivar(argv[0], NULL, argv[1], 0);
491+
return git_config_set_multivar_in_file(given_config_file,
492+
argv[0], NULL, argv[1], 0);
486493
else
487-
return git_config_set(argv[0], NULL);
494+
return git_config_set_in_file(given_config_file,
495+
argv[0], NULL);
488496
}
489497
else if (actions == ACTION_UNSET_ALL) {
490498
check_argc(argc, 1, 2);
491-
return git_config_set_multivar(argv[0], NULL, argv[1], 1);
499+
return git_config_set_multivar_in_file(given_config_file,
500+
argv[0], NULL, argv[1], 1);
492501
}
493502
else if (actions == ACTION_RENAME_SECTION) {
494503
int ret;
495504
check_argc(argc, 2, 2);
496-
ret = git_config_rename_section(argv[0], argv[1]);
505+
ret = git_config_rename_section_in_file(given_config_file,
506+
argv[0], argv[1]);
497507
if (ret < 0)
498508
return ret;
499509
if (ret == 0)
@@ -502,7 +512,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
502512
else if (actions == ACTION_REMOVE_SECTION) {
503513
int ret;
504514
check_argc(argc, 1, 1);
505-
ret = git_config_rename_section(argv[0], NULL);
515+
ret = git_config_rename_section_in_file(given_config_file,
516+
argv[0], NULL);
506517
if (ret < 0)
507518
return ret;
508519
if (ret == 0)

t/t1300-repo-config.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,14 @@ test_expect_success 'refer config from subdirectory' '
458458
459459
'
460460

461+
test_expect_success 'refer config from subdirectory via GIT_CONFIG' '
462+
(
463+
cd x &&
464+
GIT_CONFIG=../other-config git config --get ein.bahn >actual &&
465+
test_cmp expect actual
466+
)
467+
'
468+
461469
cat > expect << EOF
462470
[ein]
463471
bahn = strasse
@@ -960,4 +968,21 @@ test_expect_success 'git -c complains about empty key and value' '
960968
test_must_fail git -c "" rev-parse
961969
'
962970

971+
test_expect_success 'git config --edit works' '
972+
git config -f tmp test.value no &&
973+
echo test.value=yes >expect &&
974+
GIT_EDITOR="echo [test]value=yes >" git config -f tmp --edit &&
975+
git config -f tmp --list >actual &&
976+
test_cmp expect actual
977+
'
978+
979+
test_expect_success 'git config --edit respects core.editor' '
980+
git config -f tmp test.value no &&
981+
echo test.value=yes >expect &&
982+
test_config core.editor "echo [test]value=yes >" &&
983+
git config -f tmp --edit &&
984+
git config -f tmp --list >actual &&
985+
test_cmp expect actual
986+
'
987+
963988
test_done

0 commit comments

Comments
 (0)