Merge branch 'ds/feature-macros'
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
This commit is contained in:
@ -345,6 +345,8 @@ include::config/difftool.txt[]
|
|||||||
|
|
||||||
include::config/fastimport.txt[]
|
include::config/fastimport.txt[]
|
||||||
|
|
||||||
|
include::config/feature.txt[]
|
||||||
|
|
||||||
include::config/fetch.txt[]
|
include::config/fetch.txt[]
|
||||||
|
|
||||||
include::config/format.txt[]
|
include::config/format.txt[]
|
||||||
|
@ -86,7 +86,9 @@ core.untrackedCache::
|
|||||||
it will automatically be removed, if set to `false`. Before
|
it will automatically be removed, if set to `false`. Before
|
||||||
setting it to `true`, you should check that mtime is working
|
setting it to `true`, you should check that mtime is working
|
||||||
properly on your system.
|
properly on your system.
|
||||||
See linkgit:git-update-index[1]. `keep` by default.
|
See linkgit:git-update-index[1]. `keep` by default, unless
|
||||||
|
`feature.manyFiles` is enabled which sets this setting to
|
||||||
|
`true` by default.
|
||||||
|
|
||||||
core.checkStat::
|
core.checkStat::
|
||||||
When missing or is set to `default`, many fields in the stat
|
When missing or is set to `default`, many fields in the stat
|
||||||
@ -577,7 +579,7 @@ the `GIT_NOTES_REF` environment variable. See linkgit:git-notes[1].
|
|||||||
|
|
||||||
core.commitGraph::
|
core.commitGraph::
|
||||||
If true, then git will read the commit-graph file (if it exists)
|
If true, then git will read the commit-graph file (if it exists)
|
||||||
to parse the graph structure of commits. Defaults to false. See
|
to parse the graph structure of commits. Defaults to true. See
|
||||||
linkgit:git-commit-graph[1] for more information.
|
linkgit:git-commit-graph[1] for more information.
|
||||||
|
|
||||||
core.useReplaceRefs::
|
core.useReplaceRefs::
|
||||||
|
29
Documentation/config/feature.txt
Normal file
29
Documentation/config/feature.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
feature.*::
|
||||||
|
The config settings that start with `feature.` modify the defaults of
|
||||||
|
a group of other config settings. These groups are created by the Git
|
||||||
|
developer community as recommended defaults and are subject to change.
|
||||||
|
In particular, new config options may be added with different defaults.
|
||||||
|
|
||||||
|
feature.experimental::
|
||||||
|
Enable config options that are new to Git, and are being considered for
|
||||||
|
future defaults. Config settings included here may be added or removed
|
||||||
|
with each release, including minor version updates. These settings may
|
||||||
|
have unintended interactions since they are so new. Please enable this
|
||||||
|
setting if you are interested in providing feedback on experimental
|
||||||
|
features. The new default values are:
|
||||||
|
+
|
||||||
|
* `pack.useSparse=true` uses a new algorithm when constructing a pack-file
|
||||||
|
which can improve `git push` performance in repos with many files.
|
||||||
|
+
|
||||||
|
* `fetch.negotiationAlgorithm=skipping` may improve fetch negotiation times by
|
||||||
|
skipping more commits at a time, reducing the number of round trips.
|
||||||
|
|
||||||
|
feature.manyFiles::
|
||||||
|
Enable config options that optimize for repos with many files in the
|
||||||
|
working directory. With many files, commands such as `git status` and
|
||||||
|
`git checkout` may be slow and these new defaults improve performance:
|
||||||
|
+
|
||||||
|
* `index.version=4` enables path-prefix compression in the index.
|
||||||
|
+
|
||||||
|
* `core.untrackedCache=true` enables the untracked cache. This setting assumes
|
||||||
|
that mtime is working on your machine.
|
@ -59,7 +59,8 @@ fetch.negotiationAlgorithm::
|
|||||||
effort to converge faster, but may result in a larger-than-necessary
|
effort to converge faster, but may result in a larger-than-necessary
|
||||||
packfile; The default is "default" which instructs Git to use the default algorithm
|
packfile; The default is "default" which instructs Git to use the default algorithm
|
||||||
that never skips commits (unless the server has acknowledged it or one
|
that never skips commits (unless the server has acknowledged it or one
|
||||||
of its descendants).
|
of its descendants). If `feature.experimental` is enabled, then this
|
||||||
|
setting defaults to "skipping".
|
||||||
Unknown values will cause 'git fetch' to error out.
|
Unknown values will cause 'git fetch' to error out.
|
||||||
+
|
+
|
||||||
See also the `--negotiation-tip` option for linkgit:git-fetch[1].
|
See also the `--negotiation-tip` option for linkgit:git-fetch[1].
|
||||||
|
@ -63,7 +63,7 @@ gc.writeCommitGraph::
|
|||||||
If true, then gc will rewrite the commit-graph file when
|
If true, then gc will rewrite the commit-graph file when
|
||||||
linkgit:git-gc[1] is run. When using `git gc --auto`
|
linkgit:git-gc[1] is run. When using `git gc --auto`
|
||||||
the commit-graph will be updated if housekeeping is
|
the commit-graph will be updated if housekeeping is
|
||||||
required. Default is false. See linkgit:git-commit-graph[1]
|
required. Default is true. See linkgit:git-commit-graph[1]
|
||||||
for details.
|
for details.
|
||||||
|
|
||||||
gc.logExpiry::
|
gc.logExpiry::
|
||||||
|
@ -24,3 +24,4 @@ index.threads::
|
|||||||
index.version::
|
index.version::
|
||||||
Specify the version with which new index files should be
|
Specify the version with which new index files should be
|
||||||
initialized. This does not affect existing repositories.
|
initialized. This does not affect existing repositories.
|
||||||
|
If `feature.manyFiles` is enabled, then the default is 4.
|
||||||
|
@ -112,7 +112,8 @@ pack.useSparse::
|
|||||||
objects. This can have significant performance benefits when
|
objects. This can have significant performance benefits when
|
||||||
computing a pack to send a small change. However, it is possible
|
computing a pack to send a small change. However, it is possible
|
||||||
that extra objects are added to the pack-file if the included
|
that extra objects are added to the pack-file if the included
|
||||||
commits contain certain types of direct renames.
|
commits contain certain types of direct renames. Default is `false`
|
||||||
|
unless `feature.experimental` is enabled.
|
||||||
|
|
||||||
pack.writeBitmaps (deprecated)::
|
pack.writeBitmaps (deprecated)::
|
||||||
This is a deprecated synonym for `repack.writeBitmaps`.
|
This is a deprecated synonym for `repack.writeBitmaps`.
|
||||||
|
1
Makefile
1
Makefile
@ -965,6 +965,7 @@ LIB_OBJS += refspec.o
|
|||||||
LIB_OBJS += ref-filter.o
|
LIB_OBJS += ref-filter.o
|
||||||
LIB_OBJS += remote.o
|
LIB_OBJS += remote.o
|
||||||
LIB_OBJS += replace-object.o
|
LIB_OBJS += replace-object.o
|
||||||
|
LIB_OBJS += repo-settings.o
|
||||||
LIB_OBJS += repository.o
|
LIB_OBJS += repository.o
|
||||||
LIB_OBJS += rerere.o
|
LIB_OBJS += rerere.o
|
||||||
LIB_OBJS += resolve-undo.o
|
LIB_OBJS += resolve-undo.o
|
||||||
|
@ -41,7 +41,6 @@ static int aggressive_depth = 50;
|
|||||||
static int aggressive_window = 250;
|
static int aggressive_window = 250;
|
||||||
static int gc_auto_threshold = 6700;
|
static int gc_auto_threshold = 6700;
|
||||||
static int gc_auto_pack_limit = 50;
|
static int gc_auto_pack_limit = 50;
|
||||||
static int gc_write_commit_graph;
|
|
||||||
static int detach_auto = 1;
|
static int detach_auto = 1;
|
||||||
static timestamp_t gc_log_expire_time;
|
static timestamp_t gc_log_expire_time;
|
||||||
static const char *gc_log_expire = "1.day.ago";
|
static const char *gc_log_expire = "1.day.ago";
|
||||||
@ -148,7 +147,6 @@ static void gc_config(void)
|
|||||||
git_config_get_int("gc.aggressivedepth", &aggressive_depth);
|
git_config_get_int("gc.aggressivedepth", &aggressive_depth);
|
||||||
git_config_get_int("gc.auto", &gc_auto_threshold);
|
git_config_get_int("gc.auto", &gc_auto_threshold);
|
||||||
git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
|
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_bool("gc.autodetach", &detach_auto);
|
||||||
git_config_get_expiry("gc.pruneexpire", &prune_expire);
|
git_config_get_expiry("gc.pruneexpire", &prune_expire);
|
||||||
git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
|
git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
|
||||||
@ -685,11 +683,11 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
|
|||||||
clean_pack_garbage();
|
clean_pack_garbage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gc_write_commit_graph &&
|
prepare_repo_settings(the_repository);
|
||||||
|
if (the_repository->settings.gc_write_commit_graph == 1)
|
||||||
write_commit_graph_reachable(get_object_directory(),
|
write_commit_graph_reachable(get_object_directory(),
|
||||||
!quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
|
!quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
|
||||||
NULL))
|
NULL);
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (auto_gc && too_many_loose_objects())
|
if (auto_gc && too_many_loose_objects())
|
||||||
warning(_("There are too many unreachable loose objects; "
|
warning(_("There are too many unreachable loose objects; "
|
||||||
|
@ -2715,10 +2715,6 @@ static int git_pack_config(const char *k, const char *v, void *cb)
|
|||||||
use_bitmap_index_default = git_config_bool(k, v);
|
use_bitmap_index_default = git_config_bool(k, v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(k, "pack.usesparse")) {
|
|
||||||
sparse = git_config_bool(k, v);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!strcmp(k, "pack.threads")) {
|
if (!strcmp(k, "pack.threads")) {
|
||||||
delta_search_threads = git_config_int(k, v);
|
delta_search_threads = git_config_int(k, v);
|
||||||
if (delta_search_threads < 0)
|
if (delta_search_threads < 0)
|
||||||
@ -3343,6 +3339,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
|||||||
read_replace_refs = 0;
|
read_replace_refs = 0;
|
||||||
|
|
||||||
sparse = git_env_bool("GIT_TEST_PACK_SPARSE", 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);
|
reset_pack_idx_option(&pack_idx_opts);
|
||||||
git_config(git_pack_config, NULL);
|
git_config(git_pack_config, NULL);
|
||||||
|
|
||||||
|
@ -966,6 +966,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
|||||||
struct parse_opt_ctx_t ctx;
|
struct parse_opt_ctx_t ctx;
|
||||||
strbuf_getline_fn getline_fn;
|
strbuf_getline_fn getline_fn;
|
||||||
int parseopt_state = PARSE_OPT_UNKNOWN;
|
int parseopt_state = PARSE_OPT_UNKNOWN;
|
||||||
|
struct repository *r = the_repository;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT_BIT('q', NULL, &refresh_args.flags,
|
OPT_BIT('q', NULL, &refresh_args.flags,
|
||||||
N_("continue refresh even when index needs update"),
|
N_("continue refresh even when index needs update"),
|
||||||
@ -1180,11 +1181,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
|||||||
remove_split_index(&the_index);
|
remove_split_index(&the_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepare_repo_settings(r);
|
||||||
switch (untracked_cache) {
|
switch (untracked_cache) {
|
||||||
case UC_UNSPECIFIED:
|
case UC_UNSPECIFIED:
|
||||||
break;
|
break;
|
||||||
case UC_DISABLE:
|
case UC_DISABLE:
|
||||||
if (git_config_get_untracked_cache() == 1)
|
if (r->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)
|
||||||
warning(_("core.untrackedCache is set to true; "
|
warning(_("core.untrackedCache is set to true; "
|
||||||
"remove or change it, if you really want to "
|
"remove or change it, if you really want to "
|
||||||
"disable the untracked cache"));
|
"disable the untracked cache"));
|
||||||
@ -1196,7 +1198,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
|||||||
return !test_if_untracked_cache_is_supported();
|
return !test_if_untracked_cache_is_supported();
|
||||||
case UC_ENABLE:
|
case UC_ENABLE:
|
||||||
case UC_FORCE:
|
case UC_FORCE:
|
||||||
if (git_config_get_untracked_cache() == 0)
|
if (r->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)
|
||||||
warning(_("core.untrackedCache is set to false; "
|
warning(_("core.untrackedCache is set to false; "
|
||||||
"remove or change it, if you really want to "
|
"remove or change it, if you really want to "
|
||||||
"enable the untracked cache"));
|
"enable the untracked cache"));
|
||||||
|
@ -467,7 +467,6 @@ static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
|
|||||||
static int prepare_commit_graph(struct repository *r)
|
static int prepare_commit_graph(struct repository *r)
|
||||||
{
|
{
|
||||||
struct object_directory *odb;
|
struct object_directory *odb;
|
||||||
int config_value;
|
|
||||||
|
|
||||||
if (git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD, 0))
|
if (git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD, 0))
|
||||||
die("dying as requested by the '%s' variable on commit-graph load!",
|
die("dying as requested by the '%s' variable on commit-graph load!",
|
||||||
@ -477,9 +476,10 @@ static int prepare_commit_graph(struct repository *r)
|
|||||||
return !!r->objects->commit_graph;
|
return !!r->objects->commit_graph;
|
||||||
r->objects->commit_graph_attempted = 1;
|
r->objects->commit_graph_attempted = 1;
|
||||||
|
|
||||||
|
prepare_repo_settings(r);
|
||||||
|
|
||||||
if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
|
if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
|
||||||
(repo_config_get_bool(r, "core.commitgraph", &config_value) ||
|
r->settings.core_commit_graph != 1)
|
||||||
!config_value))
|
|
||||||
/*
|
/*
|
||||||
* This repository is not configured to use commit graphs, so
|
* This repository is not configured to use commit graphs, so
|
||||||
* do not load one. (But report commit_graph_attempted anyway
|
* do not load one. (But report commit_graph_attempted anyway
|
||||||
|
24
config.c
24
config.c
@ -2288,30 +2288,6 @@ int git_config_get_expiry_in_days(const char *key, timestamp_t *expiry, timestam
|
|||||||
return -1; /* thing exists but cannot be parsed */
|
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 git_config_get_split_index(void)
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
|
@ -2,19 +2,20 @@
|
|||||||
#include "fetch-negotiator.h"
|
#include "fetch-negotiator.h"
|
||||||
#include "negotiator/default.h"
|
#include "negotiator/default.h"
|
||||||
#include "negotiator/skipping.h"
|
#include "negotiator/skipping.h"
|
||||||
|
#include "repository.h"
|
||||||
|
|
||||||
void fetch_negotiator_init(struct fetch_negotiator *negotiator,
|
void fetch_negotiator_init(struct repository *r,
|
||||||
const char *algorithm)
|
struct fetch_negotiator *negotiator)
|
||||||
{
|
{
|
||||||
if (algorithm) {
|
prepare_repo_settings(r);
|
||||||
if (!strcmp(algorithm, "skipping")) {
|
switch(r->settings.fetch_negotiation_algorithm) {
|
||||||
|
case FETCH_NEGOTIATION_SKIPPING:
|
||||||
skipping_negotiator_init(negotiator);
|
skipping_negotiator_init(negotiator);
|
||||||
return;
|
return;
|
||||||
} else if (!strcmp(algorithm, "default")) {
|
|
||||||
/* Fall through to default initialization */
|
case FETCH_NEGOTIATION_DEFAULT:
|
||||||
} else {
|
default:
|
||||||
die("unknown fetch negotiation algorithm '%s'", algorithm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default_negotiator_init(negotiator);
|
default_negotiator_init(negotiator);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define FETCH_NEGOTIATOR_H
|
#define FETCH_NEGOTIATOR_H
|
||||||
|
|
||||||
struct commit;
|
struct commit;
|
||||||
|
struct repository;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An object that supplies the information needed to negotiate the contents of
|
* An object that supplies the information needed to negotiate the contents of
|
||||||
@ -52,7 +53,7 @@ struct fetch_negotiator {
|
|||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
void fetch_negotiator_init(struct fetch_negotiator *negotiator,
|
void fetch_negotiator_init(struct repository *r,
|
||||||
const char *algorithm);
|
struct fetch_negotiator *negotiator);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
11
fetch-pack.c
11
fetch-pack.c
@ -36,7 +36,6 @@ static int agent_supported;
|
|||||||
static int server_supports_filtering;
|
static int server_supports_filtering;
|
||||||
static struct lock_file shallow_lock;
|
static struct lock_file shallow_lock;
|
||||||
static const char *alternate_shallow_file;
|
static const char *alternate_shallow_file;
|
||||||
static char *negotiation_algorithm;
|
|
||||||
static struct strbuf fsck_msg_types = STRBUF_INIT;
|
static struct strbuf fsck_msg_types = STRBUF_INIT;
|
||||||
|
|
||||||
/* Remember to update object flag allocation in object.h */
|
/* Remember to update object flag allocation in object.h */
|
||||||
@ -892,12 +891,13 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
|||||||
struct shallow_info *si,
|
struct shallow_info *si,
|
||||||
char **pack_lockfile)
|
char **pack_lockfile)
|
||||||
{
|
{
|
||||||
|
struct repository *r = the_repository;
|
||||||
struct ref *ref = copy_ref_list(orig_ref);
|
struct ref *ref = copy_ref_list(orig_ref);
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
const char *agent_feature;
|
const char *agent_feature;
|
||||||
int agent_len;
|
int agent_len;
|
||||||
struct fetch_negotiator negotiator;
|
struct fetch_negotiator negotiator;
|
||||||
fetch_negotiator_init(&negotiator, negotiation_algorithm);
|
fetch_negotiator_init(r, &negotiator);
|
||||||
|
|
||||||
sort_ref_list(&ref, ref_compare_name);
|
sort_ref_list(&ref, ref_compare_name);
|
||||||
QSORT(sought, nr_sought, cmp_ref_by_name);
|
QSORT(sought, nr_sought, cmp_ref_by_name);
|
||||||
@ -911,7 +911,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
|||||||
|
|
||||||
if (server_supports("shallow"))
|
if (server_supports("shallow"))
|
||||||
print_verbose(args, _("Server supports %s"), "shallow");
|
print_verbose(args, _("Server supports %s"), "shallow");
|
||||||
else if (args->depth > 0 || is_repository_shallow(the_repository))
|
else if (args->depth > 0 || is_repository_shallow(r))
|
||||||
die(_("Server does not support shallow clients"));
|
die(_("Server does not support shallow clients"));
|
||||||
if (args->depth > 0 || args->deepen_since || args->deepen_not)
|
if (args->depth > 0 || args->deepen_since || args->deepen_not)
|
||||||
args->deepen = 1;
|
args->deepen = 1;
|
||||||
@ -1379,6 +1379,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
|||||||
struct shallow_info *si,
|
struct shallow_info *si,
|
||||||
char **pack_lockfile)
|
char **pack_lockfile)
|
||||||
{
|
{
|
||||||
|
struct repository *r = the_repository;
|
||||||
struct ref *ref = copy_ref_list(orig_ref);
|
struct ref *ref = copy_ref_list(orig_ref);
|
||||||
enum fetch_state state = FETCH_CHECK_LOCAL;
|
enum fetch_state state = FETCH_CHECK_LOCAL;
|
||||||
struct oidset common = OIDSET_INIT;
|
struct oidset common = OIDSET_INIT;
|
||||||
@ -1386,7 +1387,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
|
|||||||
int in_vain = 0;
|
int in_vain = 0;
|
||||||
int haves_to_send = INITIAL_FLUSH;
|
int haves_to_send = INITIAL_FLUSH;
|
||||||
struct fetch_negotiator negotiator;
|
struct fetch_negotiator negotiator;
|
||||||
fetch_negotiator_init(&negotiator, negotiation_algorithm);
|
fetch_negotiator_init(r, &negotiator);
|
||||||
packet_reader_init(&reader, fd[0], NULL, 0,
|
packet_reader_init(&reader, fd[0], NULL, 0,
|
||||||
PACKET_READ_CHOMP_NEWLINE |
|
PACKET_READ_CHOMP_NEWLINE |
|
||||||
PACKET_READ_DIE_ON_ERR_PACKET);
|
PACKET_READ_DIE_ON_ERR_PACKET);
|
||||||
@ -1505,8 +1506,6 @@ static void fetch_pack_config(void)
|
|||||||
git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
|
git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
|
||||||
git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
|
git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
|
||||||
git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
|
git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
|
||||||
git_config_get_string("fetch.negotiationalgorithm",
|
|
||||||
&negotiation_algorithm);
|
|
||||||
|
|
||||||
git_config(fetch_pack_config_cb, NULL);
|
git_config(fetch_pack_config_cb, NULL);
|
||||||
}
|
}
|
||||||
|
30
read-cache.c
30
read-cache.c
@ -1599,16 +1599,17 @@ struct cache_entry *refresh_cache_entry(struct index_state *istate,
|
|||||||
|
|
||||||
#define INDEX_FORMAT_DEFAULT 3
|
#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 *envversion = getenv("GIT_INDEX_VERSION");
|
||||||
char *endp;
|
char *endp;
|
||||||
int value;
|
|
||||||
unsigned int version = INDEX_FORMAT_DEFAULT;
|
unsigned int version = INDEX_FORMAT_DEFAULT;
|
||||||
|
|
||||||
if (!envversion) {
|
if (!envversion) {
|
||||||
if (!git_config_get_int("index.version", &value))
|
prepare_repo_settings(r);
|
||||||
version = value;
|
|
||||||
|
if (r->settings.index_version >= 0)
|
||||||
|
version = r->settings.index_version;
|
||||||
if (version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < version) {
|
if (version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < version) {
|
||||||
warning(_("index.version set, but the value is invalid.\n"
|
warning(_("index.version set, but the value is invalid.\n"
|
||||||
"Using version %i"), INDEX_FORMAT_DEFAULT);
|
"Using version %i"), INDEX_FORMAT_DEFAULT);
|
||||||
@ -1844,18 +1845,17 @@ static void check_ce_order(struct index_state *istate)
|
|||||||
|
|
||||||
static void tweak_untracked_cache(struct index_state *istate)
|
static void tweak_untracked_cache(struct index_state *istate)
|
||||||
{
|
{
|
||||||
switch (git_config_get_untracked_cache()) {
|
struct repository *r = the_repository;
|
||||||
case -1: /* keep: do nothing */
|
|
||||||
break;
|
prepare_repo_settings(r);
|
||||||
case 0: /* false */
|
|
||||||
|
if (r->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE) {
|
||||||
remove_untracked_cache(istate);
|
remove_untracked_cache(istate);
|
||||||
break;
|
return;
|
||||||
case 1: /* true */
|
|
||||||
add_untracked_cache(istate);
|
|
||||||
break;
|
|
||||||
default: /* unknown value: do nothing */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)
|
||||||
|
add_untracked_cache(istate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tweak_split_index(struct index_state *istate)
|
static void tweak_split_index(struct index_state *istate)
|
||||||
@ -2765,7 +2765,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!istate->version) {
|
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))
|
if (git_env_bool("GIT_TEST_SPLIT_INDEX", 0))
|
||||||
init_split_index(istate);
|
init_split_index(istate);
|
||||||
}
|
}
|
||||||
|
64
repo-settings.c
Normal file
64
repo-settings.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "cache.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "repository.h"
|
||||||
|
|
||||||
|
#define UPDATE_DEFAULT_BOOL(s,v) do { if (s == -1) { s = v; } } while(0)
|
||||||
|
|
||||||
|
void prepare_repo_settings(struct repository *r)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
char *strval;
|
||||||
|
|
||||||
|
if (r->settings.initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Defaults */
|
||||||
|
memset(&r->settings, -1, sizeof(r->settings));
|
||||||
|
|
||||||
|
if (!repo_config_get_bool(r, "core.commitgraph", &value))
|
||||||
|
r->settings.core_commit_graph = value;
|
||||||
|
if (!repo_config_get_bool(r, "gc.writecommitgraph", &value))
|
||||||
|
r->settings.gc_write_commit_graph = value;
|
||||||
|
UPDATE_DEFAULT_BOOL(r->settings.core_commit_graph, 1);
|
||||||
|
UPDATE_DEFAULT_BOOL(r->settings.gc_write_commit_graph, 1);
|
||||||
|
|
||||||
|
if (!repo_config_get_bool(r, "index.version", &value))
|
||||||
|
r->settings.index_version = value;
|
||||||
|
if (!repo_config_get_maybe_bool(r, "core.untrackedcache", &value)) {
|
||||||
|
if (value == 0)
|
||||||
|
r->settings.core_untracked_cache = UNTRACKED_CACHE_REMOVE;
|
||||||
|
else
|
||||||
|
r->settings.core_untracked_cache = UNTRACKED_CACHE_WRITE;
|
||||||
|
} else if (!repo_config_get_string(r, "core.untrackedcache", &strval)) {
|
||||||
|
if (!strcasecmp(strval, "keep"))
|
||||||
|
r->settings.core_untracked_cache = UNTRACKED_CACHE_KEEP;
|
||||||
|
|
||||||
|
free(strval);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!repo_config_get_string(r, "fetch.negotiationalgorithm", &strval)) {
|
||||||
|
if (!strcasecmp(strval, "skipping"))
|
||||||
|
r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING;
|
||||||
|
else
|
||||||
|
r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!repo_config_get_bool(r, "pack.usesparse", &value))
|
||||||
|
r->settings.pack_use_sparse = value;
|
||||||
|
if (!repo_config_get_bool(r, "feature.manyfiles", &value) && value) {
|
||||||
|
UPDATE_DEFAULT_BOOL(r->settings.index_version, 4);
|
||||||
|
UPDATE_DEFAULT_BOOL(r->settings.core_untracked_cache, UNTRACKED_CACHE_WRITE);
|
||||||
|
}
|
||||||
|
if (!repo_config_get_bool(r, "feature.experimental", &value) && value) {
|
||||||
|
UPDATE_DEFAULT_BOOL(r->settings.pack_use_sparse, 1);
|
||||||
|
UPDATE_DEFAULT_BOOL(r->settings.fetch_negotiation_algorithm, FETCH_NEGOTIATION_SKIPPING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hack for test programs like test-dump-untracked-cache */
|
||||||
|
if (ignore_untracked_cache_config)
|
||||||
|
r->settings.core_untracked_cache = UNTRACKED_CACHE_KEEP;
|
||||||
|
else
|
||||||
|
UPDATE_DEFAULT_BOOL(r->settings.core_untracked_cache, UNTRACKED_CACHE_KEEP);
|
||||||
|
|
||||||
|
UPDATE_DEFAULT_BOOL(r->settings.fetch_negotiation_algorithm, FETCH_NEGOTIATION_DEFAULT);
|
||||||
|
}
|
30
repository.h
30
repository.h
@ -11,6 +11,33 @@ struct pathspec;
|
|||||||
struct raw_object_store;
|
struct raw_object_store;
|
||||||
struct submodule_cache;
|
struct submodule_cache;
|
||||||
|
|
||||||
|
enum untracked_cache_setting {
|
||||||
|
UNTRACKED_CACHE_UNSET = -1,
|
||||||
|
UNTRACKED_CACHE_REMOVE = 0,
|
||||||
|
UNTRACKED_CACHE_KEEP = 1,
|
||||||
|
UNTRACKED_CACHE_WRITE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fetch_negotiation_setting {
|
||||||
|
FETCH_NEGOTIATION_UNSET = -1,
|
||||||
|
FETCH_NEGOTIATION_NONE = 0,
|
||||||
|
FETCH_NEGOTIATION_DEFAULT = 1,
|
||||||
|
FETCH_NEGOTIATION_SKIPPING = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct repo_settings {
|
||||||
|
int initialized;
|
||||||
|
|
||||||
|
int core_commit_graph;
|
||||||
|
int gc_write_commit_graph;
|
||||||
|
|
||||||
|
int index_version;
|
||||||
|
enum untracked_cache_setting core_untracked_cache;
|
||||||
|
|
||||||
|
int pack_use_sparse;
|
||||||
|
enum fetch_negotiation_setting fetch_negotiation_algorithm;
|
||||||
|
};
|
||||||
|
|
||||||
struct repository {
|
struct repository {
|
||||||
/* Environment */
|
/* Environment */
|
||||||
/*
|
/*
|
||||||
@ -72,6 +99,8 @@ struct repository {
|
|||||||
*/
|
*/
|
||||||
char *submodule_prefix;
|
char *submodule_prefix;
|
||||||
|
|
||||||
|
struct repo_settings settings;
|
||||||
|
|
||||||
/* Subsystems */
|
/* Subsystems */
|
||||||
/*
|
/*
|
||||||
* Repository's config which contains key-value pairs from the usual
|
* Repository's config which contains key-value pairs from the usual
|
||||||
@ -157,5 +186,6 @@ int repo_read_index_unmerged(struct repository *);
|
|||||||
*/
|
*/
|
||||||
void repo_update_index_if_able(struct repository *, struct lock_file *);
|
void repo_update_index_if_able(struct repository *, struct lock_file *);
|
||||||
|
|
||||||
|
void prepare_repo_settings(struct repository *r);
|
||||||
|
|
||||||
#endif /* REPOSITORY_H */
|
#endif /* REPOSITORY_H */
|
||||||
|
@ -234,7 +234,7 @@ test_expect_success 'rev-list stops traversal at missing and promised commit' '
|
|||||||
|
|
||||||
git -C repo config core.repositoryformatversion 1 &&
|
git -C repo config core.repositoryformatversion 1 &&
|
||||||
git -C repo config extensions.partialclone "arbitrary string" &&
|
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 $(git -C repo rev-parse bar) out &&
|
||||||
! grep $FOO out
|
! grep $FOO out
|
||||||
'
|
'
|
||||||
|
@ -59,17 +59,38 @@ test_expect_success 'out of bounds index.version issues warning' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'GIT_INDEX_VERSION takes precedence over config' '
|
test_index_version () {
|
||||||
|
INDEX_VERSION_CONFIG=$1 &&
|
||||||
|
FEATURE_MANY_FILES=$2 &&
|
||||||
|
ENV_VAR_VERSION=$3
|
||||||
|
EXPECTED_OUTPUT_VERSION=$4 &&
|
||||||
(
|
(
|
||||||
rm -f .git/index &&
|
rm -f .git/index &&
|
||||||
GIT_INDEX_VERSION=4 &&
|
rm -f .git/config &&
|
||||||
export GIT_INDEX_VERSION &&
|
if test "$INDEX_VERSION_CONFIG" -ne 0
|
||||||
git config --add index.version 2 &&
|
then
|
||||||
|
git config --add index.version $INDEX_VERSION_CONFIG
|
||||||
|
fi &&
|
||||||
|
git config --add feature.manyFiles $FEATURE_MANY_FILES
|
||||||
|
if test "$ENV_VAR_VERSION" -ne 0
|
||||||
|
then
|
||||||
|
GIT_INDEX_VERSION=$ENV_VAR_VERSION &&
|
||||||
|
export GIT_INDEX_VERSION
|
||||||
|
else
|
||||||
|
unset GIT_INDEX_VERSION
|
||||||
|
fi &&
|
||||||
git add a 2>&1 &&
|
git add a 2>&1 &&
|
||||||
echo 4 >expect &&
|
echo $EXPECTED_OUTPUT_VERSION >expect &&
|
||||||
test-tool index-version <.git/index >actual &&
|
test-tool index-version <.git/index >actual &&
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
test_expect_success 'index version config precedence' '
|
||||||
|
test_index_version 2 false 4 4 &&
|
||||||
|
test_index_version 2 true 0 2 &&
|
||||||
|
test_index_version 0 true 0 4 &&
|
||||||
|
test_index_version 0 true 2 2
|
||||||
'
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
@ -24,11 +24,11 @@ test_expect_success 'check corruption' '
|
|||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'rev-list notices corruption (1)' '
|
test_expect_success 'rev-list notices corruption (1)' '
|
||||||
test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git rev-list HEAD
|
test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git -c core.commitGraph=false rev-list HEAD
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'rev-list notices corruption (2)' '
|
test_expect_success 'rev-list notices corruption (2)' '
|
||||||
test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git rev-list --objects HEAD
|
test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git -c core.commitGraph=false rev-list --objects HEAD
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'pack-objects notices corruption' '
|
test_expect_success 'pack-objects notices corruption' '
|
||||||
|
@ -8,6 +8,7 @@ GIT_TEST_COMMIT_GRAPH=0
|
|||||||
test_expect_success 'setup repo' '
|
test_expect_success 'setup repo' '
|
||||||
git init &&
|
git init &&
|
||||||
git config core.commitGraph true &&
|
git config core.commitGraph true &&
|
||||||
|
git config gc.writeCommitGraph false &&
|
||||||
infodir=".git/objects/info" &&
|
infodir=".git/objects/info" &&
|
||||||
graphdir="$infodir/commit-graphs" &&
|
graphdir="$infodir/commit-graphs" &&
|
||||||
test_oid_init
|
test_oid_init
|
||||||
@ -334,6 +335,7 @@ test_expect_success 'split across alternate where alternate is not split' '
|
|||||||
git clone --no-hardlinks . alt-split &&
|
git clone --no-hardlinks . alt-split &&
|
||||||
(
|
(
|
||||||
cd alt-split &&
|
cd alt-split &&
|
||||||
|
rm -f .git/objects/info/commit-graph &&
|
||||||
echo "$(pwd)"/../.git/objects >.git/objects/info/alternates &&
|
echo "$(pwd)"/../.git/objects >.git/objects/info/alternates &&
|
||||||
test_commit 18 &&
|
test_commit 18 &&
|
||||||
git commit-graph write --reachable --split &&
|
git commit-graph write --reachable --split &&
|
||||||
|
@ -60,29 +60,6 @@ test_expect_success 'commits with no parents are sent regardless of skip distanc
|
|||||||
have_not_sent c6 c4 c3
|
have_not_sent c6 c4 c3
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'unknown fetch.negotiationAlgorithm values error out' '
|
|
||||||
rm -rf server client trace &&
|
|
||||||
git init server &&
|
|
||||||
test_commit -C server to_fetch &&
|
|
||||||
|
|
||||||
git init client &&
|
|
||||||
test_commit -C client on_client &&
|
|
||||||
git -C client checkout on_client &&
|
|
||||||
|
|
||||||
test_config -C client fetch.negotiationAlgorithm invalid &&
|
|
||||||
test_must_fail git -C client fetch "$(pwd)/server" 2>err &&
|
|
||||||
test_i18ngrep "unknown fetch negotiation algorithm" err &&
|
|
||||||
|
|
||||||
# Explicit "default" value
|
|
||||||
test_config -C client fetch.negotiationAlgorithm default &&
|
|
||||||
git -C client -c fetch.negotiationAlgorithm=default fetch "$(pwd)/server" &&
|
|
||||||
|
|
||||||
# Implementation detail: If there is nothing to fetch, we will not error out
|
|
||||||
test_config -C client fetch.negotiationAlgorithm invalid &&
|
|
||||||
git -C client fetch "$(pwd)/server" 2>err &&
|
|
||||||
test_i18ngrep ! "unknown fetch negotiation algorithm" err
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'when two skips collide, favor the larger one' '
|
test_expect_success 'when two skips collide, favor the larger one' '
|
||||||
rm -rf server client trace &&
|
rm -rf server client trace &&
|
||||||
git init server &&
|
git init server &&
|
||||||
|
@ -42,7 +42,7 @@ test_expect_success 'corrupt second commit object' \
|
|||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'rev-list should fail' '
|
test_expect_success 'rev-list should fail' '
|
||||||
test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git rev-list --all > /dev/null
|
test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git -c core.commitGraph=false rev-list --all > /dev/null
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'git repack _MUST_ fail' \
|
test_expect_success 'git repack _MUST_ fail' \
|
||||||
|
@ -137,7 +137,7 @@ test_expect_success 'do not complain about existing broken links (commit)' '
|
|||||||
some message
|
some message
|
||||||
EOF
|
EOF
|
||||||
commit=$(git hash-object -t commit -w broken-commit) &&
|
commit=$(git hash-object -t commit -w broken-commit) &&
|
||||||
git gc 2>stderr &&
|
git gc -q 2>stderr &&
|
||||||
verbose git cat-file -e $commit &&
|
verbose git cat-file -e $commit &&
|
||||||
test_must_be_empty stderr
|
test_must_be_empty stderr
|
||||||
'
|
'
|
||||||
@ -147,7 +147,7 @@ test_expect_success 'do not complain about existing broken links (tree)' '
|
|||||||
100644 blob 0000000000000000000000000000000000000003 foo
|
100644 blob 0000000000000000000000000000000000000003 foo
|
||||||
EOF
|
EOF
|
||||||
tree=$(git mktree --missing <broken-tree) &&
|
tree=$(git mktree --missing <broken-tree) &&
|
||||||
git gc 2>stderr &&
|
git gc -q 2>stderr &&
|
||||||
git cat-file -e $tree &&
|
git cat-file -e $tree &&
|
||||||
test_must_be_empty stderr
|
test_must_be_empty stderr
|
||||||
'
|
'
|
||||||
@ -162,7 +162,7 @@ test_expect_success 'do not complain about existing broken links (tag)' '
|
|||||||
this is a broken tag
|
this is a broken tag
|
||||||
EOF
|
EOF
|
||||||
tag=$(git hash-object -t tag -w broken-tag) &&
|
tag=$(git hash-object -t tag -w broken-tag) &&
|
||||||
git gc 2>stderr &&
|
git gc -q 2>stderr &&
|
||||||
git cat-file -e $tag &&
|
git cat-file -e $tag &&
|
||||||
test_must_be_empty stderr
|
test_must_be_empty stderr
|
||||||
'
|
'
|
||||||
|
Reference in New Issue
Block a user