repo-settings: create feature.experimental setting
The 'feature.experimental' setting includes config options that are not committed to become defaults, but could use additional testing. Update the following config settings to take new defaults, and to use the repo_settings struct if not already using them: * 'pack.useSparse=true' * 'fetch.negotiationAlgorithm=skipping' In the case of fetch.negotiationAlgorithm, the existing logic would load the config option only when about to use the setting, so had a die() statement on an unknown string value. This is removed as now the config is parsed under prepare_repo_settings(). In general, this die() is probably misplaced and not valuable. A test was removed that checked this die() statement executed. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
c6cc4c5afd
commit
aaf633c2ad
@ -4,6 +4,20 @@ feature.*::
|
|||||||
developer community as recommended defaults and are subject to change.
|
developer community as recommended defaults and are subject to change.
|
||||||
In particular, new config options may be added with different defaults.
|
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::
|
feature.manyFiles::
|
||||||
Enable config options that optimize for repos with many files in the
|
Enable config options that optimize for repos with many files in the
|
||||||
working directory. With many files, commands such as `git status` and
|
working directory. With many files, commands such as `git status` and
|
||||||
|
@ -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].
|
||||||
|
@ -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`.
|
||||||
|
@ -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) {
|
||||||
skipping_negotiator_init(negotiator);
|
case FETCH_NEGOTIATION_SKIPPING:
|
||||||
return;
|
skipping_negotiator_init(negotiator);
|
||||||
} else if (!strcmp(algorithm, "default")) {
|
return;
|
||||||
/* Fall through to default initialization */
|
|
||||||
} else {
|
case FETCH_NEGOTIATION_DEFAULT:
|
||||||
die("unknown fetch negotiation algorithm '%s'", algorithm);
|
default:
|
||||||
}
|
default_negotiator_init(negotiator);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
default_negotiator_init(negotiator);
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -36,16 +36,29 @@ void prepare_repo_settings(struct repository *r)
|
|||||||
free(strval);
|
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))
|
if (!repo_config_get_bool(r, "pack.usesparse", &value))
|
||||||
r->settings.pack_use_sparse = value;
|
r->settings.pack_use_sparse = value;
|
||||||
if (!repo_config_get_bool(r, "feature.manyfiles", &value) && value) {
|
if (!repo_config_get_bool(r, "feature.manyfiles", &value) && value) {
|
||||||
UPDATE_DEFAULT_BOOL(r->settings.index_version, 4);
|
UPDATE_DEFAULT_BOOL(r->settings.index_version, 4);
|
||||||
UPDATE_DEFAULT_BOOL(r->settings.core_untracked_cache, UNTRACKED_CACHE_WRITE);
|
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 */
|
/* Hack for test programs like test-dump-untracked-cache */
|
||||||
if (ignore_untracked_cache_config)
|
if (ignore_untracked_cache_config)
|
||||||
r->settings.core_untracked_cache = UNTRACKED_CACHE_KEEP;
|
r->settings.core_untracked_cache = UNTRACKED_CACHE_KEEP;
|
||||||
else
|
else
|
||||||
UPDATE_DEFAULT_BOOL(r->settings.core_untracked_cache, UNTRACKED_CACHE_KEEP);
|
UPDATE_DEFAULT_BOOL(r->settings.core_untracked_cache, UNTRACKED_CACHE_KEEP);
|
||||||
|
|
||||||
|
UPDATE_DEFAULT_BOOL(r->settings.fetch_negotiation_algorithm, FETCH_NEGOTIATION_DEFAULT);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,13 @@ enum untracked_cache_setting {
|
|||||||
UNTRACKED_CACHE_WRITE = 2
|
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 {
|
struct repo_settings {
|
||||||
int initialized;
|
int initialized;
|
||||||
|
|
||||||
@ -28,6 +35,7 @@ struct repo_settings {
|
|||||||
enum untracked_cache_setting core_untracked_cache;
|
enum untracked_cache_setting core_untracked_cache;
|
||||||
|
|
||||||
int pack_use_sparse;
|
int pack_use_sparse;
|
||||||
|
enum fetch_negotiation_setting fetch_negotiation_algorithm;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct repository {
|
struct repository {
|
||||||
|
@ -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 &&
|
||||||
|
Loading…
Reference in New Issue
Block a user