Git fork
1/*
2 * We put all the git config variables in this same object
3 * file, so that programs can link against the config parser
4 * without having to link against all the rest of git.
5 *
6 * In particular, no need to bring in libz etc unless needed,
7 * even if you might want to know where the git directory etc
8 * are.
9 */
10
11#define USE_THE_REPOSITORY_VARIABLE
12
13#include "git-compat-util.h"
14#include "abspath.h"
15#include "advice.h"
16#include "attr.h"
17#include "branch.h"
18#include "color.h"
19#include "convert.h"
20#include "environment.h"
21#include "gettext.h"
22#include "git-zlib.h"
23#include "ident.h"
24#include "mailmap.h"
25#include "object-name.h"
26#include "repository.h"
27#include "config.h"
28#include "refs.h"
29#include "fmt-merge-msg.h"
30#include "commit.h"
31#include "strvec.h"
32#include "pager.h"
33#include "path.h"
34#include "quote.h"
35#include "chdir-notify.h"
36#include "setup.h"
37#include "ws.h"
38#include "write-or-die.h"
39
40static int pack_compression_seen;
41static int zlib_compression_seen;
42
43int trust_executable_bit = 1;
44int trust_ctime = 1;
45int check_stat = 1;
46int has_symlinks = 1;
47int minimum_abbrev = 4, default_abbrev = -1;
48int ignore_case;
49int assume_unchanged;
50int is_bare_repository_cfg = -1; /* unspecified */
51int warn_on_object_refname_ambiguity = 1;
52char *git_commit_encoding;
53char *git_log_output_encoding;
54char *apply_default_whitespace;
55char *apply_default_ignorewhitespace;
56char *git_attributes_file;
57int zlib_compression_level = Z_BEST_SPEED;
58int pack_compression_level = Z_DEFAULT_COMPRESSION;
59int fsync_object_files = -1;
60int use_fsync = -1;
61enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT;
62enum fsync_component fsync_components = FSYNC_COMPONENTS_DEFAULT;
63char *editor_program;
64char *askpass_program;
65char *excludes_file;
66enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
67enum eol core_eol = EOL_UNSET;
68int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN;
69char *check_roundtrip_encoding;
70enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
71enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
72enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
73#ifndef OBJECT_CREATION_MODE
74#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
75#endif
76enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
77int grafts_keep_true_parents;
78int core_apply_sparse_checkout;
79int core_sparse_checkout_cone;
80int sparse_expect_files_outside_of_patterns;
81int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
82unsigned long pack_size_limit_cfg;
83int max_allowed_tree_depth =
84#ifdef _MSC_VER
85 /*
86 * When traversing into too-deep trees, Visual C-compiled Git seems to
87 * run into some internal stack overflow detection in the
88 * `RtlpAllocateHeap()` function that is called from within
89 * `git_inflate_init()`'s call tree. The following value seems to be
90 * low enough to avoid that by letting Git exit with an error before
91 * the stack overflow can occur.
92 */
93 512;
94#elif defined(GIT_WINDOWS_NATIVE) && defined(__clang__) && defined(__aarch64__)
95 /*
96 * Similar to Visual C, it seems that on Windows/ARM64 the clang-based
97 * builds have a smaller stack space available. When running out of
98 * that stack space, a `STATUS_STACK_OVERFLOW` is produced. When the
99 * Git command was run from an MSYS2 Bash, this unfortunately results
100 * in an exit code 127. Let's prevent that by lowering the maximal
101 * tree depth; This value seems to be low enough.
102 */
103 1280;
104#else
105 2048;
106#endif
107
108#ifndef PROTECT_HFS_DEFAULT
109#define PROTECT_HFS_DEFAULT 0
110#endif
111int protect_hfs = PROTECT_HFS_DEFAULT;
112
113#ifndef PROTECT_NTFS_DEFAULT
114#define PROTECT_NTFS_DEFAULT 1
115#endif
116int protect_ntfs = PROTECT_NTFS_DEFAULT;
117
118/*
119 * The character that begins a commented line in user-editable file
120 * that is subject to stripspace.
121 */
122const char *comment_line_str = "#";
123char *comment_line_str_to_free;
124#ifndef WITH_BREAKING_CHANGES
125int auto_comment_line_char;
126bool warn_on_auto_comment_char;
127#endif /* !WITH_BREAKING_CHANGES */
128
129/* This is set by setup_git_directory_gently() and/or git_default_config() */
130char *git_work_tree_cfg;
131
132/*
133 * Repository-local GIT_* environment variables; see environment.h for details.
134 */
135const char * const local_repo_env[] = {
136 ALTERNATE_DB_ENVIRONMENT,
137 CONFIG_ENVIRONMENT,
138 CONFIG_DATA_ENVIRONMENT,
139 CONFIG_COUNT_ENVIRONMENT,
140 DB_ENVIRONMENT,
141 GIT_DIR_ENVIRONMENT,
142 GIT_WORK_TREE_ENVIRONMENT,
143 GIT_IMPLICIT_WORK_TREE_ENVIRONMENT,
144 GRAFT_ENVIRONMENT,
145 INDEX_ENVIRONMENT,
146 NO_REPLACE_OBJECTS_ENVIRONMENT,
147 GIT_REPLACE_REF_BASE_ENVIRONMENT,
148 GIT_PREFIX_ENVIRONMENT,
149 GIT_SHALLOW_FILE_ENVIRONMENT,
150 GIT_COMMON_DIR_ENVIRONMENT,
151 NULL
152};
153
154const char *getenv_safe(struct strvec *argv, const char *name)
155{
156 const char *value = getenv(name);
157
158 if (!value)
159 return NULL;
160
161 strvec_push(argv, value);
162 return argv->v[argv->nr - 1];
163}
164
165int is_bare_repository(void)
166{
167 /* if core.bare is not 'false', let's see if there is a work tree */
168 return is_bare_repository_cfg && !repo_get_work_tree(the_repository);
169}
170
171int have_git_dir(void)
172{
173 return startup_info->have_repository
174 || the_repository->gitdir;
175}
176
177const char *get_git_namespace(void)
178{
179 static const char *namespace;
180 struct strbuf buf = STRBUF_INIT;
181 const char *raw_namespace;
182 struct string_list components = STRING_LIST_INIT_DUP;
183 struct string_list_item *item;
184
185 if (namespace)
186 return namespace;
187
188 raw_namespace = getenv(GIT_NAMESPACE_ENVIRONMENT);
189 if (!raw_namespace || !*raw_namespace) {
190 namespace = "";
191 return namespace;
192 }
193
194 strbuf_addstr(&buf, raw_namespace);
195
196 string_list_split(&components, buf.buf, "/", -1);
197 strbuf_reset(&buf);
198
199 for_each_string_list_item(item, &components) {
200 if (item->string[0])
201 strbuf_addf(&buf, "refs/namespaces/%s/", item->string);
202 }
203 string_list_clear(&components, 0);
204
205 strbuf_trim_trailing_dir_sep(&buf);
206 if (check_refname_format(buf.buf, 0))
207 die(_("bad git namespace path \"%s\""), raw_namespace);
208 strbuf_addch(&buf, '/');
209
210 namespace = strbuf_detach(&buf, NULL);
211
212 return namespace;
213}
214
215const char *strip_namespace(const char *namespaced_ref)
216{
217 const char *out;
218 if (skip_prefix(namespaced_ref, get_git_namespace(), &out))
219 return out;
220 return NULL;
221}
222
223const char *get_log_output_encoding(void)
224{
225 return git_log_output_encoding ? git_log_output_encoding
226 : get_commit_output_encoding();
227}
228
229const char *get_commit_output_encoding(void)
230{
231 return git_commit_encoding ? git_commit_encoding : "UTF-8";
232}
233
234int use_optional_locks(void)
235{
236 return git_env_bool(GIT_OPTIONAL_LOCKS_ENVIRONMENT, 1);
237}
238
239int print_sha1_ellipsis(void)
240{
241 /*
242 * Determine if the calling environment contains the variable
243 * GIT_PRINT_SHA1_ELLIPSIS set to "yes".
244 */
245 static int cached_result = -1; /* unknown */
246
247 if (cached_result < 0) {
248 const char *v = getenv("GIT_PRINT_SHA1_ELLIPSIS");
249 cached_result = (v && !strcasecmp(v, "yes"));
250 }
251 return cached_result;
252}
253
254static const struct fsync_component_name {
255 const char *name;
256 enum fsync_component component_bits;
257} fsync_component_names[] = {
258 { "loose-object", FSYNC_COMPONENT_LOOSE_OBJECT },
259 { "pack", FSYNC_COMPONENT_PACK },
260 { "pack-metadata", FSYNC_COMPONENT_PACK_METADATA },
261 { "commit-graph", FSYNC_COMPONENT_COMMIT_GRAPH },
262 { "index", FSYNC_COMPONENT_INDEX },
263 { "objects", FSYNC_COMPONENTS_OBJECTS },
264 { "reference", FSYNC_COMPONENT_REFERENCE },
265 { "derived-metadata", FSYNC_COMPONENTS_DERIVED_METADATA },
266 { "committed", FSYNC_COMPONENTS_COMMITTED },
267 { "added", FSYNC_COMPONENTS_ADDED },
268 { "all", FSYNC_COMPONENTS_ALL },
269};
270
271static enum fsync_component parse_fsync_components(const char *var, const char *string)
272{
273 enum fsync_component current = FSYNC_COMPONENTS_PLATFORM_DEFAULT;
274 enum fsync_component positive = 0, negative = 0;
275
276 while (string) {
277 size_t len;
278 const char *ep;
279 int negated = 0;
280 int found = 0;
281
282 string = string + strspn(string, ", \t\n\r");
283 ep = strchrnul(string, ',');
284 len = ep - string;
285 if (!strcmp(string, "none")) {
286 current = FSYNC_COMPONENT_NONE;
287 goto next_name;
288 }
289
290 if (*string == '-') {
291 negated = 1;
292 string++;
293 len--;
294 if (!len)
295 warning(_("invalid value for variable %s"), var);
296 }
297
298 if (!len)
299 break;
300
301 for (size_t i = 0; i < ARRAY_SIZE(fsync_component_names); ++i) {
302 const struct fsync_component_name *n = &fsync_component_names[i];
303
304 if (strncmp(n->name, string, len))
305 continue;
306
307 found = 1;
308 if (negated)
309 negative |= n->component_bits;
310 else
311 positive |= n->component_bits;
312 }
313
314 if (!found) {
315 char *component = xstrndup(string, len);
316 warning(_("ignoring unknown core.fsync component '%s'"), component);
317 free(component);
318 }
319
320next_name:
321 string = ep;
322 }
323
324 return (current & ~negative) | positive;
325}
326
327static int git_default_core_config(const char *var, const char *value,
328 const struct config_context *ctx, void *cb)
329{
330 /* This needs a better name */
331 if (!strcmp(var, "core.filemode")) {
332 trust_executable_bit = git_config_bool(var, value);
333 return 0;
334 }
335 if (!strcmp(var, "core.trustctime")) {
336 trust_ctime = git_config_bool(var, value);
337 return 0;
338 }
339 if (!strcmp(var, "core.checkstat")) {
340 if (!value)
341 return config_error_nonbool(var);
342 if (!strcasecmp(value, "default"))
343 check_stat = 1;
344 else if (!strcasecmp(value, "minimal"))
345 check_stat = 0;
346 else
347 return error(_("invalid value for '%s': '%s'"),
348 var, value);
349 }
350
351 if (!strcmp(var, "core.quotepath")) {
352 quote_path_fully = git_config_bool(var, value);
353 return 0;
354 }
355
356 if (!strcmp(var, "core.symlinks")) {
357 has_symlinks = git_config_bool(var, value);
358 return 0;
359 }
360
361 if (!strcmp(var, "core.ignorecase")) {
362 ignore_case = git_config_bool(var, value);
363 return 0;
364 }
365
366 if (!strcmp(var, "core.attributesfile")) {
367 FREE_AND_NULL(git_attributes_file);
368 return git_config_pathname(&git_attributes_file, var, value);
369 }
370
371 if (!strcmp(var, "core.bare")) {
372 is_bare_repository_cfg = git_config_bool(var, value);
373 return 0;
374 }
375
376 if (!strcmp(var, "core.ignorestat")) {
377 assume_unchanged = git_config_bool(var, value);
378 return 0;
379 }
380
381 if (!strcmp(var, "core.abbrev")) {
382 if (!value)
383 return config_error_nonbool(var);
384 if (!strcasecmp(value, "auto"))
385 default_abbrev = -1;
386 else if (!git_parse_maybe_bool_text(value))
387 default_abbrev = GIT_MAX_HEXSZ;
388 else {
389 int abbrev = git_config_int(var, value, ctx->kvi);
390 if (abbrev < minimum_abbrev)
391 return error(_("abbrev length out of range: %d"), abbrev);
392 default_abbrev = abbrev;
393 }
394 return 0;
395 }
396
397 if (!strcmp(var, "core.disambiguate"))
398 return set_disambiguate_hint_config(var, value);
399
400 if (!strcmp(var, "core.loosecompression")) {
401 int level = git_config_int(var, value, ctx->kvi);
402 if (level == -1)
403 level = Z_DEFAULT_COMPRESSION;
404 else if (level < 0 || level > Z_BEST_COMPRESSION)
405 die(_("bad zlib compression level %d"), level);
406 zlib_compression_level = level;
407 zlib_compression_seen = 1;
408 return 0;
409 }
410
411 if (!strcmp(var, "core.compression")) {
412 int level = git_config_int(var, value, ctx->kvi);
413 if (level == -1)
414 level = Z_DEFAULT_COMPRESSION;
415 else if (level < 0 || level > Z_BEST_COMPRESSION)
416 die(_("bad zlib compression level %d"), level);
417 if (!zlib_compression_seen)
418 zlib_compression_level = level;
419 if (!pack_compression_seen)
420 pack_compression_level = level;
421 return 0;
422 }
423
424 if (!strcmp(var, "core.autocrlf")) {
425 if (value && !strcasecmp(value, "input")) {
426 auto_crlf = AUTO_CRLF_INPUT;
427 return 0;
428 }
429 auto_crlf = git_config_bool(var, value);
430 return 0;
431 }
432
433 if (!strcmp(var, "core.safecrlf")) {
434 int eol_rndtrp_die;
435 if (value && !strcasecmp(value, "warn")) {
436 global_conv_flags_eol = CONV_EOL_RNDTRP_WARN;
437 return 0;
438 }
439 eol_rndtrp_die = git_config_bool(var, value);
440 global_conv_flags_eol = eol_rndtrp_die ?
441 CONV_EOL_RNDTRP_DIE : 0;
442 return 0;
443 }
444
445 if (!strcmp(var, "core.eol")) {
446 if (value && !strcasecmp(value, "lf"))
447 core_eol = EOL_LF;
448 else if (value && !strcasecmp(value, "crlf"))
449 core_eol = EOL_CRLF;
450 else if (value && !strcasecmp(value, "native"))
451 core_eol = EOL_NATIVE;
452 else
453 core_eol = EOL_UNSET;
454 return 0;
455 }
456
457 if (!strcmp(var, "core.checkroundtripencoding")) {
458 FREE_AND_NULL(check_roundtrip_encoding);
459 return git_config_string(&check_roundtrip_encoding, var, value);
460 }
461
462 if (!strcmp(var, "core.editor")) {
463 FREE_AND_NULL(editor_program);
464 return git_config_string(&editor_program, var, value);
465 }
466
467 if (!strcmp(var, "core.commentchar") ||
468 !strcmp(var, "core.commentstring")) {
469 if (!value) {
470 return config_error_nonbool(var);
471#ifndef WITH_BREAKING_CHANGES
472 } else if (!strcasecmp(value, "auto")) {
473 auto_comment_line_char = 1;
474 FREE_AND_NULL(comment_line_str_to_free);
475 comment_line_str = "#";
476#endif /* !WITH_BREAKING_CHANGES */
477 } else if (value[0]) {
478 if (strchr(value, '\n'))
479 return error(_("%s cannot contain newline"), var);
480 comment_line_str = value;
481 FREE_AND_NULL(comment_line_str_to_free);
482#ifndef WITH_BREAKING_CHANGES
483 auto_comment_line_char = 0;
484#endif /* !WITH_BREAKING_CHANGES */
485 } else
486 return error(_("%s must have at least one character"), var);
487 return 0;
488 }
489
490 if (!strcmp(var, "core.askpass")) {
491 FREE_AND_NULL(askpass_program);
492 return git_config_string(&askpass_program, var, value);
493 }
494
495 if (!strcmp(var, "core.excludesfile")) {
496 FREE_AND_NULL(excludes_file);
497 return git_config_pathname(&excludes_file, var, value);
498 }
499
500 if (!strcmp(var, "core.whitespace")) {
501 if (!value)
502 return config_error_nonbool(var);
503 whitespace_rule_cfg = parse_whitespace_rule(value);
504 return 0;
505 }
506
507 if (!strcmp(var, "core.fsync")) {
508 if (!value)
509 return config_error_nonbool(var);
510 fsync_components = parse_fsync_components(var, value);
511 return 0;
512 }
513
514 if (!strcmp(var, "core.fsyncmethod")) {
515 if (!value)
516 return config_error_nonbool(var);
517 if (!strcmp(value, "fsync"))
518 fsync_method = FSYNC_METHOD_FSYNC;
519 else if (!strcmp(value, "writeout-only"))
520 fsync_method = FSYNC_METHOD_WRITEOUT_ONLY;
521 else if (!strcmp(value, "batch"))
522 fsync_method = FSYNC_METHOD_BATCH;
523 else
524 warning(_("ignoring unknown core.fsyncMethod value '%s'"), value);
525
526 }
527
528 if (!strcmp(var, "core.fsyncobjectfiles")) {
529 if (fsync_object_files < 0)
530 warning(_("core.fsyncObjectFiles is deprecated; use core.fsync instead"));
531 fsync_object_files = git_config_bool(var, value);
532 return 0;
533 }
534
535 if (!strcmp(var, "core.createobject")) {
536 if (!value)
537 return config_error_nonbool(var);
538 if (!strcmp(value, "rename"))
539 object_creation_mode = OBJECT_CREATION_USES_RENAMES;
540 else if (!strcmp(value, "link"))
541 object_creation_mode = OBJECT_CREATION_USES_HARDLINKS;
542 else
543 die(_("invalid mode for object creation: %s"), value);
544 return 0;
545 }
546
547 if (!strcmp(var, "core.sparsecheckout")) {
548 core_apply_sparse_checkout = git_config_bool(var, value);
549 return 0;
550 }
551
552 if (!strcmp(var, "core.sparsecheckoutcone")) {
553 core_sparse_checkout_cone = git_config_bool(var, value);
554 return 0;
555 }
556
557 if (!strcmp(var, "core.precomposeunicode")) {
558 precomposed_unicode = git_config_bool(var, value);
559 return 0;
560 }
561
562 if (!strcmp(var, "core.protecthfs")) {
563 protect_hfs = git_config_bool(var, value);
564 return 0;
565 }
566
567 if (!strcmp(var, "core.protectntfs")) {
568 protect_ntfs = git_config_bool(var, value);
569 return 0;
570 }
571
572 if (!strcmp(var, "core.maxtreedepth")) {
573 max_allowed_tree_depth = git_config_int(var, value, ctx->kvi);
574 return 0;
575 }
576
577 /* Add other config variables here and to Documentation/config.adoc. */
578 return platform_core_config(var, value, ctx, cb);
579}
580
581static int git_default_sparse_config(const char *var, const char *value)
582{
583 if (!strcmp(var, "sparse.expectfilesoutsideofpatterns")) {
584 sparse_expect_files_outside_of_patterns = git_config_bool(var, value);
585 return 0;
586 }
587
588 /* Add other config variables here and to Documentation/config/sparse.adoc. */
589 return 0;
590}
591
592static int git_default_i18n_config(const char *var, const char *value)
593{
594 if (!strcmp(var, "i18n.commitencoding")) {
595 FREE_AND_NULL(git_commit_encoding);
596 return git_config_string(&git_commit_encoding, var, value);
597 }
598
599 if (!strcmp(var, "i18n.logoutputencoding")) {
600 FREE_AND_NULL(git_log_output_encoding);
601 return git_config_string(&git_log_output_encoding, var, value);
602 }
603
604 /* Add other config variables here and to Documentation/config.adoc. */
605 return 0;
606}
607
608static int git_default_branch_config(const char *var, const char *value)
609{
610 if (!strcmp(var, "branch.autosetupmerge")) {
611 if (value && !strcmp(value, "always")) {
612 git_branch_track = BRANCH_TRACK_ALWAYS;
613 return 0;
614 } else if (value && !strcmp(value, "inherit")) {
615 git_branch_track = BRANCH_TRACK_INHERIT;
616 return 0;
617 } else if (value && !strcmp(value, "simple")) {
618 git_branch_track = BRANCH_TRACK_SIMPLE;
619 return 0;
620 }
621 git_branch_track = git_config_bool(var, value);
622 return 0;
623 }
624 if (!strcmp(var, "branch.autosetuprebase")) {
625 if (!value)
626 return config_error_nonbool(var);
627 else if (!strcmp(value, "never"))
628 autorebase = AUTOREBASE_NEVER;
629 else if (!strcmp(value, "local"))
630 autorebase = AUTOREBASE_LOCAL;
631 else if (!strcmp(value, "remote"))
632 autorebase = AUTOREBASE_REMOTE;
633 else if (!strcmp(value, "always"))
634 autorebase = AUTOREBASE_ALWAYS;
635 else
636 return error(_("malformed value for %s"), var);
637 return 0;
638 }
639
640 /* Add other config variables here and to Documentation/config.adoc. */
641 return 0;
642}
643
644static int git_default_push_config(const char *var, const char *value)
645{
646 if (!strcmp(var, "push.default")) {
647 if (!value)
648 return config_error_nonbool(var);
649 else if (!strcmp(value, "nothing"))
650 push_default = PUSH_DEFAULT_NOTHING;
651 else if (!strcmp(value, "matching"))
652 push_default = PUSH_DEFAULT_MATCHING;
653 else if (!strcmp(value, "simple"))
654 push_default = PUSH_DEFAULT_SIMPLE;
655 else if (!strcmp(value, "upstream"))
656 push_default = PUSH_DEFAULT_UPSTREAM;
657 else if (!strcmp(value, "tracking")) /* deprecated */
658 push_default = PUSH_DEFAULT_UPSTREAM;
659 else if (!strcmp(value, "current"))
660 push_default = PUSH_DEFAULT_CURRENT;
661 else {
662 error(_("malformed value for %s: %s"), var, value);
663 return error(_("must be one of nothing, matching, simple, "
664 "upstream or current"));
665 }
666 return 0;
667 }
668
669 /* Add other config variables here and to Documentation/config.adoc. */
670 return 0;
671}
672
673static int git_default_mailmap_config(const char *var, const char *value)
674{
675 if (!strcmp(var, "mailmap.file")) {
676 FREE_AND_NULL(git_mailmap_file);
677 return git_config_pathname(&git_mailmap_file, var, value);
678 }
679
680 if (!strcmp(var, "mailmap.blob")) {
681 FREE_AND_NULL(git_mailmap_blob);
682 return git_config_string(&git_mailmap_blob, var, value);
683 }
684
685 /* Add other config variables here and to Documentation/config.adoc. */
686 return 0;
687}
688
689static int git_default_attr_config(const char *var, const char *value)
690{
691 if (!strcmp(var, "attr.tree")) {
692 FREE_AND_NULL(git_attr_tree);
693 return git_config_string(&git_attr_tree, var, value);
694 }
695
696 /*
697 * Add other attribute related config variables here and to
698 * Documentation/config/attr.adoc.
699 */
700 return 0;
701}
702
703int git_default_config(const char *var, const char *value,
704 const struct config_context *ctx, void *cb)
705{
706 if (starts_with(var, "core."))
707 return git_default_core_config(var, value, ctx, cb);
708
709 if (starts_with(var, "user.") ||
710 starts_with(var, "author.") ||
711 starts_with(var, "committer."))
712 return git_ident_config(var, value, ctx, cb);
713
714 if (starts_with(var, "i18n."))
715 return git_default_i18n_config(var, value);
716
717 if (starts_with(var, "branch."))
718 return git_default_branch_config(var, value);
719
720 if (starts_with(var, "push."))
721 return git_default_push_config(var, value);
722
723 if (starts_with(var, "mailmap."))
724 return git_default_mailmap_config(var, value);
725
726 if (starts_with(var, "attr."))
727 return git_default_attr_config(var, value);
728
729 if (starts_with(var, "advice.") || starts_with(var, "color.advice"))
730 return git_default_advice_config(var, value);
731
732 if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) {
733 pager_use_color = git_config_bool(var,value);
734 return 0;
735 }
736
737 if (!strcmp(var, "pack.packsizelimit")) {
738 pack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi);
739 return 0;
740 }
741
742 if (!strcmp(var, "pack.compression")) {
743 int level = git_config_int(var, value, ctx->kvi);
744 if (level == -1)
745 level = Z_DEFAULT_COMPRESSION;
746 else if (level < 0 || level > Z_BEST_COMPRESSION)
747 die(_("bad pack compression level %d"), level);
748 pack_compression_level = level;
749 pack_compression_seen = 1;
750 return 0;
751 }
752
753 if (starts_with(var, "sparse."))
754 return git_default_sparse_config(var, value);
755
756 /* Add other config variables here and to Documentation/config.adoc. */
757 return 0;
758}