Merge branch 'ds/feature-macros'
authorJunio C Hamano <gitster@pobox.com>
Mon, 9 Sep 2019 19:26:36 +0000 (12:26 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Sep 2019 19:26:36 +0000 (12:26 -0700)
A mechanism to affect the default setting for a (related) group of
configuration variables is introduced.

* ds/feature-macros:
repo-settings: create feature.experimental setting
repo-settings: create feature.manyFiles setting
repo-settings: parse core.untrackedCache
commit-graph: turn on commit-graph by default
t6501: use 'git gc' in quiet mode
repo-settings: consolidate some config settings

1  2 
Makefile
builtin/gc.c
builtin/pack-objects.c
commit-graph.c
config.c
read-cache.c
t/t0410-partial-clone.sh
t/t5324-split-commit-graph.sh
diff --combined Makefile
index f9255344ae5009a192ab83a332be749632d94531,032fe9b5f9552e660f40019dcbc48795219bace5..ad71ae12194e1d27f2adcd4014d0048ee4a5ebcd
+++ b/Makefile
@@@ -704,7 -704,6 +704,7 @@@ TEST_BUILTINS_OBJS += test-config.
  TEST_BUILTINS_OBJS += test-ctype.o
  TEST_BUILTINS_OBJS += test-date.o
  TEST_BUILTINS_OBJS += test-delta.o
 +TEST_BUILTINS_OBJS += test-dir-iterator.o
  TEST_BUILTINS_OBJS += test-drop-caches.o
  TEST_BUILTINS_OBJS += test-dump-cache-tree.o
  TEST_BUILTINS_OBJS += test-dump-fsmonitor.o
@@@ -965,6 -964,7 +965,7 @@@ LIB_OBJS += refspec.
  LIB_OBJS += ref-filter.o
  LIB_OBJS += remote.o
  LIB_OBJS += replace-object.o
+ LIB_OBJS += repo-settings.o
  LIB_OBJS += repository.o
  LIB_OBJS += rerere.o
  LIB_OBJS += resolve-undo.o
@@@ -1063,7 -1063,6 +1064,7 @@@ BUILTIN_OBJS += builtin/diff-index.
  BUILTIN_OBJS += builtin/diff-tree.o
  BUILTIN_OBJS += builtin/diff.o
  BUILTIN_OBJS += builtin/difftool.o
 +BUILTIN_OBJS += builtin/env--helper.o
  BUILTIN_OBJS += builtin/fast-export.o
  BUILTIN_OBJS += builtin/fetch-pack.o
  BUILTIN_OBJS += builtin/fetch.o
@@@ -2720,7 -2719,7 +2721,7 @@@ bin-wrappers/%: wrap-for-bin.s
        @mkdir -p bin-wrappers
        $(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
             -e 's|@@BUILD_DIR@@|$(shell pwd)|' \
 -           -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' < $< > $@ && \
 +           -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \
        chmod +x $@
  
  # GNU make supports exporting all variables by "export" without parameters.
diff --combined builtin/gc.c
index 305fb0f45af3bdfc32e15bcc18acdcaa6af205cb,4b8fbb9965c88ae44f88e62aa30e5737d95b1cc8..a22b6ff683465a3addeb059c89775e080197f155
@@@ -41,7 -41,6 +41,6 @@@ static int aggressive_depth = 50
  static int aggressive_window = 250;
  static int gc_auto_threshold = 6700;
  static int gc_auto_pack_limit = 50;
- static int gc_write_commit_graph;
  static int detach_auto = 1;
  static timestamp_t gc_log_expire_time;
  static const char *gc_log_expire = "1.day.ago";
@@@ -148,7 -147,6 +147,6 @@@ static void gc_config(void
        git_config_get_int("gc.aggressivedepth", &aggressive_depth);
        git_config_get_int("gc.auto", &gc_auto_threshold);
        git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
-       git_config_get_bool("gc.writecommitgraph", &gc_write_commit_graph);
        git_config_get_bool("gc.autodetach", &detach_auto);
        git_config_get_expiry("gc.pruneexpire", &prune_expire);
        git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
@@@ -685,11 -683,11 +683,11 @@@ int cmd_gc(int argc, const char **argv
                clean_pack_garbage();
        }
  
-       if (gc_write_commit_graph &&
-           write_commit_graph_reachable(get_object_directory(),
-                                        !quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
-                                        NULL))
-               return 1;
+       prepare_repo_settings(the_repository);
+       if (the_repository->settings.gc_write_commit_graph == 1)
+               write_commit_graph_reachable(get_object_directory(),
 -                                           !quiet && !daemonized ? COMMIT_GRAPH_PROGRESS : 0,
++                                           !quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
+                                            NULL);
  
        if (auto_gc && too_many_loose_objects())
                warning(_("There are too many unreachable loose objects; "
diff --combined builtin/pack-objects.c
index 76ce9069467e06545652a70040b79316f0a87fb9,f9f7181f3f8daa2a2f2c766ae09aa8941525f218..b410801edb6b8a18ffff17b6c720db98d4238106
@@@ -96,11 -96,7 +96,11 @@@ static off_t reuse_packfile_offset
  
  static int use_bitmap_index_default = 1;
  static int use_bitmap_index = -1;
 -static int write_bitmap_index;
 +static enum {
 +      WRITE_BITMAP_FALSE = 0,
 +      WRITE_BITMAP_QUIET,
 +      WRITE_BITMAP_TRUE,
 +} write_bitmap_index;
  static uint16_t write_bitmap_options = BITMAP_OPT_HASH_CACHE;
  
  static int exclude_promisor_objects;
@@@ -896,8 -892,7 +896,8 @@@ static void write_pack_file(void
                                                 nr_written, oid.hash, offset);
                        close(fd);
                        if (write_bitmap_index) {
 -                              warning(_(no_split_warning));
 +                              if (write_bitmap_index != WRITE_BITMAP_QUIET)
 +                                      warning(_(no_split_warning));
                                write_bitmap_index = 0;
                        }
                }
@@@ -1181,8 -1176,7 +1181,8 @@@ static int add_object_entry(const struc
        if (!want_object_in_pack(oid, exclude, &found_pack, &found_offset)) {
                /* The pack is missing an object, so it will not have closure */
                if (write_bitmap_index) {
 -                      warning(_(no_closure_warning));
 +                      if (write_bitmap_index != WRITE_BITMAP_QUIET)
 +                              warning(_(no_closure_warning));
                        write_bitmap_index = 0;
                }
                return 0;
@@@ -2715,10 -2709,6 +2715,6 @@@ static int git_pack_config(const char *
                use_bitmap_index_default = git_config_bool(k, v);
                return 0;
        }
-       if (!strcmp(k, "pack.usesparse")) {
-               sparse = git_config_bool(k, v);
-               return 0;
-       }
        if (!strcmp(k, "pack.threads")) {
                delta_search_threads = git_config_int(k, v);
                if (delta_search_threads < 0)
@@@ -3319,13 -3309,8 +3315,13 @@@ int cmd_pack_objects(int argc, const ch
                            N_("do not hide commits by grafts"), 0),
                OPT_BOOL(0, "use-bitmap-index", &use_bitmap_index,
                         N_("use a bitmap index if available to speed up counting objects")),
 -              OPT_BOOL(0, "write-bitmap-index", &write_bitmap_index,
 -                       N_("write a bitmap index together with the pack index")),
 +              OPT_SET_INT(0, "write-bitmap-index", &write_bitmap_index,
 +                          N_("write a bitmap index together with the pack index"),
 +                          WRITE_BITMAP_TRUE),
 +              OPT_SET_INT_F(0, "write-bitmap-index-quiet",
 +                            &write_bitmap_index,
 +                            N_("write a bitmap index if possible"),
 +                            WRITE_BITMAP_QUIET, PARSE_OPT_HIDDEN),
                OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
                { OPTION_CALLBACK, 0, "missing", NULL, N_("action"),
                  N_("handling for missing objects"), PARSE_OPT_NONEG,
        read_replace_refs = 0;
  
        sparse = git_env_bool("GIT_TEST_PACK_SPARSE", 0);
+       prepare_repo_settings(the_repository);
+       if (!sparse && the_repository->settings.pack_use_sparse != -1)
+               sparse = the_repository->settings.pack_use_sparse;
        reset_pack_idx_option(&pack_idx_opts);
        git_config(git_pack_config, NULL);
  
diff --combined commit-graph.c
index f2888c203b677a8a0091f7f63129efe282899172,7854e491b23666d3d6dbb827d1290348b9ec14eb..9b02d2c42657b4cef247fee6aa4240dead0ae776
@@@ -434,7 -434,6 +434,7 @@@ static struct commit_graph *load_commit
  
        free(oids);
        fclose(fp);
 +      strbuf_release(&line);
  
        return graph_chain;
  }
@@@ -467,7 -466,6 +467,6 @@@ static void prepare_commit_graph_one(st
  static int prepare_commit_graph(struct repository *r)
  {
        struct object_directory *odb;
-       int config_value;
  
        if (git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD, 0))
                die("dying as requested by the '%s' variable on commit-graph load!",
                return !!r->objects->commit_graph;
        r->objects->commit_graph_attempted = 1;
  
+       prepare_repo_settings(r);
        if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
-           (repo_config_get_bool(r, "core.commitgraph", &config_value) ||
-           !config_value))
+           r->settings.core_commit_graph != 1)
                /*
                 * This repository is not configured to use commit graphs, so
                 * do not load one. (But report commit_graph_attempted anyway
@@@ -783,8 -782,7 +783,8 @@@ struct write_commit_graph_context 
  
        unsigned append:1,
                 report_progress:1,
 -               split:1;
 +               split:1,
 +               check_oids:1;
  
        const struct split_commit_graph_opts *split_opts;
  };
@@@ -1135,8 -1133,7 +1135,8 @@@ static int add_ref_to_list(const char *
        return 0;
  }
  
 -int write_commit_graph_reachable(const char *obj_dir, unsigned int flags,
 +int write_commit_graph_reachable(const char *obj_dir,
 +                               enum commit_graph_write_flags flags,
                                 const struct split_commit_graph_opts *split_opts)
  {
        struct string_list list = STRING_LIST_INIT_DUP;
@@@ -1189,14 -1186,14 +1189,14 @@@ static int fill_oids_from_packs(struct 
        }
  
        stop_progress(&ctx->progress);
 -      strbuf_reset(&progress_title);
 +      strbuf_release(&progress_title);
        strbuf_release(&packname);
  
        return 0;
  }
  
 -static void fill_oids_from_commit_hex(struct write_commit_graph_context *ctx,
 -                                    struct string_list *commit_hex)
 +static int fill_oids_from_commit_hex(struct write_commit_graph_context *ctx,
 +                                   struct string_list *commit_hex)
  {
        uint32_t i;
        struct strbuf progress_title = STRBUF_INIT;
                struct commit *result;
  
                display_progress(ctx->progress, i + 1);
 -              if (commit_hex->items[i].string &&
 -                  parse_oid_hex(commit_hex->items[i].string, &oid, &end))
 -                      continue;
 -
 -              result = lookup_commit_reference_gently(ctx->r, &oid, 1);
 -
 -              if (result) {
 +              if (!parse_oid_hex(commit_hex->items[i].string, &oid, &end) &&
 +                  (result = lookup_commit_reference_gently(ctx->r, &oid, 1))) {
                        ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc);
                        oidcpy(&ctx->oids.list[ctx->oids.nr], &(result->object.oid));
                        ctx->oids.nr++;
 +              } else if (ctx->check_oids) {
 +                      error(_("invalid commit object id: %s"),
 +                          commit_hex->items[i].string);
 +                      return -1;
                }
        }
        stop_progress(&ctx->progress);
        strbuf_release(&progress_title);
 +
 +      return 0;
  }
  
  static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx)
@@@ -1640,7 -1636,7 +1640,7 @@@ static void sort_and_scan_merged_commit
                                num_parents++;
  
                        if (num_parents > 2)
 -                              ctx->num_extra_edges += num_parents - 2;
 +                              ctx->num_extra_edges += num_parents - 1;
                }
        }
  
@@@ -1717,8 -1713,10 +1717,8 @@@ static void expire_commit_graphs(struc
        strbuf_addstr(&path, "/info/commit-graphs");
        dir = opendir(path.buf);
  
 -      if (!dir) {
 -              strbuf_release(&path);
 -              return;
 -      }
 +      if (!dir)
 +              goto out;
  
        strbuf_addch(&path, '/');
        dirnamelen = path.len;
                if (!found)
                        unlink(path.buf);
        }
 +
 +out:
 +      strbuf_release(&path);
  }
  
  int write_commit_graph(const char *obj_dir,
                       struct string_list *pack_indexes,
                       struct string_list *commit_hex,
 -                     unsigned int flags,
 +                     enum commit_graph_write_flags flags,
                       const struct split_commit_graph_opts *split_opts)
  {
        struct write_commit_graph_context *ctx;
        if (len && ctx->obj_dir[len - 1] == '/')
                ctx->obj_dir[len - 1] = 0;
  
 -      ctx->append = flags & COMMIT_GRAPH_APPEND ? 1 : 0;
 -      ctx->report_progress = flags & COMMIT_GRAPH_PROGRESS ? 1 : 0;
 -      ctx->split = flags & COMMIT_GRAPH_SPLIT ? 1 : 0;
 +      ctx->append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0;
 +      ctx->report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0;
 +      ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0;
 +      ctx->check_oids = flags & COMMIT_GRAPH_WRITE_CHECK_OIDS ? 1 : 0;
        ctx->split_opts = split_opts;
  
        if (ctx->split) {
                        goto cleanup;
        }
  
 -      if (commit_hex)
 -              fill_oids_from_commit_hex(ctx, commit_hex);
 +      if (commit_hex) {
 +              if ((res = fill_oids_from_commit_hex(ctx, commit_hex)))
 +                      goto cleanup;
 +      }
  
        if (!pack_indexes && !commit_hex)
                fill_oids_from_all_packs(ctx);
diff --combined config.c
index cc637363bbae10f1b87b5b7ab0bd015e49cb56b8,3241dbc54de47aad9845f0bf26fd29638b13e9ba..b61c258d6da5266a66caa55ef821de0f8e0d75aa
+++ b/config.c
@@@ -275,8 -275,7 +275,8 @@@ static int include_by_branch(const cha
        int flags;
        int ret;
        struct strbuf pattern = STRBUF_INIT;
 -      const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, &flags);
 +      const char *refname = !the_repository->gitdir ?
 +              NULL : resolve_ref_unsafe("HEAD", 0, NULL, &flags);
        const char *shortname;
  
        if (!refname || !(flags & REF_ISSYMREF) ||
@@@ -974,44 -973,34 +974,44 @@@ int git_parse_ssize_t(const char *value
  NORETURN
  static void die_bad_number(const char *name, const char *value)
  {
 -      const char * error_type = (errno == ERANGE)? _("out of range"):_("invalid unit");
 +      const char *error_type = (errno == ERANGE) ?
 +              N_("out of range") : N_("invalid unit");
 +      const char *bad_numeric = N_("bad numeric config value '%s' for '%s': %s");
  
        if (!value)
                value = "";
  
 +      if (!strcmp(name, "GIT_TEST_GETTEXT_POISON"))
 +              /*
 +               * We explicitly *don't* use _() here since it would
 +               * cause an infinite loop with _() needing to call
 +               * use_gettext_poison(). This is why marked up
 +               * translations with N_() above.
 +               */
 +              die(bad_numeric, value, name, error_type);
 +
        if (!(cf && cf->name))
 -              die(_("bad numeric config value '%s' for '%s': %s"),
 -                  value, name, error_type);
 +              die(_(bad_numeric), value, name, _(error_type));
  
        switch (cf->origin_type) {
        case CONFIG_ORIGIN_BLOB:
                die(_("bad numeric config value '%s' for '%s' in blob %s: %s"),
 -                  value, name, cf->name, error_type);
 +                  value, name, cf->name, _(error_type));
        case CONFIG_ORIGIN_FILE:
                die(_("bad numeric config value '%s' for '%s' in file %s: %s"),
 -                  value, name, cf->name, error_type);
 +                  value, name, cf->name, _(error_type));
        case CONFIG_ORIGIN_STDIN:
                die(_("bad numeric config value '%s' for '%s' in standard input: %s"),
 -                  value, name, error_type);
 +                  value, name, _(error_type));
        case CONFIG_ORIGIN_SUBMODULE_BLOB:
                die(_("bad numeric config value '%s' for '%s' in submodule-blob %s: %s"),
 -                  value, name, cf->name, error_type);
 +                  value, name, cf->name, _(error_type));
        case CONFIG_ORIGIN_CMDLINE:
                die(_("bad numeric config value '%s' for '%s' in command line %s: %s"),
 -                  value, name, cf->name, error_type);
 +                  value, name, cf->name, _(error_type));
        default:
                die(_("bad numeric config value '%s' for '%s' in %s: %s"),
 -                  value, name, cf->name, error_type);
 +                  value, name, cf->name, _(error_type));
        }
  }
  
@@@ -2288,30 -2277,6 +2288,6 @@@ int git_config_get_expiry_in_days(cons
        return -1; /* thing exists but cannot be parsed */
  }
  
- int git_config_get_untracked_cache(void)
- {
-       int val = -1;
-       const char *v;
-       /* Hack for test programs like test-dump-untracked-cache */
-       if (ignore_untracked_cache_config)
-               return -1;
-       if (!git_config_get_maybe_bool("core.untrackedcache", &val))
-               return val;
-       if (!git_config_get_value("core.untrackedcache", &v)) {
-               if (!strcasecmp(v, "keep"))
-                       return -1;
-               error(_("unknown core.untrackedCache value '%s'; "
-                       "using 'keep' default value"), v);
-               return -1;
-       }
-       return -1; /* default value */
- }
  int git_config_get_split_index(void)
  {
        int val;
diff --combined read-cache.c
index 52ffa8a3139f2e427fadb7d233fb4910819becc9,7a07286164f9492ebd17543c976e0931c2899b74..cff1280975b5d400844916083c070b9ee861d1cf
@@@ -1599,16 -1599,17 +1599,17 @@@ struct cache_entry *refresh_cache_entry
  
  #define INDEX_FORMAT_DEFAULT 3
  
- static unsigned int get_index_format_default(void)
+ static unsigned int get_index_format_default(struct repository *r)
  {
        char *envversion = getenv("GIT_INDEX_VERSION");
        char *endp;
-       int value;
        unsigned int version = INDEX_FORMAT_DEFAULT;
  
        if (!envversion) {
-               if (!git_config_get_int("index.version", &value))
-                       version = value;
+               prepare_repo_settings(r);
+               if (r->settings.index_version >= 0)
+                       version = r->settings.index_version;
                if (version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < version) {
                        warning(_("index.version set, but the value is invalid.\n"
                                  "Using version %i"), INDEX_FORMAT_DEFAULT);
@@@ -1844,18 -1845,17 +1845,17 @@@ static void check_ce_order(struct index
  
  static void tweak_untracked_cache(struct index_state *istate)
  {
-       switch (git_config_get_untracked_cache()) {
-       case -1: /* keep: do nothing */
-               break;
-       case 0: /* false */
+       struct repository *r = the_repository;
+       prepare_repo_settings(r);
+       if (r->settings.core_untracked_cache  == UNTRACKED_CACHE_REMOVE) {
                remove_untracked_cache(istate);
-               break;
-       case 1: /* true */
-               add_untracked_cache(istate);
-               break;
-       default: /* unknown value: do nothing */
-               break;
+               return;
        }
+       if (r->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)
+               add_untracked_cache(istate);
  }
  
  static void tweak_split_index(struct index_state *istate)
@@@ -2140,7 -2140,7 +2140,7 @@@ int do_read_index(struct index_state *i
        if (mmap_size < sizeof(struct cache_header) + the_hash_algo->rawsz)
                die(_("%s: index file smaller than expected"), path);
  
 -      mmap = xmmap(NULL, mmap_size, PROT_READ, MAP_PRIVATE, fd, 0);
 +      mmap = xmmap_gently(NULL, mmap_size, PROT_READ, MAP_PRIVATE, fd, 0);
        if (mmap == MAP_FAILED)
                die_errno(_("%s: unable to map index file"), path);
        close(fd);
@@@ -2765,7 -2765,7 +2765,7 @@@ static int do_write_index(struct index_
        }
  
        if (!istate->version) {
-               istate->version = get_index_format_default();
+               istate->version = get_index_format_default(the_repository);
                if (git_env_bool("GIT_TEST_SPLIT_INDEX", 0))
                        init_split_index(istate);
        }
diff --combined t/t0410-partial-clone.sh
index 6415063980b49985b25d351f5c0079f44ad92533,181ffa44e9067072c89ef230446f3c2222efdedc..33e0aa4a896575f14442e5b1a9029640d4d7ac50
@@@ -234,7 -234,7 +234,7 @@@ test_expect_success 'rev-list stops tra
  
        git -C repo config core.repositoryformatversion 1 &&
        git -C repo config extensions.partialclone "arbitrary string" &&
-       GIT_TEST_COMMIT_GRAPH=0 git -C repo rev-list --exclude-promisor-objects --objects bar >out &&
+       GIT_TEST_COMMIT_GRAPH=0 git -C repo -c core.commitGraph=false rev-list --exclude-promisor-objects --objects bar >out &&
        grep $(git -C repo rev-parse bar) out &&
        ! grep $FOO out
  '
@@@ -518,7 -518,4 +518,7 @@@ test_expect_success 'fetching of missin
        git verify-pack --verbose "$IDX" | grep "$HASH"
  '
  
 +# DO NOT add non-httpd-specific tests here, because the last part of this
 +# test script is only executed when httpd is available and enabled.
 +
  test_done
index 99f4ef4c19dff028facac6da810c973b3a82a4fc,19aa40de15c70c391d30a4a23b50240c631b6430..e2c39533d3f8ce292f151d82f19dd753b564b882
@@@ -8,6 -8,7 +8,7 @@@ GIT_TEST_COMMIT_GRAPH=
  test_expect_success 'setup repo' '
        git init &&
        git config core.commitGraph true &&
+       git config gc.writeCommitGraph false &&
        infodir=".git/objects/info" &&
        graphdir="$infodir/commit-graphs" &&
        test_oid_init
@@@ -319,9 -320,7 +320,9 @@@ test_expect_success 'add octopus merge
        git merge commits/3 commits/4 &&
        git branch merge/octopus &&
        git commit-graph write --reachable --split &&
 -      git commit-graph verify &&
 +      git commit-graph verify 2>err &&
 +      test_line_count = 3 err &&
 +      test_i18ngrep ! warning err &&
        test_line_count = 3 $graphdir/commit-graph-chain
  '
  
@@@ -334,6 -333,7 +335,7 @@@ test_expect_success 'split across alter
        git clone --no-hardlinks . alt-split &&
        (
                cd alt-split &&
+               rm -f .git/objects/info/commit-graph &&
                echo "$(pwd)"/../.git/objects >.git/objects/info/alternates &&
                test_commit 18 &&
                git commit-graph write --reachable --split &&