2 * GIT - The information manager from hell
4 * Copyright (C) Linus Torvalds, 2005
5 * Copyright (C) Johannes Schindelin, 2005
16 #include "environment.h"
19 #include "repository.h"
26 #include "string-list.h"
27 #include "object-name.h"
28 #include "object-store.h"
33 #include "replace-object.h"
39 #include "write-or-die.h"
41 struct config_source
{
42 struct config_source
*prev
;
51 enum config_origin_type origin_type
;
54 enum config_error_action default_error_action
;
60 unsigned subsection_case_sensitive
: 1;
62 int (*do_fgetc
)(struct config_source
*c
);
63 int (*do_ungetc
)(int c
, struct config_source
*conf
);
64 long (*do_ftell
)(struct config_source
*c
);
68 * These variables record the "current" config source, which
69 * can be accessed by parsing callbacks.
71 * The "cf" variable will be non-NULL only when we are actually parsing a real
72 * config source (file, blob, cmdline, etc).
74 * The "current_config_kvi" variable will be non-NULL only when we are feeding
75 * cached config from a configset into a callback.
77 * They should generally never be non-NULL at the same time. If they are both
78 * NULL, then we aren't parsing anything (and depending on the function looking
79 * at the variables, it's either a bug for it to be called in the first place,
80 * or it's a function which can be reused for non-config purposes, and should
81 * fall back to some sane behavior).
83 static struct config_source
*cf
;
84 static struct key_value_info
*current_config_kvi
;
87 * Similar to the variables above, this gives access to the "scope" of the
88 * current value (repo, global, etc). For cached values, it can be found via
89 * the current_config_kvi as above. During parsing, the current value can be
90 * found in this variable. It's not part of "cf" because it transcends a single
91 * file (i.e., a file included from .git/config is still in "repo" scope).
93 static enum config_scope current_parsing_scope
;
95 static int pack_compression_seen
;
96 static int zlib_compression_seen
;
99 * Config that comes from trusted scopes, namely:
100 * - CONFIG_SCOPE_SYSTEM (e.g. /etc/gitconfig)
101 * - CONFIG_SCOPE_GLOBAL (e.g. $HOME/.gitconfig, $XDG_CONFIG_HOME/git)
102 * - CONFIG_SCOPE_COMMAND (e.g. "-c" option, environment variables)
104 * This is declared here for code cleanliness, but unlike the other
105 * static variables, this does not hold config parser state.
107 static struct config_set protected_config
;
109 static int config_file_fgetc(struct config_source
*conf
)
111 return getc_unlocked(conf
->u
.file
);
114 static int config_file_ungetc(int c
, struct config_source
*conf
)
116 return ungetc(c
, conf
->u
.file
);
119 static long config_file_ftell(struct config_source
*conf
)
121 return ftell(conf
->u
.file
);
125 static int config_buf_fgetc(struct config_source
*conf
)
127 if (conf
->u
.buf
.pos
< conf
->u
.buf
.len
)
128 return conf
->u
.buf
.buf
[conf
->u
.buf
.pos
++];
133 static int config_buf_ungetc(int c
, struct config_source
*conf
)
135 if (conf
->u
.buf
.pos
> 0) {
137 if (conf
->u
.buf
.buf
[conf
->u
.buf
.pos
] != c
)
138 BUG("config_buf can only ungetc the same character");
145 static long config_buf_ftell(struct config_source
*conf
)
147 return conf
->u
.buf
.pos
;
150 struct config_include_data
{
154 const struct config_options
*opts
;
155 struct git_config_source
*config_source
;
158 * All remote URLs discovered when reading all config files.
160 struct string_list
*remote_urls
;
162 #define CONFIG_INCLUDE_INIT { 0 }
164 static int git_config_include(const char *var
, const char *value
, void *data
);
166 #define MAX_INCLUDE_DEPTH 10
167 static const char include_depth_advice
[] = N_(
168 "exceeded maximum include depth (%d) while including\n"
172 "This might be due to circular includes.");
173 static int handle_path_include(const char *path
, struct config_include_data
*inc
)
176 struct strbuf buf
= STRBUF_INIT
;
180 return config_error_nonbool("include.path");
182 expanded
= interpolate_path(path
, 0);
184 return error(_("could not expand include path '%s'"), path
);
188 * Use an absolute path as-is, but interpret relative paths
189 * based on the including config file.
191 if (!is_absolute_path(path
)) {
194 if (!cf
|| !cf
->path
) {
195 ret
= error(_("relative config includes must come from files"));
199 slash
= find_last_dir_sep(cf
->path
);
201 strbuf_add(&buf
, cf
->path
, slash
- cf
->path
+ 1);
202 strbuf_addstr(&buf
, path
);
206 if (!access_or_die(path
, R_OK
, 0)) {
207 if (++inc
->depth
> MAX_INCLUDE_DEPTH
)
208 die(_(include_depth_advice
), MAX_INCLUDE_DEPTH
, path
,
210 cf
->name
? cf
->name
:
212 ret
= git_config_from_file(git_config_include
, path
, inc
);
216 strbuf_release(&buf
);
221 static void add_trailing_starstar_for_dir(struct strbuf
*pat
)
223 if (pat
->len
&& is_dir_sep(pat
->buf
[pat
->len
- 1]))
224 strbuf_addstr(pat
, "**");
227 static int prepare_include_condition_pattern(struct strbuf
*pat
)
229 struct strbuf path
= STRBUF_INIT
;
233 expanded
= interpolate_path(pat
->buf
, 1);
236 strbuf_addstr(pat
, expanded
);
240 if (pat
->buf
[0] == '.' && is_dir_sep(pat
->buf
[1])) {
243 if (!cf
|| !cf
->path
)
244 return error(_("relative config include "
245 "conditionals must come from files"));
247 strbuf_realpath(&path
, cf
->path
, 1);
248 slash
= find_last_dir_sep(path
.buf
);
250 BUG("how is this possible?");
251 strbuf_splice(pat
, 0, 1, path
.buf
, slash
- path
.buf
);
252 prefix
= slash
- path
.buf
+ 1 /* slash */;
253 } else if (!is_absolute_path(pat
->buf
))
254 strbuf_insertstr(pat
, 0, "**/");
256 add_trailing_starstar_for_dir(pat
);
258 strbuf_release(&path
);
262 static int include_by_gitdir(const struct config_options
*opts
,
263 const char *cond
, size_t cond_len
, int icase
)
265 struct strbuf text
= STRBUF_INIT
;
266 struct strbuf pattern
= STRBUF_INIT
;
269 int already_tried_absolute
= 0;
272 git_dir
= opts
->git_dir
;
276 strbuf_realpath(&text
, git_dir
, 1);
277 strbuf_add(&pattern
, cond
, cond_len
);
278 prefix
= prepare_include_condition_pattern(&pattern
);
286 * perform literal matching on the prefix part so that
287 * any wildcard character in it can't create side effects.
289 if (text
.len
< prefix
)
291 if (!icase
&& strncmp(pattern
.buf
, text
.buf
, prefix
))
293 if (icase
&& strncasecmp(pattern
.buf
, text
.buf
, prefix
))
297 ret
= !wildmatch(pattern
.buf
+ prefix
, text
.buf
+ prefix
,
298 WM_PATHNAME
| (icase
? WM_CASEFOLD
: 0));
300 if (!ret
&& !already_tried_absolute
) {
302 * We've tried e.g. matching gitdir:~/work, but if
303 * ~/work is a symlink to /mnt/storage/work
304 * strbuf_realpath() will expand it, so the rule won't
305 * match. Let's match against a
306 * strbuf_add_absolute_path() version of the path,
307 * which'll do the right thing
310 strbuf_add_absolute_path(&text
, git_dir
);
311 already_tried_absolute
= 1;
315 strbuf_release(&pattern
);
316 strbuf_release(&text
);
320 static int include_by_branch(const char *cond
, size_t cond_len
)
324 struct strbuf pattern
= STRBUF_INIT
;
325 const char *refname
= !the_repository
->gitdir
?
326 NULL
: resolve_ref_unsafe("HEAD", 0, NULL
, &flags
);
327 const char *shortname
;
329 if (!refname
|| !(flags
& REF_ISSYMREF
) ||
330 !skip_prefix(refname
, "refs/heads/", &shortname
))
333 strbuf_add(&pattern
, cond
, cond_len
);
334 add_trailing_starstar_for_dir(&pattern
);
335 ret
= !wildmatch(pattern
.buf
, shortname
, WM_PATHNAME
);
336 strbuf_release(&pattern
);
340 static int add_remote_url(const char *var
, const char *value
, void *data
)
342 struct string_list
*remote_urls
= data
;
343 const char *remote_name
;
344 size_t remote_name_len
;
347 if (!parse_config_key(var
, "remote", &remote_name
, &remote_name_len
,
351 string_list_append(remote_urls
, value
);
355 static void populate_remote_urls(struct config_include_data
*inc
)
357 struct config_options opts
;
359 struct config_source
*store_cf
= cf
;
360 struct key_value_info
*store_kvi
= current_config_kvi
;
361 enum config_scope store_scope
= current_parsing_scope
;
364 opts
.unconditional_remote_url
= 1;
367 current_config_kvi
= NULL
;
368 current_parsing_scope
= 0;
370 inc
->remote_urls
= xmalloc(sizeof(*inc
->remote_urls
));
371 string_list_init_dup(inc
->remote_urls
);
372 config_with_options(add_remote_url
, inc
->remote_urls
, inc
->config_source
, &opts
);
375 current_config_kvi
= store_kvi
;
376 current_parsing_scope
= store_scope
;
379 static int forbid_remote_url(const char *var
, const char *value UNUSED
,
382 const char *remote_name
;
383 size_t remote_name_len
;
386 if (!parse_config_key(var
, "remote", &remote_name
, &remote_name_len
,
390 die(_("remote URLs cannot be configured in file directly or indirectly included by includeIf.hasconfig:remote.*.url"));
394 static int at_least_one_url_matches_glob(const char *glob
, int glob_len
,
395 struct string_list
*remote_urls
)
397 struct strbuf pattern
= STRBUF_INIT
;
398 struct string_list_item
*url_item
;
401 strbuf_add(&pattern
, glob
, glob_len
);
402 for_each_string_list_item(url_item
, remote_urls
) {
403 if (!wildmatch(pattern
.buf
, url_item
->string
, WM_PATHNAME
)) {
408 strbuf_release(&pattern
);
412 static int include_by_remote_url(struct config_include_data
*inc
,
413 const char *cond
, size_t cond_len
)
415 if (inc
->opts
->unconditional_remote_url
)
417 if (!inc
->remote_urls
)
418 populate_remote_urls(inc
);
419 return at_least_one_url_matches_glob(cond
, cond_len
,
423 static int include_condition_is_true(struct config_include_data
*inc
,
424 const char *cond
, size_t cond_len
)
426 const struct config_options
*opts
= inc
->opts
;
428 if (skip_prefix_mem(cond
, cond_len
, "gitdir:", &cond
, &cond_len
))
429 return include_by_gitdir(opts
, cond
, cond_len
, 0);
430 else if (skip_prefix_mem(cond
, cond_len
, "gitdir/i:", &cond
, &cond_len
))
431 return include_by_gitdir(opts
, cond
, cond_len
, 1);
432 else if (skip_prefix_mem(cond
, cond_len
, "onbranch:", &cond
, &cond_len
))
433 return include_by_branch(cond
, cond_len
);
434 else if (skip_prefix_mem(cond
, cond_len
, "hasconfig:remote.*.url:", &cond
,
436 return include_by_remote_url(inc
, cond
, cond_len
);
438 /* unknown conditionals are always false */
442 static int git_config_include(const char *var
, const char *value
, void *data
)
444 struct config_include_data
*inc
= data
;
445 const char *cond
, *key
;
450 * Pass along all values, including "include" directives; this makes it
451 * possible to query information on the includes themselves.
453 ret
= inc
->fn(var
, value
, inc
->data
);
457 if (!strcmp(var
, "include.path"))
458 ret
= handle_path_include(value
, inc
);
460 if (!parse_config_key(var
, "includeif", &cond
, &cond_len
, &key
) &&
461 cond
&& include_condition_is_true(inc
, cond
, cond_len
) &&
462 !strcmp(key
, "path")) {
463 config_fn_t old_fn
= inc
->fn
;
465 if (inc
->opts
->unconditional_remote_url
)
466 inc
->fn
= forbid_remote_url
;
467 ret
= handle_path_include(value
, inc
);
474 static void git_config_push_split_parameter(const char *key
, const char *value
)
476 struct strbuf env
= STRBUF_INIT
;
477 const char *old
= getenv(CONFIG_DATA_ENVIRONMENT
);
479 strbuf_addstr(&env
, old
);
480 strbuf_addch(&env
, ' ');
482 sq_quote_buf(&env
, key
);
483 strbuf_addch(&env
, '=');
485 sq_quote_buf(&env
, value
);
486 setenv(CONFIG_DATA_ENVIRONMENT
, env
.buf
, 1);
487 strbuf_release(&env
);
490 void git_config_push_parameter(const char *text
)
497 * section.subsection=with=equals.key=value
499 * we cannot tell if it means:
501 * [section "subsection=with=equals"]
507 * subsection = with=equals.key=value
509 * We parse left-to-right for the first "=", meaning we'll prefer to
510 * keep the value intact over the subsection. This is historical, but
511 * also sensible since values are more likely to contain odd or
512 * untrusted input than a section name.
514 * A missing equals is explicitly allowed (as a bool-only entry).
516 value
= strchr(text
, '=');
518 char *key
= xmemdupz(text
, value
- text
);
519 git_config_push_split_parameter(key
, value
+ 1);
522 git_config_push_split_parameter(text
, NULL
);
526 void git_config_push_env(const char *spec
)
529 const char *env_name
;
530 const char *env_value
;
532 env_name
= strrchr(spec
, '=');
534 die(_("invalid config format: %s"), spec
);
535 key
= xmemdupz(spec
, env_name
- spec
);
538 die(_("missing environment variable name for configuration '%.*s'"),
539 (int)(env_name
- spec
- 1), spec
);
541 env_value
= getenv(env_name
);
543 die(_("missing environment variable '%s' for configuration '%.*s'"),
544 env_name
, (int)(env_name
- spec
- 1), spec
);
546 git_config_push_split_parameter(key
, env_value
);
550 static inline int iskeychar(int c
)
552 return isalnum(c
) || c
== '-';
556 * Auxiliary function to sanity-check and split the key into the section
557 * identifier and variable name.
559 * Returns 0 on success, -1 when there is an invalid character in the key and
560 * -2 if there is no section name in the key.
562 * store_key - pointer to char* which will hold a copy of the key with
563 * lowercase section and variable name
564 * baselen - pointer to size_t which will hold the length of the
565 * section + subsection part, can be NULL
567 int git_config_parse_key(const char *key
, char **store_key
, size_t *baselen_
)
571 const char *last_dot
= strrchr(key
, '.');
574 * Since "key" actually contains the section name and the real
575 * key name separated by a dot, we have to know where the dot is.
578 if (last_dot
== NULL
|| last_dot
== key
) {
579 error(_("key does not contain a section: %s"), key
);
580 return -CONFIG_NO_SECTION_OR_NAME
;
584 error(_("key does not contain variable name: %s"), key
);
585 return -CONFIG_NO_SECTION_OR_NAME
;
588 baselen
= last_dot
- key
;
593 * Validate the key and while at it, lower case it for matching.
595 *store_key
= xmallocz(strlen(key
));
598 for (i
= 0; key
[i
]; i
++) {
599 unsigned char c
= key
[i
];
602 /* Leave the extended basename untouched.. */
603 if (!dot
|| i
> baselen
) {
605 (i
== baselen
+ 1 && !isalpha(c
))) {
606 error(_("invalid key: %s"), key
);
610 } else if (c
== '\n') {
611 error(_("invalid key (newline): %s"), key
);
620 FREE_AND_NULL(*store_key
);
621 return -CONFIG_INVALID_KEY
;
624 static int config_parse_pair(const char *key
, const char *value
,
625 config_fn_t fn
, void *data
)
627 char *canonical_name
;
631 return error(_("empty config key"));
632 if (git_config_parse_key(key
, &canonical_name
, NULL
))
635 ret
= (fn(canonical_name
, value
, data
) < 0) ? -1 : 0;
636 free(canonical_name
);
640 int git_config_parse_parameter(const char *text
,
641 config_fn_t fn
, void *data
)
644 struct strbuf
**pair
;
647 pair
= strbuf_split_str(text
, '=', 2);
649 return error(_("bogus config parameter: %s"), text
);
651 if (pair
[0]->len
&& pair
[0]->buf
[pair
[0]->len
- 1] == '=') {
652 strbuf_setlen(pair
[0], pair
[0]->len
- 1);
653 value
= pair
[1] ? pair
[1]->buf
: "";
658 strbuf_trim(pair
[0]);
660 strbuf_list_free(pair
);
661 return error(_("bogus config parameter: %s"), text
);
664 ret
= config_parse_pair(pair
[0]->buf
, value
, fn
, data
);
665 strbuf_list_free(pair
);
669 static int parse_config_env_list(char *env
, config_fn_t fn
, void *data
)
672 while (cur
&& *cur
) {
673 const char *key
= sq_dequote_step(cur
, &cur
);
675 return error(_("bogus format in %s"),
676 CONFIG_DATA_ENVIRONMENT
);
678 if (!cur
|| isspace(*cur
)) {
679 /* old-style 'key=value' */
680 if (git_config_parse_parameter(key
, fn
, data
) < 0)
683 else if (*cur
== '=') {
684 /* new-style 'key'='value' */
690 value
= sq_dequote_step(cur
, &cur
);
691 if (!value
|| (cur
&& !isspace(*cur
))) {
692 return error(_("bogus format in %s"),
693 CONFIG_DATA_ENVIRONMENT
);
695 } else if (!*cur
|| isspace(*cur
)) {
696 /* implicit bool: 'key'= */
699 return error(_("bogus format in %s"),
700 CONFIG_DATA_ENVIRONMENT
);
703 if (config_parse_pair(key
, value
, fn
, data
) < 0)
708 return error(_("bogus format in %s"),
709 CONFIG_DATA_ENVIRONMENT
);
713 while (isspace(*cur
))
720 int git_config_from_parameters(config_fn_t fn
, void *data
)
723 struct strbuf envvar
= STRBUF_INIT
;
724 struct strvec to_free
= STRVEC_INIT
;
727 struct config_source source
;
729 memset(&source
, 0, sizeof(source
));
731 source
.origin_type
= CONFIG_ORIGIN_CMDLINE
;
734 env
= getenv(CONFIG_COUNT_ENVIRONMENT
);
740 count
= strtoul(env
, &endp
, 10);
742 ret
= error(_("bogus count in %s"), CONFIG_COUNT_ENVIRONMENT
);
745 if (count
> INT_MAX
) {
746 ret
= error(_("too many entries in %s"), CONFIG_COUNT_ENVIRONMENT
);
750 for (i
= 0; i
< count
; i
++) {
751 const char *key
, *value
;
753 strbuf_addf(&envvar
, "GIT_CONFIG_KEY_%d", i
);
754 key
= getenv_safe(&to_free
, envvar
.buf
);
756 ret
= error(_("missing config key %s"), envvar
.buf
);
759 strbuf_reset(&envvar
);
761 strbuf_addf(&envvar
, "GIT_CONFIG_VALUE_%d", i
);
762 value
= getenv_safe(&to_free
, envvar
.buf
);
764 ret
= error(_("missing config value %s"), envvar
.buf
);
767 strbuf_reset(&envvar
);
769 if (config_parse_pair(key
, value
, fn
, data
) < 0) {
776 env
= getenv(CONFIG_DATA_ENVIRONMENT
);
778 /* sq_dequote will write over it */
780 if (parse_config_env_list(envw
, fn
, data
) < 0) {
787 strbuf_release(&envvar
);
788 strvec_clear(&to_free
);
794 static int get_next_char(void)
796 int c
= cf
->do_fgetc(cf
);
799 /* DOS like systems */
800 c
= cf
->do_fgetc(cf
);
803 cf
->do_ungetc(c
, cf
);
808 if (c
!= EOF
&& ++cf
->total_len
> INT_MAX
) {
810 * This is an absurdly long config file; refuse to parse
811 * further in order to protect downstream code from integer
812 * overflows. Note that we can't return an error specifically,
813 * but we can mark EOF and put trash in the return value,
814 * which will trigger a parse error.
830 static char *parse_value(void)
832 int quote
= 0, comment
= 0, space
= 0;
834 strbuf_reset(&cf
->value
);
836 int c
= get_next_char();
842 return cf
->value
.buf
;
846 if (isspace(c
) && !quote
) {
852 if (c
== ';' || c
== '#') {
857 for (; space
; space
--)
858 strbuf_addch(&cf
->value
, ' ');
873 /* Some characters escape as themselves */
876 /* Reject unknown escape sequences */
880 strbuf_addch(&cf
->value
, c
);
887 strbuf_addch(&cf
->value
, c
);
891 static int get_value(config_fn_t fn
, void *data
, struct strbuf
*name
)
897 /* Get the full name */
904 strbuf_addch(name
, tolower(c
));
907 while (c
== ' ' || c
== '\t')
914 value
= parse_value();
919 * We already consumed the \n, but we need linenr to point to
920 * the line we just parsed during the call to fn to get
921 * accurate line number in error messages.
924 ret
= fn(name
->buf
, value
, data
);
930 static int get_extended_base_var(struct strbuf
*name
, int c
)
932 cf
->subsection_case_sensitive
= 0;
935 goto error_incomplete_line
;
937 } while (isspace(c
));
939 /* We require the format to be '[base "extension"]' */
942 strbuf_addch(name
, '.');
945 int c
= get_next_char();
947 goto error_incomplete_line
;
953 goto error_incomplete_line
;
955 strbuf_addch(name
, c
);
959 if (get_next_char() != ']')
962 error_incomplete_line
:
967 static int get_base_var(struct strbuf
*name
)
969 cf
->subsection_case_sensitive
= 1;
971 int c
= get_next_char();
977 return get_extended_base_var(name
, c
);
978 if (!iskeychar(c
) && c
!= '.')
980 strbuf_addch(name
, tolower(c
));
984 struct parse_event_data
{
985 enum config_event_t previous_type
;
986 size_t previous_offset
;
987 const struct config_options
*opts
;
990 static int do_event(enum config_event_t type
, struct parse_event_data
*data
)
994 if (!data
->opts
|| !data
->opts
->event_fn
)
997 if (type
== CONFIG_EVENT_WHITESPACE
&&
998 data
->previous_type
== type
)
1001 offset
= cf
->do_ftell(cf
);
1003 * At EOF, the parser always "inserts" an extra '\n', therefore
1004 * the end offset of the event is the current file position, otherwise
1005 * we will already have advanced to the next event.
1007 if (type
!= CONFIG_EVENT_EOF
)
1010 if (data
->previous_type
!= CONFIG_EVENT_EOF
&&
1011 data
->opts
->event_fn(data
->previous_type
, data
->previous_offset
,
1012 offset
, data
->opts
->event_fn_data
) < 0)
1015 data
->previous_type
= type
;
1016 data
->previous_offset
= offset
;
1021 static int git_parse_source(config_fn_t fn
, void *data
,
1022 const struct config_options
*opts
)
1026 struct strbuf
*var
= &cf
->var
;
1027 int error_return
= 0;
1028 char *error_msg
= NULL
;
1030 /* U+FEFF Byte Order Mark in UTF8 */
1031 const char *bomptr
= utf8_bom
;
1033 /* For the parser event callback */
1034 struct parse_event_data event_data
= {
1035 CONFIG_EVENT_EOF
, 0, opts
1041 c
= get_next_char();
1042 if (bomptr
&& *bomptr
) {
1043 /* We are at the file beginning; skip UTF8-encoded BOM
1044 * if present. Sane editors won't put this in on their
1045 * own, but e.g. Windows Notepad will do it happily. */
1046 if (c
== (*bomptr
& 0377)) {
1050 /* Do not tolerate partial BOM. */
1051 if (bomptr
!= utf8_bom
)
1053 /* No BOM at file beginning. Cool. */
1059 if (do_event(CONFIG_EVENT_EOF
, &event_data
) < 0)
1063 if (do_event(CONFIG_EVENT_WHITESPACE
, &event_data
) < 0)
1071 if (do_event(CONFIG_EVENT_WHITESPACE
, &event_data
) < 0)
1075 if (c
== '#' || c
== ';') {
1076 if (do_event(CONFIG_EVENT_COMMENT
, &event_data
) < 0)
1082 if (do_event(CONFIG_EVENT_SECTION
, &event_data
) < 0)
1085 /* Reset prior to determining a new stem */
1087 if (get_base_var(var
) < 0 || var
->len
< 1)
1089 strbuf_addch(var
, '.');
1096 if (do_event(CONFIG_EVENT_ENTRY
, &event_data
) < 0)
1100 * Truncate the var name back to the section header
1101 * stem prior to grabbing the suffix part of the name
1104 strbuf_setlen(var
, baselen
);
1105 strbuf_addch(var
, tolower(c
));
1106 if (get_value(fn
, data
, var
) < 0)
1110 if (do_event(CONFIG_EVENT_ERROR
, &event_data
) < 0)
1113 switch (cf
->origin_type
) {
1114 case CONFIG_ORIGIN_BLOB
:
1115 error_msg
= xstrfmt(_("bad config line %d in blob %s"),
1116 cf
->linenr
, cf
->name
);
1118 case CONFIG_ORIGIN_FILE
:
1119 error_msg
= xstrfmt(_("bad config line %d in file %s"),
1120 cf
->linenr
, cf
->name
);
1122 case CONFIG_ORIGIN_STDIN
:
1123 error_msg
= xstrfmt(_("bad config line %d in standard input"),
1126 case CONFIG_ORIGIN_SUBMODULE_BLOB
:
1127 error_msg
= xstrfmt(_("bad config line %d in submodule-blob %s"),
1128 cf
->linenr
, cf
->name
);
1130 case CONFIG_ORIGIN_CMDLINE
:
1131 error_msg
= xstrfmt(_("bad config line %d in command line %s"),
1132 cf
->linenr
, cf
->name
);
1135 error_msg
= xstrfmt(_("bad config line %d in %s"),
1136 cf
->linenr
, cf
->name
);
1139 switch (opts
&& opts
->error_action
?
1140 opts
->error_action
:
1141 cf
->default_error_action
) {
1142 case CONFIG_ERROR_DIE
:
1143 die("%s", error_msg
);
1145 case CONFIG_ERROR_ERROR
:
1146 error_return
= error("%s", error_msg
);
1148 case CONFIG_ERROR_SILENT
:
1151 case CONFIG_ERROR_UNSET
:
1152 BUG("config error action unset");
1156 return error_return
;
1159 static uintmax_t get_unit_factor(const char *end
)
1163 else if (!strcasecmp(end
, "k"))
1165 else if (!strcasecmp(end
, "m"))
1167 else if (!strcasecmp(end
, "g"))
1168 return 1024 * 1024 * 1024;
1172 static int git_parse_signed(const char *value
, intmax_t *ret
, intmax_t max
)
1174 if (value
&& *value
) {
1180 BUG("max must be a positive integer");
1183 val
= strtoimax(value
, &end
, 0);
1184 if (errno
== ERANGE
)
1190 factor
= get_unit_factor(end
);
1195 if ((val
< 0 && -max
/ factor
> val
) ||
1196 (val
> 0 && max
/ factor
< val
)) {
1208 static int git_parse_unsigned(const char *value
, uintmax_t *ret
, uintmax_t max
)
1210 if (value
&& *value
) {
1215 /* negative values would be accepted by strtoumax */
1216 if (strchr(value
, '-')) {
1221 val
= strtoumax(value
, &end
, 0);
1222 if (errno
== ERANGE
)
1228 factor
= get_unit_factor(end
);
1233 if (unsigned_mult_overflows(factor
, val
) ||
1234 factor
* val
> max
) {
1246 int git_parse_int(const char *value
, int *ret
)
1249 if (!git_parse_signed(value
, &tmp
, maximum_signed_value_of_type(int)))
1255 static int git_parse_int64(const char *value
, int64_t *ret
)
1258 if (!git_parse_signed(value
, &tmp
, maximum_signed_value_of_type(int64_t)))
1264 int git_parse_ulong(const char *value
, unsigned long *ret
)
1267 if (!git_parse_unsigned(value
, &tmp
, maximum_unsigned_value_of_type(long)))
1273 int git_parse_ssize_t(const char *value
, ssize_t
*ret
)
1276 if (!git_parse_signed(value
, &tmp
, maximum_signed_value_of_type(ssize_t
)))
1283 static void die_bad_number(const char *name
, const char *value
)
1285 const char *error_type
= (errno
== ERANGE
) ?
1286 N_("out of range") : N_("invalid unit");
1287 const char *bad_numeric
= N_("bad numeric config value '%s' for '%s': %s");
1292 if (!(cf
&& cf
->name
))
1293 die(_(bad_numeric
), value
, name
, _(error_type
));
1295 switch (cf
->origin_type
) {
1296 case CONFIG_ORIGIN_BLOB
:
1297 die(_("bad numeric config value '%s' for '%s' in blob %s: %s"),
1298 value
, name
, cf
->name
, _(error_type
));
1299 case CONFIG_ORIGIN_FILE
:
1300 die(_("bad numeric config value '%s' for '%s' in file %s: %s"),
1301 value
, name
, cf
->name
, _(error_type
));
1302 case CONFIG_ORIGIN_STDIN
:
1303 die(_("bad numeric config value '%s' for '%s' in standard input: %s"),
1304 value
, name
, _(error_type
));
1305 case CONFIG_ORIGIN_SUBMODULE_BLOB
:
1306 die(_("bad numeric config value '%s' for '%s' in submodule-blob %s: %s"),
1307 value
, name
, cf
->name
, _(error_type
));
1308 case CONFIG_ORIGIN_CMDLINE
:
1309 die(_("bad numeric config value '%s' for '%s' in command line %s: %s"),
1310 value
, name
, cf
->name
, _(error_type
));
1312 die(_("bad numeric config value '%s' for '%s' in %s: %s"),
1313 value
, name
, cf
->name
, _(error_type
));
1317 int git_config_int(const char *name
, const char *value
)
1320 if (!git_parse_int(value
, &ret
))
1321 die_bad_number(name
, value
);
1325 int64_t git_config_int64(const char *name
, const char *value
)
1328 if (!git_parse_int64(value
, &ret
))
1329 die_bad_number(name
, value
);
1333 unsigned long git_config_ulong(const char *name
, const char *value
)
1336 if (!git_parse_ulong(value
, &ret
))
1337 die_bad_number(name
, value
);
1341 ssize_t
git_config_ssize_t(const char *name
, const char *value
)
1344 if (!git_parse_ssize_t(value
, &ret
))
1345 die_bad_number(name
, value
);
1349 static int git_parse_maybe_bool_text(const char *value
)
1355 if (!strcasecmp(value
, "true")
1356 || !strcasecmp(value
, "yes")
1357 || !strcasecmp(value
, "on"))
1359 if (!strcasecmp(value
, "false")
1360 || !strcasecmp(value
, "no")
1361 || !strcasecmp(value
, "off"))
1366 static const struct fsync_component_name
{
1368 enum fsync_component component_bits
;
1369 } fsync_component_names
[] = {
1370 { "loose-object", FSYNC_COMPONENT_LOOSE_OBJECT
},
1371 { "pack", FSYNC_COMPONENT_PACK
},
1372 { "pack-metadata", FSYNC_COMPONENT_PACK_METADATA
},
1373 { "commit-graph", FSYNC_COMPONENT_COMMIT_GRAPH
},
1374 { "index", FSYNC_COMPONENT_INDEX
},
1375 { "objects", FSYNC_COMPONENTS_OBJECTS
},
1376 { "reference", FSYNC_COMPONENT_REFERENCE
},
1377 { "derived-metadata", FSYNC_COMPONENTS_DERIVED_METADATA
},
1378 { "committed", FSYNC_COMPONENTS_COMMITTED
},
1379 { "added", FSYNC_COMPONENTS_ADDED
},
1380 { "all", FSYNC_COMPONENTS_ALL
},
1383 static enum fsync_component
parse_fsync_components(const char *var
, const char *string
)
1385 enum fsync_component current
= FSYNC_COMPONENTS_PLATFORM_DEFAULT
;
1386 enum fsync_component positive
= 0, negative
= 0;
1395 string
= string
+ strspn(string
, ", \t\n\r");
1396 ep
= strchrnul(string
, ',');
1398 if (!strcmp(string
, "none")) {
1399 current
= FSYNC_COMPONENT_NONE
;
1403 if (*string
== '-') {
1408 warning(_("invalid value for variable %s"), var
);
1414 for (i
= 0; i
< ARRAY_SIZE(fsync_component_names
); ++i
) {
1415 const struct fsync_component_name
*n
= &fsync_component_names
[i
];
1417 if (strncmp(n
->name
, string
, len
))
1422 negative
|= n
->component_bits
;
1424 positive
|= n
->component_bits
;
1428 char *component
= xstrndup(string
, len
);
1429 warning(_("ignoring unknown core.fsync component '%s'"), component
);
1437 return (current
& ~negative
) | positive
;
1440 int git_parse_maybe_bool(const char *value
)
1442 int v
= git_parse_maybe_bool_text(value
);
1445 if (git_parse_int(value
, &v
))
1450 int git_config_bool_or_int(const char *name
, const char *value
, int *is_bool
)
1452 int v
= git_parse_maybe_bool_text(value
);
1458 return git_config_int(name
, value
);
1461 int git_config_bool(const char *name
, const char *value
)
1463 int v
= git_parse_maybe_bool(value
);
1465 die(_("bad boolean config value '%s' for '%s'"), value
, name
);
1469 int git_config_string(const char **dest
, const char *var
, const char *value
)
1472 return config_error_nonbool(var
);
1473 *dest
= xstrdup(value
);
1477 int git_config_pathname(const char **dest
, const char *var
, const char *value
)
1480 return config_error_nonbool(var
);
1481 *dest
= interpolate_path(value
, 0);
1483 die(_("failed to expand user dir in: '%s'"), value
);
1487 int git_config_expiry_date(timestamp_t
*timestamp
, const char *var
, const char *value
)
1490 return config_error_nonbool(var
);
1491 if (parse_expiry_date(value
, timestamp
))
1492 return error(_("'%s' for '%s' is not a valid timestamp"),
1497 int git_config_color(char *dest
, const char *var
, const char *value
)
1500 return config_error_nonbool(var
);
1501 if (color_parse(value
, dest
) < 0)
1506 static int git_default_core_config(const char *var
, const char *value
, void *cb
)
1508 /* This needs a better name */
1509 if (!strcmp(var
, "core.filemode")) {
1510 trust_executable_bit
= git_config_bool(var
, value
);
1513 if (!strcmp(var
, "core.trustctime")) {
1514 trust_ctime
= git_config_bool(var
, value
);
1517 if (!strcmp(var
, "core.checkstat")) {
1518 if (!strcasecmp(value
, "default"))
1520 else if (!strcasecmp(value
, "minimal"))
1524 if (!strcmp(var
, "core.quotepath")) {
1525 quote_path_fully
= git_config_bool(var
, value
);
1529 if (!strcmp(var
, "core.symlinks")) {
1530 has_symlinks
= git_config_bool(var
, value
);
1534 if (!strcmp(var
, "core.ignorecase")) {
1535 ignore_case
= git_config_bool(var
, value
);
1539 if (!strcmp(var
, "core.attributesfile"))
1540 return git_config_pathname(&git_attributes_file
, var
, value
);
1542 if (!strcmp(var
, "core.hookspath"))
1543 return git_config_pathname(&git_hooks_path
, var
, value
);
1545 if (!strcmp(var
, "core.bare")) {
1546 is_bare_repository_cfg
= git_config_bool(var
, value
);
1550 if (!strcmp(var
, "core.ignorestat")) {
1551 assume_unchanged
= git_config_bool(var
, value
);
1555 if (!strcmp(var
, "core.prefersymlinkrefs")) {
1556 prefer_symlink_refs
= git_config_bool(var
, value
);
1560 if (!strcmp(var
, "core.logallrefupdates")) {
1561 if (value
&& !strcasecmp(value
, "always"))
1562 log_all_ref_updates
= LOG_REFS_ALWAYS
;
1563 else if (git_config_bool(var
, value
))
1564 log_all_ref_updates
= LOG_REFS_NORMAL
;
1566 log_all_ref_updates
= LOG_REFS_NONE
;
1570 if (!strcmp(var
, "core.warnambiguousrefs")) {
1571 warn_ambiguous_refs
= git_config_bool(var
, value
);
1575 if (!strcmp(var
, "core.abbrev")) {
1577 return config_error_nonbool(var
);
1578 if (!strcasecmp(value
, "auto"))
1579 default_abbrev
= -1;
1580 else if (!git_parse_maybe_bool_text(value
))
1581 default_abbrev
= the_hash_algo
->hexsz
;
1583 int abbrev
= git_config_int(var
, value
);
1584 if (abbrev
< minimum_abbrev
|| abbrev
> the_hash_algo
->hexsz
)
1585 return error(_("abbrev length out of range: %d"), abbrev
);
1586 default_abbrev
= abbrev
;
1591 if (!strcmp(var
, "core.disambiguate"))
1592 return set_disambiguate_hint_config(var
, value
);
1594 if (!strcmp(var
, "core.loosecompression")) {
1595 int level
= git_config_int(var
, value
);
1597 level
= Z_DEFAULT_COMPRESSION
;
1598 else if (level
< 0 || level
> Z_BEST_COMPRESSION
)
1599 die(_("bad zlib compression level %d"), level
);
1600 zlib_compression_level
= level
;
1601 zlib_compression_seen
= 1;
1605 if (!strcmp(var
, "core.compression")) {
1606 int level
= git_config_int(var
, value
);
1608 level
= Z_DEFAULT_COMPRESSION
;
1609 else if (level
< 0 || level
> Z_BEST_COMPRESSION
)
1610 die(_("bad zlib compression level %d"), level
);
1611 if (!zlib_compression_seen
)
1612 zlib_compression_level
= level
;
1613 if (!pack_compression_seen
)
1614 pack_compression_level
= level
;
1618 if (!strcmp(var
, "core.packedgitwindowsize")) {
1619 int pgsz_x2
= getpagesize() * 2;
1620 packed_git_window_size
= git_config_ulong(var
, value
);
1622 /* This value must be multiple of (pagesize * 2) */
1623 packed_git_window_size
/= pgsz_x2
;
1624 if (packed_git_window_size
< 1)
1625 packed_git_window_size
= 1;
1626 packed_git_window_size
*= pgsz_x2
;
1630 if (!strcmp(var
, "core.bigfilethreshold")) {
1631 big_file_threshold
= git_config_ulong(var
, value
);
1635 if (!strcmp(var
, "core.packedgitlimit")) {
1636 packed_git_limit
= git_config_ulong(var
, value
);
1640 if (!strcmp(var
, "core.deltabasecachelimit")) {
1641 delta_base_cache_limit
= git_config_ulong(var
, value
);
1645 if (!strcmp(var
, "core.autocrlf")) {
1646 if (value
&& !strcasecmp(value
, "input")) {
1647 auto_crlf
= AUTO_CRLF_INPUT
;
1650 auto_crlf
= git_config_bool(var
, value
);
1654 if (!strcmp(var
, "core.safecrlf")) {
1656 if (value
&& !strcasecmp(value
, "warn")) {
1657 global_conv_flags_eol
= CONV_EOL_RNDTRP_WARN
;
1660 eol_rndtrp_die
= git_config_bool(var
, value
);
1661 global_conv_flags_eol
= eol_rndtrp_die
?
1662 CONV_EOL_RNDTRP_DIE
: 0;
1666 if (!strcmp(var
, "core.eol")) {
1667 if (value
&& !strcasecmp(value
, "lf"))
1669 else if (value
&& !strcasecmp(value
, "crlf"))
1670 core_eol
= EOL_CRLF
;
1671 else if (value
&& !strcasecmp(value
, "native"))
1672 core_eol
= EOL_NATIVE
;
1674 core_eol
= EOL_UNSET
;
1678 if (!strcmp(var
, "core.checkroundtripencoding")) {
1679 check_roundtrip_encoding
= xstrdup(value
);
1683 if (!strcmp(var
, "core.notesref")) {
1684 notes_ref_name
= xstrdup(value
);
1688 if (!strcmp(var
, "core.editor"))
1689 return git_config_string(&editor_program
, var
, value
);
1691 if (!strcmp(var
, "core.commentchar")) {
1693 return config_error_nonbool(var
);
1694 else if (!strcasecmp(value
, "auto"))
1695 auto_comment_line_char
= 1;
1696 else if (value
[0] && !value
[1]) {
1697 comment_line_char
= value
[0];
1698 auto_comment_line_char
= 0;
1700 return error(_("core.commentChar should only be one character"));
1704 if (!strcmp(var
, "core.askpass"))
1705 return git_config_string(&askpass_program
, var
, value
);
1707 if (!strcmp(var
, "core.excludesfile"))
1708 return git_config_pathname(&excludes_file
, var
, value
);
1710 if (!strcmp(var
, "core.whitespace")) {
1712 return config_error_nonbool(var
);
1713 whitespace_rule_cfg
= parse_whitespace_rule(value
);
1717 if (!strcmp(var
, "core.fsync")) {
1719 return config_error_nonbool(var
);
1720 fsync_components
= parse_fsync_components(var
, value
);
1724 if (!strcmp(var
, "core.fsyncmethod")) {
1726 return config_error_nonbool(var
);
1727 if (!strcmp(value
, "fsync"))
1728 fsync_method
= FSYNC_METHOD_FSYNC
;
1729 else if (!strcmp(value
, "writeout-only"))
1730 fsync_method
= FSYNC_METHOD_WRITEOUT_ONLY
;
1731 else if (!strcmp(value
, "batch"))
1732 fsync_method
= FSYNC_METHOD_BATCH
;
1734 warning(_("ignoring unknown core.fsyncMethod value '%s'"), value
);
1738 if (!strcmp(var
, "core.fsyncobjectfiles")) {
1739 if (fsync_object_files
< 0)
1740 warning(_("core.fsyncObjectFiles is deprecated; use core.fsync instead"));
1741 fsync_object_files
= git_config_bool(var
, value
);
1745 if (!strcmp(var
, "core.preloadindex")) {
1746 core_preload_index
= git_config_bool(var
, value
);
1750 if (!strcmp(var
, "core.createobject")) {
1751 if (!strcmp(value
, "rename"))
1752 object_creation_mode
= OBJECT_CREATION_USES_RENAMES
;
1753 else if (!strcmp(value
, "link"))
1754 object_creation_mode
= OBJECT_CREATION_USES_HARDLINKS
;
1756 die(_("invalid mode for object creation: %s"), value
);
1760 if (!strcmp(var
, "core.sparsecheckout")) {
1761 core_apply_sparse_checkout
= git_config_bool(var
, value
);
1765 if (!strcmp(var
, "core.sparsecheckoutcone")) {
1766 core_sparse_checkout_cone
= git_config_bool(var
, value
);
1770 if (!strcmp(var
, "core.precomposeunicode")) {
1771 precomposed_unicode
= git_config_bool(var
, value
);
1775 if (!strcmp(var
, "core.protecthfs")) {
1776 protect_hfs
= git_config_bool(var
, value
);
1780 if (!strcmp(var
, "core.protectntfs")) {
1781 protect_ntfs
= git_config_bool(var
, value
);
1785 if (!strcmp(var
, "core.usereplacerefs")) {
1786 read_replace_refs
= git_config_bool(var
, value
);
1790 /* Add other config variables here and to Documentation/config.txt. */
1791 return platform_core_config(var
, value
, cb
);
1794 static int git_default_sparse_config(const char *var
, const char *value
)
1796 if (!strcmp(var
, "sparse.expectfilesoutsideofpatterns")) {
1797 sparse_expect_files_outside_of_patterns
= git_config_bool(var
, value
);
1801 /* Add other config variables here and to Documentation/config/sparse.txt. */
1805 static int git_default_i18n_config(const char *var
, const char *value
)
1807 if (!strcmp(var
, "i18n.commitencoding"))
1808 return git_config_string(&git_commit_encoding
, var
, value
);
1810 if (!strcmp(var
, "i18n.logoutputencoding"))
1811 return git_config_string(&git_log_output_encoding
, var
, value
);
1813 /* Add other config variables here and to Documentation/config.txt. */
1817 static int git_default_branch_config(const char *var
, const char *value
)
1819 if (!strcmp(var
, "branch.autosetupmerge")) {
1820 if (value
&& !strcmp(value
, "always")) {
1821 git_branch_track
= BRANCH_TRACK_ALWAYS
;
1823 } else if (value
&& !strcmp(value
, "inherit")) {
1824 git_branch_track
= BRANCH_TRACK_INHERIT
;
1826 } else if (value
&& !strcmp(value
, "simple")) {
1827 git_branch_track
= BRANCH_TRACK_SIMPLE
;
1830 git_branch_track
= git_config_bool(var
, value
);
1833 if (!strcmp(var
, "branch.autosetuprebase")) {
1835 return config_error_nonbool(var
);
1836 else if (!strcmp(value
, "never"))
1837 autorebase
= AUTOREBASE_NEVER
;
1838 else if (!strcmp(value
, "local"))
1839 autorebase
= AUTOREBASE_LOCAL
;
1840 else if (!strcmp(value
, "remote"))
1841 autorebase
= AUTOREBASE_REMOTE
;
1842 else if (!strcmp(value
, "always"))
1843 autorebase
= AUTOREBASE_ALWAYS
;
1845 return error(_("malformed value for %s"), var
);
1849 /* Add other config variables here and to Documentation/config.txt. */
1853 static int git_default_push_config(const char *var
, const char *value
)
1855 if (!strcmp(var
, "push.default")) {
1857 return config_error_nonbool(var
);
1858 else if (!strcmp(value
, "nothing"))
1859 push_default
= PUSH_DEFAULT_NOTHING
;
1860 else if (!strcmp(value
, "matching"))
1861 push_default
= PUSH_DEFAULT_MATCHING
;
1862 else if (!strcmp(value
, "simple"))
1863 push_default
= PUSH_DEFAULT_SIMPLE
;
1864 else if (!strcmp(value
, "upstream"))
1865 push_default
= PUSH_DEFAULT_UPSTREAM
;
1866 else if (!strcmp(value
, "tracking")) /* deprecated */
1867 push_default
= PUSH_DEFAULT_UPSTREAM
;
1868 else if (!strcmp(value
, "current"))
1869 push_default
= PUSH_DEFAULT_CURRENT
;
1871 error(_("malformed value for %s: %s"), var
, value
);
1872 return error(_("must be one of nothing, matching, simple, "
1873 "upstream or current"));
1878 /* Add other config variables here and to Documentation/config.txt. */
1882 static int git_default_mailmap_config(const char *var
, const char *value
)
1884 if (!strcmp(var
, "mailmap.file"))
1885 return git_config_pathname(&git_mailmap_file
, var
, value
);
1886 if (!strcmp(var
, "mailmap.blob"))
1887 return git_config_string(&git_mailmap_blob
, var
, value
);
1889 /* Add other config variables here and to Documentation/config.txt. */
1893 int git_default_config(const char *var
, const char *value
, void *cb
)
1895 if (starts_with(var
, "core."))
1896 return git_default_core_config(var
, value
, cb
);
1898 if (starts_with(var
, "user.") ||
1899 starts_with(var
, "author.") ||
1900 starts_with(var
, "committer."))
1901 return git_ident_config(var
, value
, cb
);
1903 if (starts_with(var
, "i18n."))
1904 return git_default_i18n_config(var
, value
);
1906 if (starts_with(var
, "branch."))
1907 return git_default_branch_config(var
, value
);
1909 if (starts_with(var
, "push."))
1910 return git_default_push_config(var
, value
);
1912 if (starts_with(var
, "mailmap."))
1913 return git_default_mailmap_config(var
, value
);
1915 if (starts_with(var
, "advice.") || starts_with(var
, "color.advice"))
1916 return git_default_advice_config(var
, value
);
1918 if (!strcmp(var
, "pager.color") || !strcmp(var
, "color.pager")) {
1919 pager_use_color
= git_config_bool(var
,value
);
1923 if (!strcmp(var
, "pack.packsizelimit")) {
1924 pack_size_limit_cfg
= git_config_ulong(var
, value
);
1928 if (!strcmp(var
, "pack.compression")) {
1929 int level
= git_config_int(var
, value
);
1931 level
= Z_DEFAULT_COMPRESSION
;
1932 else if (level
< 0 || level
> Z_BEST_COMPRESSION
)
1933 die(_("bad pack compression level %d"), level
);
1934 pack_compression_level
= level
;
1935 pack_compression_seen
= 1;
1939 if (starts_with(var
, "sparse."))
1940 return git_default_sparse_config(var
, value
);
1942 /* Add other config variables here and to Documentation/config.txt. */
1947 * All source specific fields in the union, die_on_error, name and the callbacks
1948 * fgetc, ungetc, ftell of top need to be initialized before calling
1951 static int do_config_from(struct config_source
*top
, config_fn_t fn
, void *data
,
1952 const struct config_options
*opts
)
1956 /* push config-file parsing state stack */
1961 strbuf_init(&top
->value
, 1024);
1962 strbuf_init(&top
->var
, 1024);
1965 ret
= git_parse_source(fn
, data
, opts
);
1967 /* pop config-file parsing state stack */
1968 strbuf_release(&top
->value
);
1969 strbuf_release(&top
->var
);
1975 static int do_config_from_file(config_fn_t fn
,
1976 const enum config_origin_type origin_type
,
1977 const char *name
, const char *path
, FILE *f
,
1978 void *data
, const struct config_options
*opts
)
1980 struct config_source top
;
1984 top
.origin_type
= origin_type
;
1987 top
.default_error_action
= CONFIG_ERROR_DIE
;
1988 top
.do_fgetc
= config_file_fgetc
;
1989 top
.do_ungetc
= config_file_ungetc
;
1990 top
.do_ftell
= config_file_ftell
;
1993 ret
= do_config_from(&top
, fn
, data
, opts
);
1998 static int git_config_from_stdin(config_fn_t fn
, void *data
)
2000 return do_config_from_file(fn
, CONFIG_ORIGIN_STDIN
, "", NULL
, stdin
,
2004 int git_config_from_file_with_options(config_fn_t fn
, const char *filename
,
2006 const struct config_options
*opts
)
2012 BUG("filename cannot be NULL");
2013 f
= fopen_or_warn(filename
, "r");
2015 ret
= do_config_from_file(fn
, CONFIG_ORIGIN_FILE
, filename
,
2016 filename
, f
, data
, opts
);
2022 int git_config_from_file(config_fn_t fn
, const char *filename
, void *data
)
2024 return git_config_from_file_with_options(fn
, filename
, data
, NULL
);
2027 int git_config_from_mem(config_fn_t fn
,
2028 const enum config_origin_type origin_type
,
2029 const char *name
, const char *buf
, size_t len
,
2030 void *data
, const struct config_options
*opts
)
2032 struct config_source top
;
2034 top
.u
.buf
.buf
= buf
;
2035 top
.u
.buf
.len
= len
;
2037 top
.origin_type
= origin_type
;
2040 top
.default_error_action
= CONFIG_ERROR_ERROR
;
2041 top
.do_fgetc
= config_buf_fgetc
;
2042 top
.do_ungetc
= config_buf_ungetc
;
2043 top
.do_ftell
= config_buf_ftell
;
2045 return do_config_from(&top
, fn
, data
, opts
);
2048 int git_config_from_blob_oid(config_fn_t fn
,
2050 struct repository
*repo
,
2051 const struct object_id
*oid
,
2054 enum object_type type
;
2059 buf
= repo_read_object_file(repo
, oid
, &type
, &size
);
2061 return error(_("unable to load config blob object '%s'"), name
);
2062 if (type
!= OBJ_BLOB
) {
2064 return error(_("reference '%s' does not point to a blob"), name
);
2067 ret
= git_config_from_mem(fn
, CONFIG_ORIGIN_BLOB
, name
, buf
, size
,
2074 static int git_config_from_blob_ref(config_fn_t fn
,
2075 struct repository
*repo
,
2079 struct object_id oid
;
2081 if (repo_get_oid(repo
, name
, &oid
) < 0)
2082 return error(_("unable to resolve config blob '%s'"), name
);
2083 return git_config_from_blob_oid(fn
, name
, repo
, &oid
, data
);
2086 char *git_system_config(void)
2088 char *system_config
= xstrdup_or_null(getenv("GIT_CONFIG_SYSTEM"));
2090 system_config
= system_path(ETC_GITCONFIG
);
2091 normalize_path_copy(system_config
, system_config
);
2092 return system_config
;
2095 void git_global_config(char **user_out
, char **xdg_out
)
2097 char *user_config
= xstrdup_or_null(getenv("GIT_CONFIG_GLOBAL"));
2098 char *xdg_config
= NULL
;
2101 user_config
= interpolate_path("~/.gitconfig", 0);
2102 xdg_config
= xdg_config_home("config");
2105 *user_out
= user_config
;
2106 *xdg_out
= xdg_config
;
2110 * Parse environment variable 'k' as a boolean (in various
2111 * possible spellings); if missing, use the default value 'def'.
2113 int git_env_bool(const char *k
, int def
)
2115 const char *v
= getenv(k
);
2116 return v
? git_config_bool(k
, v
) : def
;
2120 * Parse environment variable 'k' as ulong with possibly a unit
2121 * suffix; if missing, use the default value 'val'.
2123 unsigned long git_env_ulong(const char *k
, unsigned long val
)
2125 const char *v
= getenv(k
);
2126 if (v
&& !git_parse_ulong(v
, &val
))
2127 die(_("failed to parse %s"), k
);
2131 int git_config_system(void)
2133 return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0);
2136 static int do_git_config_sequence(const struct config_options
*opts
,
2137 config_fn_t fn
, void *data
)
2140 char *system_config
= git_system_config();
2141 char *xdg_config
= NULL
;
2142 char *user_config
= NULL
;
2144 enum config_scope prev_parsing_scope
= current_parsing_scope
;
2146 if (opts
->commondir
)
2147 repo_config
= mkpathdup("%s/config", opts
->commondir
);
2148 else if (opts
->git_dir
)
2149 BUG("git_dir without commondir");
2153 current_parsing_scope
= CONFIG_SCOPE_SYSTEM
;
2154 if (git_config_system() && system_config
&&
2155 !access_or_die(system_config
, R_OK
,
2156 opts
->system_gently
? ACCESS_EACCES_OK
: 0))
2157 ret
+= git_config_from_file(fn
, system_config
, data
);
2159 current_parsing_scope
= CONFIG_SCOPE_GLOBAL
;
2160 git_global_config(&user_config
, &xdg_config
);
2162 if (xdg_config
&& !access_or_die(xdg_config
, R_OK
, ACCESS_EACCES_OK
))
2163 ret
+= git_config_from_file(fn
, xdg_config
, data
);
2165 if (user_config
&& !access_or_die(user_config
, R_OK
, ACCESS_EACCES_OK
))
2166 ret
+= git_config_from_file(fn
, user_config
, data
);
2168 current_parsing_scope
= CONFIG_SCOPE_LOCAL
;
2169 if (!opts
->ignore_repo
&& repo_config
&&
2170 !access_or_die(repo_config
, R_OK
, 0))
2171 ret
+= git_config_from_file(fn
, repo_config
, data
);
2173 current_parsing_scope
= CONFIG_SCOPE_WORKTREE
;
2174 if (!opts
->ignore_worktree
&& repository_format_worktree_config
) {
2175 char *path
= git_pathdup("config.worktree");
2176 if (!access_or_die(path
, R_OK
, 0))
2177 ret
+= git_config_from_file(fn
, path
, data
);
2181 current_parsing_scope
= CONFIG_SCOPE_COMMAND
;
2182 if (!opts
->ignore_cmdline
&& git_config_from_parameters(fn
, data
) < 0)
2183 die(_("unable to parse command-line config"));
2185 current_parsing_scope
= prev_parsing_scope
;
2186 free(system_config
);
2193 int config_with_options(config_fn_t fn
, void *data
,
2194 struct git_config_source
*config_source
,
2195 const struct config_options
*opts
)
2197 struct config_include_data inc
= CONFIG_INCLUDE_INIT
;
2200 if (opts
->respect_includes
) {
2204 inc
.config_source
= config_source
;
2205 fn
= git_config_include
;
2210 current_parsing_scope
= config_source
->scope
;
2213 * If we have a specific filename, use it. Otherwise, follow the
2214 * regular lookup sequence.
2216 if (config_source
&& config_source
->use_stdin
) {
2217 ret
= git_config_from_stdin(fn
, data
);
2218 } else if (config_source
&& config_source
->file
) {
2219 ret
= git_config_from_file(fn
, config_source
->file
, data
);
2220 } else if (config_source
&& config_source
->blob
) {
2221 struct repository
*repo
= config_source
->repo
?
2222 config_source
->repo
: the_repository
;
2223 ret
= git_config_from_blob_ref(fn
, repo
, config_source
->blob
,
2226 ret
= do_git_config_sequence(opts
, fn
, data
);
2229 if (inc
.remote_urls
) {
2230 string_list_clear(inc
.remote_urls
, 0);
2231 FREE_AND_NULL(inc
.remote_urls
);
2236 static void configset_iter(struct config_set
*cs
, config_fn_t fn
, void *data
)
2239 struct string_list
*values
;
2240 struct config_set_element
*entry
;
2241 struct configset_list
*list
= &cs
->list
;
2243 for (i
= 0; i
< list
->nr
; i
++) {
2244 entry
= list
->items
[i
].e
;
2245 value_index
= list
->items
[i
].value_index
;
2246 values
= &entry
->value_list
;
2248 current_config_kvi
= values
->items
[value_index
].util
;
2250 if (fn(entry
->key
, values
->items
[value_index
].string
, data
) < 0)
2251 git_die_config_linenr(entry
->key
,
2252 current_config_kvi
->filename
,
2253 current_config_kvi
->linenr
);
2255 current_config_kvi
= NULL
;
2259 void read_early_config(config_fn_t cb
, void *data
)
2261 struct config_options opts
= {0};
2262 struct strbuf commondir
= STRBUF_INIT
;
2263 struct strbuf gitdir
= STRBUF_INIT
;
2265 opts
.respect_includes
= 1;
2267 if (have_git_dir()) {
2268 opts
.commondir
= get_git_common_dir();
2269 opts
.git_dir
= get_git_dir();
2271 * When setup_git_directory() was not yet asked to discover the
2272 * GIT_DIR, we ask discover_git_directory() to figure out whether there
2273 * is any repository config we should use (but unlike
2274 * setup_git_directory_gently(), no global state is changed, most
2275 * notably, the current working directory is still the same after the
2278 } else if (!discover_git_directory(&commondir
, &gitdir
)) {
2279 opts
.commondir
= commondir
.buf
;
2280 opts
.git_dir
= gitdir
.buf
;
2283 config_with_options(cb
, data
, NULL
, &opts
);
2285 strbuf_release(&commondir
);
2286 strbuf_release(&gitdir
);
2290 * Read config but only enumerate system and global settings.
2291 * Omit any repo-local, worktree-local, or command-line settings.
2293 void read_very_early_config(config_fn_t cb
, void *data
)
2295 struct config_options opts
= { 0 };
2297 opts
.respect_includes
= 1;
2298 opts
.ignore_repo
= 1;
2299 opts
.ignore_worktree
= 1;
2300 opts
.ignore_cmdline
= 1;
2301 opts
.system_gently
= 1;
2303 config_with_options(cb
, data
, NULL
, &opts
);
2306 static struct config_set_element
*configset_find_element(struct config_set
*cs
, const char *key
)
2308 struct config_set_element k
;
2309 struct config_set_element
*found_entry
;
2310 char *normalized_key
;
2312 * `key` may come from the user, so normalize it before using it
2313 * for querying entries from the hashmap.
2315 if (git_config_parse_key(key
, &normalized_key
, NULL
))
2318 hashmap_entry_init(&k
.ent
, strhash(normalized_key
));
2319 k
.key
= normalized_key
;
2320 found_entry
= hashmap_get_entry(&cs
->config_hash
, &k
, ent
, NULL
);
2321 free(normalized_key
);
2325 static int configset_add_value(struct config_set
*cs
, const char *key
, const char *value
)
2327 struct config_set_element
*e
;
2328 struct string_list_item
*si
;
2329 struct configset_list_item
*l_item
;
2330 struct key_value_info
*kv_info
= xmalloc(sizeof(*kv_info
));
2332 e
= configset_find_element(cs
, key
);
2334 * Since the keys are being fed by git_config*() callback mechanism, they
2335 * are already normalized. So simply add them without any further munging.
2338 e
= xmalloc(sizeof(*e
));
2339 hashmap_entry_init(&e
->ent
, strhash(key
));
2340 e
->key
= xstrdup(key
);
2341 string_list_init_dup(&e
->value_list
);
2342 hashmap_add(&cs
->config_hash
, &e
->ent
);
2344 si
= string_list_append_nodup(&e
->value_list
, xstrdup_or_null(value
));
2346 ALLOC_GROW(cs
->list
.items
, cs
->list
.nr
+ 1, cs
->list
.alloc
);
2347 l_item
= &cs
->list
.items
[cs
->list
.nr
++];
2349 l_item
->value_index
= e
->value_list
.nr
- 1;
2352 BUG("configset_add_value has no source");
2354 kv_info
->filename
= strintern(cf
->name
);
2355 kv_info
->linenr
= cf
->linenr
;
2356 kv_info
->origin_type
= cf
->origin_type
;
2358 /* for values read from `git_config_from_parameters()` */
2359 kv_info
->filename
= NULL
;
2360 kv_info
->linenr
= -1;
2361 kv_info
->origin_type
= CONFIG_ORIGIN_CMDLINE
;
2363 kv_info
->scope
= current_parsing_scope
;
2369 static int config_set_element_cmp(const void *cmp_data UNUSED
,
2370 const struct hashmap_entry
*eptr
,
2371 const struct hashmap_entry
*entry_or_key
,
2372 const void *keydata UNUSED
)
2374 const struct config_set_element
*e1
, *e2
;
2376 e1
= container_of(eptr
, const struct config_set_element
, ent
);
2377 e2
= container_of(entry_or_key
, const struct config_set_element
, ent
);
2379 return strcmp(e1
->key
, e2
->key
);
2382 void git_configset_init(struct config_set
*cs
)
2384 hashmap_init(&cs
->config_hash
, config_set_element_cmp
, NULL
, 0);
2385 cs
->hash_initialized
= 1;
2388 cs
->list
.items
= NULL
;
2391 void git_configset_clear(struct config_set
*cs
)
2393 struct config_set_element
*entry
;
2394 struct hashmap_iter iter
;
2395 if (!cs
->hash_initialized
)
2398 hashmap_for_each_entry(&cs
->config_hash
, &iter
, entry
,
2399 ent
/* member name */) {
2401 string_list_clear(&entry
->value_list
, 1);
2403 hashmap_clear_and_free(&cs
->config_hash
, struct config_set_element
, ent
);
2404 cs
->hash_initialized
= 0;
2405 free(cs
->list
.items
);
2408 cs
->list
.items
= NULL
;
2411 static int config_set_callback(const char *key
, const char *value
, void *cb
)
2413 struct config_set
*cs
= cb
;
2414 configset_add_value(cs
, key
, value
);
2418 int git_configset_add_file(struct config_set
*cs
, const char *filename
)
2420 return git_config_from_file(config_set_callback
, filename
, cs
);
2423 int git_configset_get_value(struct config_set
*cs
, const char *key
, const char **value
)
2425 const struct string_list
*values
= NULL
;
2427 * Follows "last one wins" semantic, i.e., if there are multiple matches for the
2428 * queried key in the files of the configset, the value returned will be the last
2429 * value in the value list for that key.
2431 values
= git_configset_get_value_multi(cs
, key
);
2435 assert(values
->nr
> 0);
2436 *value
= values
->items
[values
->nr
- 1].string
;
2440 const struct string_list
*git_configset_get_value_multi(struct config_set
*cs
, const char *key
)
2442 struct config_set_element
*e
= configset_find_element(cs
, key
);
2443 return e
? &e
->value_list
: NULL
;
2446 int git_configset_get_string(struct config_set
*cs
, const char *key
, char **dest
)
2449 if (!git_configset_get_value(cs
, key
, &value
))
2450 return git_config_string((const char **)dest
, key
, value
);
2455 static int git_configset_get_string_tmp(struct config_set
*cs
, const char *key
,
2459 if (!git_configset_get_value(cs
, key
, &value
)) {
2461 return config_error_nonbool(key
);
2469 int git_configset_get_int(struct config_set
*cs
, const char *key
, int *dest
)
2472 if (!git_configset_get_value(cs
, key
, &value
)) {
2473 *dest
= git_config_int(key
, value
);
2479 int git_configset_get_ulong(struct config_set
*cs
, const char *key
, unsigned long *dest
)
2482 if (!git_configset_get_value(cs
, key
, &value
)) {
2483 *dest
= git_config_ulong(key
, value
);
2489 int git_configset_get_bool(struct config_set
*cs
, const char *key
, int *dest
)
2492 if (!git_configset_get_value(cs
, key
, &value
)) {
2493 *dest
= git_config_bool(key
, value
);
2499 int git_configset_get_bool_or_int(struct config_set
*cs
, const char *key
,
2500 int *is_bool
, int *dest
)
2503 if (!git_configset_get_value(cs
, key
, &value
)) {
2504 *dest
= git_config_bool_or_int(key
, value
, is_bool
);
2510 int git_configset_get_maybe_bool(struct config_set
*cs
, const char *key
, int *dest
)
2513 if (!git_configset_get_value(cs
, key
, &value
)) {
2514 *dest
= git_parse_maybe_bool(value
);
2522 int git_configset_get_pathname(struct config_set
*cs
, const char *key
, const char **dest
)
2525 if (!git_configset_get_value(cs
, key
, &value
))
2526 return git_config_pathname(dest
, key
, value
);
2531 /* Functions use to read configuration from a repository */
2532 static void repo_read_config(struct repository
*repo
)
2534 struct config_options opts
= { 0 };
2536 opts
.respect_includes
= 1;
2537 opts
.commondir
= repo
->commondir
;
2538 opts
.git_dir
= repo
->gitdir
;
2541 CALLOC_ARRAY(repo
->config
, 1);
2543 git_configset_clear(repo
->config
);
2545 git_configset_init(repo
->config
);
2547 if (config_with_options(config_set_callback
, repo
->config
, NULL
, &opts
) < 0)
2549 * config_with_options() normally returns only
2550 * zero, as most errors are fatal, and
2551 * non-fatal potential errors are guarded by "if"
2552 * statements that are entered only when no error is
2555 * If we ever encounter a non-fatal error, it means
2556 * something went really wrong and we should stop
2559 die(_("unknown error occurred while reading the configuration files"));
2562 static void git_config_check_init(struct repository
*repo
)
2564 if (repo
->config
&& repo
->config
->hash_initialized
)
2566 repo_read_config(repo
);
2569 static void repo_config_clear(struct repository
*repo
)
2571 if (!repo
->config
|| !repo
->config
->hash_initialized
)
2573 git_configset_clear(repo
->config
);
2576 void repo_config(struct repository
*repo
, config_fn_t fn
, void *data
)
2578 git_config_check_init(repo
);
2579 configset_iter(repo
->config
, fn
, data
);
2582 int repo_config_get_value(struct repository
*repo
,
2583 const char *key
, const char **value
)
2585 git_config_check_init(repo
);
2586 return git_configset_get_value(repo
->config
, key
, value
);
2589 const struct string_list
*repo_config_get_value_multi(struct repository
*repo
,
2592 git_config_check_init(repo
);
2593 return git_configset_get_value_multi(repo
->config
, key
);
2596 int repo_config_get_string(struct repository
*repo
,
2597 const char *key
, char **dest
)
2600 git_config_check_init(repo
);
2601 ret
= git_configset_get_string(repo
->config
, key
, dest
);
2603 git_die_config(key
, NULL
);
2607 int repo_config_get_string_tmp(struct repository
*repo
,
2608 const char *key
, const char **dest
)
2611 git_config_check_init(repo
);
2612 ret
= git_configset_get_string_tmp(repo
->config
, key
, dest
);
2614 git_die_config(key
, NULL
);
2618 int repo_config_get_int(struct repository
*repo
,
2619 const char *key
, int *dest
)
2621 git_config_check_init(repo
);
2622 return git_configset_get_int(repo
->config
, key
, dest
);
2625 int repo_config_get_ulong(struct repository
*repo
,
2626 const char *key
, unsigned long *dest
)
2628 git_config_check_init(repo
);
2629 return git_configset_get_ulong(repo
->config
, key
, dest
);
2632 int repo_config_get_bool(struct repository
*repo
,
2633 const char *key
, int *dest
)
2635 git_config_check_init(repo
);
2636 return git_configset_get_bool(repo
->config
, key
, dest
);
2639 int repo_config_get_bool_or_int(struct repository
*repo
,
2640 const char *key
, int *is_bool
, int *dest
)
2642 git_config_check_init(repo
);
2643 return git_configset_get_bool_or_int(repo
->config
, key
, is_bool
, dest
);
2646 int repo_config_get_maybe_bool(struct repository
*repo
,
2647 const char *key
, int *dest
)
2649 git_config_check_init(repo
);
2650 return git_configset_get_maybe_bool(repo
->config
, key
, dest
);
2653 int repo_config_get_pathname(struct repository
*repo
,
2654 const char *key
, const char **dest
)
2657 git_config_check_init(repo
);
2658 ret
= git_configset_get_pathname(repo
->config
, key
, dest
);
2660 git_die_config(key
, NULL
);
2664 /* Read values into protected_config. */
2665 static void read_protected_config(void)
2667 struct config_options opts
= {
2668 .respect_includes
= 1,
2670 .ignore_worktree
= 1,
2673 git_configset_init(&protected_config
);
2674 config_with_options(config_set_callback
, &protected_config
,
2678 void git_protected_config(config_fn_t fn
, void *data
)
2680 if (!protected_config
.hash_initialized
)
2681 read_protected_config();
2682 configset_iter(&protected_config
, fn
, data
);
2685 /* Functions used historically to read configuration from 'the_repository' */
2686 void git_config(config_fn_t fn
, void *data
)
2688 repo_config(the_repository
, fn
, data
);
2691 void git_config_clear(void)
2693 repo_config_clear(the_repository
);
2696 int git_config_get_value(const char *key
, const char **value
)
2698 return repo_config_get_value(the_repository
, key
, value
);
2701 const struct string_list
*git_config_get_value_multi(const char *key
)
2703 return repo_config_get_value_multi(the_repository
, key
);
2706 int git_config_get_string(const char *key
, char **dest
)
2708 return repo_config_get_string(the_repository
, key
, dest
);
2711 int git_config_get_string_tmp(const char *key
, const char **dest
)
2713 return repo_config_get_string_tmp(the_repository
, key
, dest
);
2716 int git_config_get_int(const char *key
, int *dest
)
2718 return repo_config_get_int(the_repository
, key
, dest
);
2721 int git_config_get_ulong(const char *key
, unsigned long *dest
)
2723 return repo_config_get_ulong(the_repository
, key
, dest
);
2726 int git_config_get_bool(const char *key
, int *dest
)
2728 return repo_config_get_bool(the_repository
, key
, dest
);
2731 int git_config_get_bool_or_int(const char *key
, int *is_bool
, int *dest
)
2733 return repo_config_get_bool_or_int(the_repository
, key
, is_bool
, dest
);
2736 int git_config_get_maybe_bool(const char *key
, int *dest
)
2738 return repo_config_get_maybe_bool(the_repository
, key
, dest
);
2741 int git_config_get_pathname(const char *key
, const char **dest
)
2743 return repo_config_get_pathname(the_repository
, key
, dest
);
2746 int git_config_get_expiry(const char *key
, const char **output
)
2748 int ret
= git_config_get_string(key
, (char **)output
);
2751 if (strcmp(*output
, "now")) {
2752 timestamp_t now
= approxidate("now");
2753 if (approxidate(*output
) >= now
)
2754 git_die_config(key
, _("Invalid %s: '%s'"), key
, *output
);
2759 int git_config_get_expiry_in_days(const char *key
, timestamp_t
*expiry
, timestamp_t now
)
2761 const char *expiry_string
;
2765 if (git_config_get_string_tmp(key
, &expiry_string
))
2766 return 1; /* no such thing */
2768 if (git_parse_signed(expiry_string
, &days
, maximum_signed_value_of_type(int))) {
2769 const int scale
= 86400;
2770 *expiry
= now
- days
* scale
;
2774 if (!parse_expiry_date(expiry_string
, &when
)) {
2778 return -1; /* thing exists but cannot be parsed */
2781 int git_config_get_split_index(void)
2785 if (!git_config_get_maybe_bool("core.splitindex", &val
))
2788 return -1; /* default value */
2791 int git_config_get_max_percent_split_change(void)
2795 if (!git_config_get_int("splitindex.maxpercentchange", &val
)) {
2796 if (0 <= val
&& val
<= 100)
2799 return error(_("splitIndex.maxPercentChange value '%d' "
2800 "should be between 0 and 100"), val
);
2803 return -1; /* default value */
2806 int git_config_get_index_threads(int *dest
)
2810 val
= git_env_ulong("GIT_TEST_INDEX_THREADS", 0);
2816 if (!git_config_get_bool_or_int("index.threads", &is_bool
, &val
)) {
2818 *dest
= val
? 0 : 1;
2828 void git_die_config_linenr(const char *key
, const char *filename
, int linenr
)
2831 die(_("unable to parse '%s' from command-line config"), key
);
2833 die(_("bad config variable '%s' in file '%s' at line %d"),
2834 key
, filename
, linenr
);
2837 NORETURN
__attribute__((format(printf
, 2, 3)))
2838 void git_die_config(const char *key
, const char *err
, ...)
2840 const struct string_list
*values
;
2841 struct key_value_info
*kv_info
;
2842 report_fn error_fn
= get_error_routine();
2846 va_start(params
, err
);
2847 error_fn(err
, params
);
2850 values
= git_config_get_value_multi(key
);
2851 kv_info
= values
->items
[values
->nr
- 1].util
;
2852 git_die_config_linenr(key
, kv_info
->filename
, kv_info
->linenr
);
2856 * Find all the stuff for git_config_set() below.
2859 struct config_store_data
{
2863 const char *fixed_value
;
2864 regex_t
*value_pattern
;
2868 enum config_event_t type
;
2869 int is_keys_section
;
2871 unsigned int parsed_nr
, parsed_alloc
, *seen
, seen_nr
, seen_alloc
;
2872 unsigned int key_seen
:1, section_seen
:1, is_keys_section
:1;
2875 static void config_store_data_clear(struct config_store_data
*store
)
2878 if (store
->value_pattern
!= NULL
&&
2879 store
->value_pattern
!= CONFIG_REGEX_NONE
) {
2880 regfree(store
->value_pattern
);
2881 free(store
->value_pattern
);
2883 free(store
->parsed
);
2885 memset(store
, 0, sizeof(*store
));
2888 static int matches(const char *key
, const char *value
,
2889 const struct config_store_data
*store
)
2891 if (strcmp(key
, store
->key
))
2892 return 0; /* not ours */
2893 if (store
->fixed_value
)
2894 return !strcmp(store
->fixed_value
, value
);
2895 if (!store
->value_pattern
)
2896 return 1; /* always matches */
2897 if (store
->value_pattern
== CONFIG_REGEX_NONE
)
2898 return 0; /* never matches */
2900 return store
->do_not_match
^
2901 (value
&& !regexec(store
->value_pattern
, value
, 0, NULL
, 0));
2904 static int store_aux_event(enum config_event_t type
,
2905 size_t begin
, size_t end
, void *data
)
2907 struct config_store_data
*store
= data
;
2909 ALLOC_GROW(store
->parsed
, store
->parsed_nr
+ 1, store
->parsed_alloc
);
2910 store
->parsed
[store
->parsed_nr
].begin
= begin
;
2911 store
->parsed
[store
->parsed_nr
].end
= end
;
2912 store
->parsed
[store
->parsed_nr
].type
= type
;
2914 if (type
== CONFIG_EVENT_SECTION
) {
2915 int (*cmpfn
)(const char *, const char *, size_t);
2917 if (cf
->var
.len
< 2 || cf
->var
.buf
[cf
->var
.len
- 1] != '.')
2918 return error(_("invalid section name '%s'"), cf
->var
.buf
);
2920 if (cf
->subsection_case_sensitive
)
2921 cmpfn
= strncasecmp
;
2925 /* Is this the section we were looking for? */
2926 store
->is_keys_section
=
2927 store
->parsed
[store
->parsed_nr
].is_keys_section
=
2928 cf
->var
.len
- 1 == store
->baselen
&&
2929 !cmpfn(cf
->var
.buf
, store
->key
, store
->baselen
);
2930 if (store
->is_keys_section
) {
2931 store
->section_seen
= 1;
2932 ALLOC_GROW(store
->seen
, store
->seen_nr
+ 1,
2934 store
->seen
[store
->seen_nr
] = store
->parsed_nr
;
2943 static int store_aux(const char *key
, const char *value
, void *cb
)
2945 struct config_store_data
*store
= cb
;
2947 if (store
->key_seen
) {
2948 if (matches(key
, value
, store
)) {
2949 if (store
->seen_nr
== 1 && store
->multi_replace
== 0) {
2950 warning(_("%s has multiple values"), key
);
2953 ALLOC_GROW(store
->seen
, store
->seen_nr
+ 1,
2956 store
->seen
[store
->seen_nr
] = store
->parsed_nr
;
2959 } else if (store
->is_keys_section
) {
2961 * Do not increment matches yet: this may not be a match, but we
2962 * are in the desired section.
2964 ALLOC_GROW(store
->seen
, store
->seen_nr
+ 1, store
->seen_alloc
);
2965 store
->seen
[store
->seen_nr
] = store
->parsed_nr
;
2966 store
->section_seen
= 1;
2968 if (matches(key
, value
, store
)) {
2970 store
->key_seen
= 1;
2977 static int write_error(const char *filename
)
2979 error(_("failed to write new configuration file %s"), filename
);
2981 /* Same error code as "failed to rename". */
2985 static struct strbuf
store_create_section(const char *key
,
2986 const struct config_store_data
*store
)
2990 struct strbuf sb
= STRBUF_INIT
;
2992 dot
= memchr(key
, '.', store
->baselen
);
2994 strbuf_addf(&sb
, "[%.*s \"", (int)(dot
- key
), key
);
2995 for (i
= dot
- key
+ 1; i
< store
->baselen
; i
++) {
2996 if (key
[i
] == '"' || key
[i
] == '\\')
2997 strbuf_addch(&sb
, '\\');
2998 strbuf_addch(&sb
, key
[i
]);
3000 strbuf_addstr(&sb
, "\"]\n");
3002 strbuf_addch(&sb
, '[');
3003 strbuf_add(&sb
, key
, store
->baselen
);
3004 strbuf_addstr(&sb
, "]\n");
3010 static ssize_t
write_section(int fd
, const char *key
,
3011 const struct config_store_data
*store
)
3013 struct strbuf sb
= store_create_section(key
, store
);
3016 ret
= write_in_full(fd
, sb
.buf
, sb
.len
);
3017 strbuf_release(&sb
);
3022 static ssize_t
write_pair(int fd
, const char *key
, const char *value
,
3023 const struct config_store_data
*store
)
3027 const char *quote
= "";
3028 struct strbuf sb
= STRBUF_INIT
;
3031 * Check to see if the value needs to be surrounded with a dq pair.
3032 * Note that problematic characters are always backslash-quoted; this
3033 * check is about not losing leading or trailing SP and strings that
3034 * follow beginning-of-comment characters (i.e. ';' and '#') by the
3035 * configuration parser.
3037 if (value
[0] == ' ')
3039 for (i
= 0; value
[i
]; i
++)
3040 if (value
[i
] == ';' || value
[i
] == '#')
3042 if (i
&& value
[i
- 1] == ' ')
3045 strbuf_addf(&sb
, "\t%s = %s", key
+ store
->baselen
+ 1, quote
);
3047 for (i
= 0; value
[i
]; i
++)
3050 strbuf_addstr(&sb
, "\\n");
3053 strbuf_addstr(&sb
, "\\t");
3057 strbuf_addch(&sb
, '\\');
3060 strbuf_addch(&sb
, value
[i
]);
3063 strbuf_addf(&sb
, "%s\n", quote
);
3065 ret
= write_in_full(fd
, sb
.buf
, sb
.len
);
3066 strbuf_release(&sb
);
3072 * If we are about to unset the last key(s) in a section, and if there are
3073 * no comments surrounding (or included in) the section, we will want to
3074 * extend begin/end to remove the entire section.
3076 * Note: the parameter `seen_ptr` points to the index into the store.seen
3077 * array. * This index may be incremented if a section has more than one
3078 * entry (which all are to be removed).
3080 static void maybe_remove_section(struct config_store_data
*store
,
3081 size_t *begin_offset
, size_t *end_offset
,
3085 int i
, seen
, section_seen
= 0;
3088 * First, ensure that this is the first key, and that there are no
3089 * comments before the entry nor before the section header.
3092 for (i
= store
->seen
[seen
]; i
> 0; i
--) {
3093 enum config_event_t type
= store
->parsed
[i
- 1].type
;
3095 if (type
== CONFIG_EVENT_COMMENT
)
3096 /* There is a comment before this entry or section */
3098 if (type
== CONFIG_EVENT_ENTRY
) {
3100 /* This is not the section's first entry. */
3102 /* We encountered no comment before the section. */
3105 if (type
== CONFIG_EVENT_SECTION
) {
3106 if (!store
->parsed
[i
- 1].is_keys_section
)
3111 begin
= store
->parsed
[i
].begin
;
3114 * Next, make sure that we are removing the last key(s) in the section,
3115 * and that there are no comments that are possibly about the current
3118 for (i
= store
->seen
[seen
] + 1; i
< store
->parsed_nr
; i
++) {
3119 enum config_event_t type
= store
->parsed
[i
].type
;
3121 if (type
== CONFIG_EVENT_COMMENT
)
3123 if (type
== CONFIG_EVENT_SECTION
) {
3124 if (store
->parsed
[i
].is_keys_section
)
3128 if (type
== CONFIG_EVENT_ENTRY
) {
3129 if (++seen
< store
->seen_nr
&&
3130 i
== store
->seen
[seen
])
3131 /* We want to remove this entry, too */
3133 /* There is another entry in this section. */
3139 * We are really removing the last entry/entries from this section, and
3140 * there are no enclosed or surrounding comments. Remove the entire,
3141 * now-empty section.
3144 *begin_offset
= begin
;
3145 if (i
< store
->parsed_nr
)
3146 *end_offset
= store
->parsed
[i
].begin
;
3148 *end_offset
= store
->parsed
[store
->parsed_nr
- 1].end
;
3151 int git_config_set_in_file_gently(const char *config_filename
,
3152 const char *key
, const char *value
)
3154 return git_config_set_multivar_in_file_gently(config_filename
, key
, value
, NULL
, 0);
3157 void git_config_set_in_file(const char *config_filename
,
3158 const char *key
, const char *value
)
3160 git_config_set_multivar_in_file(config_filename
, key
, value
, NULL
, 0);
3163 int git_config_set_gently(const char *key
, const char *value
)
3165 return git_config_set_multivar_gently(key
, value
, NULL
, 0);
3168 int repo_config_set_worktree_gently(struct repository
*r
,
3169 const char *key
, const char *value
)
3171 /* Only use worktree-specific config if it is already enabled. */
3172 if (repository_format_worktree_config
) {
3173 char *file
= repo_git_path(r
, "config.worktree");
3174 int ret
= git_config_set_multivar_in_file_gently(
3175 file
, key
, value
, NULL
, 0);
3179 return repo_config_set_multivar_gently(r
, key
, value
, NULL
, 0);
3182 void git_config_set(const char *key
, const char *value
)
3184 git_config_set_multivar(key
, value
, NULL
, 0);
3186 trace2_cmd_set_config(key
, value
);
3190 * If value==NULL, unset in (remove from) config,
3191 * if value_pattern!=NULL, disregard key/value pairs where value does not match.
3192 * if value_pattern==CONFIG_REGEX_NONE, do not match any existing values
3193 * (only add a new one)
3194 * if flags contains the CONFIG_FLAGS_MULTI_REPLACE flag, all matching
3195 * key/values are removed before a single new pair is written. If the
3196 * flag is not present, then replace only the first match.
3198 * Returns 0 on success.
3200 * This function does this:
3202 * - it locks the config file by creating ".git/config.lock"
3204 * - it then parses the config using store_aux() as validator to find
3205 * the position on the key/value pair to replace. If it is to be unset,
3206 * it must be found exactly once.
3208 * - the config file is mmap()ed and the part before the match (if any) is
3209 * written to the lock file, then the changed part and the rest.
3211 * - the config file is removed and the lock file rename()d to it.
3214 int git_config_set_multivar_in_file_gently(const char *config_filename
,
3215 const char *key
, const char *value
,
3216 const char *value_pattern
,
3219 int fd
= -1, in_fd
= -1;
3221 struct lock_file lock
= LOCK_INIT
;
3222 char *filename_buf
= NULL
;
3223 char *contents
= NULL
;
3225 struct config_store_data store
;
3227 memset(&store
, 0, sizeof(store
));
3229 /* parse-key returns negative; flip the sign to feed exit(3) */
3230 ret
= 0 - git_config_parse_key(key
, &store
.key
, &store
.baselen
);
3234 store
.multi_replace
= (flags
& CONFIG_FLAGS_MULTI_REPLACE
) != 0;
3236 if (!config_filename
)
3237 config_filename
= filename_buf
= git_pathdup("config");
3240 * The lock serves a purpose in addition to locking: the new
3241 * contents of .git/config will be written into it.
3243 fd
= hold_lock_file_for_update(&lock
, config_filename
, 0);
3245 error_errno(_("could not lock config file %s"), config_filename
);
3246 ret
= CONFIG_NO_LOCK
;
3251 * If .git/config does not exist yet, write a minimal version.
3253 in_fd
= open(config_filename
, O_RDONLY
);
3255 if ( ENOENT
!= errno
) {
3256 error_errno(_("opening %s"), config_filename
);
3257 ret
= CONFIG_INVALID_FILE
; /* same as "invalid config file" */
3260 /* if nothing to unset, error out */
3262 ret
= CONFIG_NOTHING_SET
;
3267 store
.key
= xstrdup(key
);
3268 if (write_section(fd
, key
, &store
) < 0 ||
3269 write_pair(fd
, key
, value
, &store
) < 0)
3273 size_t copy_begin
, copy_end
;
3274 int i
, new_line
= 0;
3275 struct config_options opts
;
3278 store
.value_pattern
= NULL
;
3279 else if (value_pattern
== CONFIG_REGEX_NONE
)
3280 store
.value_pattern
= CONFIG_REGEX_NONE
;
3281 else if (flags
& CONFIG_FLAGS_FIXED_VALUE
)
3282 store
.fixed_value
= value_pattern
;
3284 if (value_pattern
[0] == '!') {
3285 store
.do_not_match
= 1;
3288 store
.do_not_match
= 0;
3290 store
.value_pattern
= (regex_t
*)xmalloc(sizeof(regex_t
));
3291 if (regcomp(store
.value_pattern
, value_pattern
,
3293 error(_("invalid pattern: %s"), value_pattern
);
3294 FREE_AND_NULL(store
.value_pattern
);
3295 ret
= CONFIG_INVALID_PATTERN
;
3300 ALLOC_GROW(store
.parsed
, 1, store
.parsed_alloc
);
3301 store
.parsed
[0].end
= 0;
3303 memset(&opts
, 0, sizeof(opts
));
3304 opts
.event_fn
= store_aux_event
;
3305 opts
.event_fn_data
= &store
;
3308 * After this, store.parsed will contain offsets of all the
3309 * parsed elements, and store.seen will contain a list of
3310 * matches, as indices into store.parsed.
3312 * As a side effect, we make sure to transform only a valid
3313 * existing config file.
3315 if (git_config_from_file_with_options(store_aux
,
3318 error(_("invalid config file %s"), config_filename
);
3319 ret
= CONFIG_INVALID_FILE
;
3323 /* if nothing to unset, or too many matches, error out */
3324 if ((store
.seen_nr
== 0 && value
== NULL
) ||
3325 (store
.seen_nr
> 1 && !store
.multi_replace
)) {
3326 ret
= CONFIG_NOTHING_SET
;
3330 if (fstat(in_fd
, &st
) == -1) {
3331 error_errno(_("fstat on %s failed"), config_filename
);
3332 ret
= CONFIG_INVALID_FILE
;
3336 contents_sz
= xsize_t(st
.st_size
);
3337 contents
= xmmap_gently(NULL
, contents_sz
, PROT_READ
,
3338 MAP_PRIVATE
, in_fd
, 0);
3339 if (contents
== MAP_FAILED
) {
3340 if (errno
== ENODEV
&& S_ISDIR(st
.st_mode
))
3342 error_errno(_("unable to mmap '%s'%s"),
3343 config_filename
, mmap_os_err());
3344 ret
= CONFIG_INVALID_FILE
;
3351 if (chmod(get_lock_file_path(&lock
), st
.st_mode
& 07777) < 0) {
3352 error_errno(_("chmod on %s failed"), get_lock_file_path(&lock
));
3353 ret
= CONFIG_NO_WRITE
;
3357 if (store
.seen_nr
== 0) {
3358 if (!store
.seen_alloc
) {
3359 /* Did not see key nor section */
3360 ALLOC_GROW(store
.seen
, 1, store
.seen_alloc
);
3361 store
.seen
[0] = store
.parsed_nr
3362 - !!store
.parsed_nr
;
3367 for (i
= 0, copy_begin
= 0; i
< store
.seen_nr
; i
++) {
3369 int j
= store
.seen
[i
];
3372 if (!store
.key_seen
) {
3373 copy_end
= store
.parsed
[j
].end
;
3374 /* include '\n' when copying section header */
3375 if (copy_end
> 0 && copy_end
< contents_sz
&&
3376 contents
[copy_end
- 1] != '\n' &&
3377 contents
[copy_end
] == '\n')
3379 replace_end
= copy_end
;
3381 replace_end
= store
.parsed
[j
].end
;
3382 copy_end
= store
.parsed
[j
].begin
;
3384 maybe_remove_section(&store
,
3388 * Swallow preceding white-space on the same
3391 while (copy_end
> 0 ) {
3392 char c
= contents
[copy_end
- 1];
3394 if (isspace(c
) && c
!= '\n')
3401 if (copy_end
> 0 && contents
[copy_end
-1] != '\n')
3404 /* write the first part of the config */
3405 if (copy_end
> copy_begin
) {
3406 if (write_in_full(fd
, contents
+ copy_begin
,
3407 copy_end
- copy_begin
) < 0)
3410 write_str_in_full(fd
, "\n") < 0)
3413 copy_begin
= replace_end
;
3416 /* write the pair (value == NULL means unset) */
3418 if (!store
.section_seen
) {
3419 if (write_section(fd
, key
, &store
) < 0)
3422 if (write_pair(fd
, key
, value
, &store
) < 0)
3426 /* write the rest of the config */
3427 if (copy_begin
< contents_sz
)
3428 if (write_in_full(fd
, contents
+ copy_begin
,
3429 contents_sz
- copy_begin
) < 0)
3432 munmap(contents
, contents_sz
);
3436 if (commit_lock_file(&lock
) < 0) {
3437 error_errno(_("could not write config file %s"), config_filename
);
3438 ret
= CONFIG_NO_WRITE
;
3444 /* Invalidate the config cache */
3448 rollback_lock_file(&lock
);
3451 munmap(contents
, contents_sz
);
3454 config_store_data_clear(&store
);
3458 ret
= write_error(get_lock_file_path(&lock
));
3463 void git_config_set_multivar_in_file(const char *config_filename
,
3464 const char *key
, const char *value
,
3465 const char *value_pattern
, unsigned flags
)
3467 if (!git_config_set_multivar_in_file_gently(config_filename
, key
, value
,
3468 value_pattern
, flags
))
3471 die(_("could not set '%s' to '%s'"), key
, value
);
3473 die(_("could not unset '%s'"), key
);
3476 int git_config_set_multivar_gently(const char *key
, const char *value
,
3477 const char *value_pattern
, unsigned flags
)
3479 return repo_config_set_multivar_gently(the_repository
, key
, value
,
3480 value_pattern
, flags
);
3483 int repo_config_set_multivar_gently(struct repository
*r
, const char *key
,
3485 const char *value_pattern
, unsigned flags
)
3487 char *file
= repo_git_path(r
, "config");
3488 int res
= git_config_set_multivar_in_file_gently(file
,
3496 void git_config_set_multivar(const char *key
, const char *value
,
3497 const char *value_pattern
, unsigned flags
)
3499 git_config_set_multivar_in_file(git_path("config"),
3500 key
, value
, value_pattern
,
3504 static int section_name_match (const char *buf
, const char *name
)
3506 int i
= 0, j
= 0, dot
= 0;
3509 for (i
= 1; buf
[i
] && buf
[i
] != ']'; i
++) {
3510 if (!dot
&& isspace(buf
[i
])) {
3512 if (name
[j
++] != '.')
3514 for (i
++; isspace(buf
[i
]); i
++)
3520 if (buf
[i
] == '\\' && dot
)
3522 else if (buf
[i
] == '"' && dot
) {
3523 for (i
++; isspace(buf
[i
]); i
++)
3527 if (buf
[i
] != name
[j
++])
3530 if (buf
[i
] == ']' && name
[j
] == 0) {
3532 * We match, now just find the right length offset by
3533 * gobbling up any whitespace after it, as well
3536 for (; buf
[i
] && isspace(buf
[i
]); i
++)
3543 static int section_name_is_ok(const char *name
)
3545 /* Empty section names are bogus. */
3550 * Before a dot, we must be alphanumeric or dash. After the first dot,
3551 * anything goes, so we can stop checking.
3553 for (; *name
&& *name
!= '.'; name
++)
3554 if (*name
!= '-' && !isalnum(*name
))
3559 /* if new_name == NULL, the section is removed instead */
3560 static int git_config_copy_or_rename_section_in_file(const char *config_filename
,
3561 const char *old_name
,
3562 const char *new_name
, int copy
)
3564 int ret
= 0, remove
= 0;
3565 char *filename_buf
= NULL
;
3566 struct lock_file lock
= LOCK_INIT
;
3569 FILE *config_file
= NULL
;
3571 struct strbuf copystr
= STRBUF_INIT
;
3572 struct config_store_data store
;
3574 memset(&store
, 0, sizeof(store
));
3576 if (new_name
&& !section_name_is_ok(new_name
)) {
3577 ret
= error(_("invalid section name: %s"), new_name
);
3578 goto out_no_rollback
;
3581 if (!config_filename
)
3582 config_filename
= filename_buf
= git_pathdup("config");
3584 out_fd
= hold_lock_file_for_update(&lock
, config_filename
, 0);
3586 ret
= error(_("could not lock config file %s"), config_filename
);
3590 if (!(config_file
= fopen(config_filename
, "rb"))) {
3591 ret
= warn_on_fopen_errors(config_filename
);
3594 /* no config file means nothing to rename, no error */
3595 goto commit_and_out
;
3598 if (fstat(fileno(config_file
), &st
) == -1) {
3599 ret
= error_errno(_("fstat on %s failed"), config_filename
);
3603 if (chmod(get_lock_file_path(&lock
), st
.st_mode
& 07777) < 0) {
3604 ret
= error_errno(_("chmod on %s failed"),
3605 get_lock_file_path(&lock
));
3609 while (fgets(buf
, sizeof(buf
), config_file
)) {
3614 for (i
= 0; buf
[i
] && isspace(buf
[i
]); i
++)
3616 if (buf
[i
] == '[') {
3617 /* it's a section */
3622 * When encountering a new section under -c we
3623 * need to flush out any section we're already
3624 * coping and begin anew. There might be
3625 * multiple [branch "$name"] sections.
3627 if (copystr
.len
> 0) {
3628 if (write_in_full(out_fd
, copystr
.buf
, copystr
.len
) < 0) {
3629 ret
= write_error(get_lock_file_path(&lock
));
3632 strbuf_reset(©str
);
3635 offset
= section_name_match(&buf
[i
], old_name
);
3642 store
.baselen
= strlen(new_name
);
3644 if (write_section(out_fd
, new_name
, &store
) < 0) {
3645 ret
= write_error(get_lock_file_path(&lock
));
3649 * We wrote out the new section, with
3650 * a newline, now skip the old
3653 output
+= offset
+ i
;
3654 if (strlen(output
) > 0) {
3656 * More content means there's
3657 * a declaration to put on the
3658 * next line; indent with a
3665 copystr
= store_create_section(new_name
, &store
);
3672 length
= strlen(output
);
3674 if (!is_section
&& copystr
.len
> 0) {
3675 strbuf_add(©str
, output
, length
);
3678 if (write_in_full(out_fd
, output
, length
) < 0) {
3679 ret
= write_error(get_lock_file_path(&lock
));
3685 * Copy a trailing section at the end of the config, won't be
3686 * flushed by the usual "flush because we have a new section
3687 * logic in the loop above.
3689 if (copystr
.len
> 0) {
3690 if (write_in_full(out_fd
, copystr
.buf
, copystr
.len
) < 0) {
3691 ret
= write_error(get_lock_file_path(&lock
));
3694 strbuf_reset(©str
);
3697 fclose(config_file
);
3700 if (commit_lock_file(&lock
) < 0)
3701 ret
= error_errno(_("could not write config file %s"),
3705 fclose(config_file
);
3706 rollback_lock_file(&lock
);
3709 config_store_data_clear(&store
);
3713 int git_config_rename_section_in_file(const char *config_filename
,
3714 const char *old_name
, const char *new_name
)
3716 return git_config_copy_or_rename_section_in_file(config_filename
,
3717 old_name
, new_name
, 0);
3720 int git_config_rename_section(const char *old_name
, const char *new_name
)
3722 return git_config_rename_section_in_file(NULL
, old_name
, new_name
);
3725 int git_config_copy_section_in_file(const char *config_filename
,
3726 const char *old_name
, const char *new_name
)
3728 return git_config_copy_or_rename_section_in_file(config_filename
,
3729 old_name
, new_name
, 1);
3732 int git_config_copy_section(const char *old_name
, const char *new_name
)
3734 return git_config_copy_section_in_file(NULL
, old_name
, new_name
);
3738 * Call this to report error for your variable that should not
3739 * get a boolean value (i.e. "[my] var" means "true").
3741 #undef config_error_nonbool
3742 int config_error_nonbool(const char *var
)
3744 return error(_("missing value for '%s'"), var
);
3747 int parse_config_key(const char *var
,
3748 const char *section
,
3749 const char **subsection
, size_t *subsection_len
,
3754 /* Does it start with "section." ? */
3755 if (!skip_prefix(var
, section
, &var
) || *var
!= '.')
3759 * Find the key; we don't know yet if we have a subsection, but we must
3760 * parse backwards from the end, since the subsection may have dots in
3763 dot
= strrchr(var
, '.');
3766 /* Did we have a subsection at all? */
3770 *subsection_len
= 0;
3776 *subsection
= var
+ 1;
3777 *subsection_len
= dot
- *subsection
;
3783 const char *current_config_origin_type(void)
3786 if (current_config_kvi
)
3787 type
= current_config_kvi
->origin_type
;
3789 type
= cf
->origin_type
;
3791 BUG("current_config_origin_type called outside config callback");
3794 case CONFIG_ORIGIN_BLOB
:
3796 case CONFIG_ORIGIN_FILE
:
3798 case CONFIG_ORIGIN_STDIN
:
3799 return "standard input";
3800 case CONFIG_ORIGIN_SUBMODULE_BLOB
:
3801 return "submodule-blob";
3802 case CONFIG_ORIGIN_CMDLINE
:
3803 return "command line";
3805 BUG("unknown config origin type");
3809 const char *config_scope_name(enum config_scope scope
)
3812 case CONFIG_SCOPE_SYSTEM
:
3814 case CONFIG_SCOPE_GLOBAL
:
3816 case CONFIG_SCOPE_LOCAL
:
3818 case CONFIG_SCOPE_WORKTREE
:
3820 case CONFIG_SCOPE_COMMAND
:
3822 case CONFIG_SCOPE_SUBMODULE
:
3829 const char *current_config_name(void)
3832 if (current_config_kvi
)
3833 name
= current_config_kvi
->filename
;
3837 BUG("current_config_name called outside config callback");
3838 return name
? name
: "";
3841 enum config_scope
current_config_scope(void)
3843 if (current_config_kvi
)
3844 return current_config_kvi
->scope
;
3846 return current_parsing_scope
;
3849 int current_config_line(void)
3851 if (current_config_kvi
)
3852 return current_config_kvi
->linenr
;
3857 int lookup_config(const char **mapping
, int nr_mapping
, const char *var
)
3861 for (i
= 0; i
< nr_mapping
; i
++) {
3862 const char *name
= mapping
[i
];
3864 if (name
&& !strcasecmp(var
, name
))