Git fork
at reftables-rust 758 lines 20 kB view raw
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}