Coverage Report

Created: 2026-10-17 07:15

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