Skip to content

Commit 2e153fa

Browse files
committed
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' * 'merge.directoryRenames=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 <[email protected]>
1 parent 0d4774d commit 2e153fa

File tree

11 files changed

+84
-55
lines changed

11 files changed

+84
-55
lines changed

Documentation/config/feature.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ feature.*::
44
developer community as recommended defaults and are subject to change.
55
In particular, new config options may be added with different defaults.
66

7+
feature.experimental::
8+
Enable config options that are new to Git, and are being considered for
9+
future defaults. Config settings included here may be added or removed
10+
with each release, including minor version updates. These settings may
11+
have unintended interactions since they are so new. Please enable this
12+
setting if you are interested in providing feedback on experimental
13+
features. The new default values are:
14+
+
15+
* `pack.useSparse=true` uses a new algorithm when constructing a pack-file
16+
which can improve `git push` performance in repos with many files.
17+
+
18+
* `merge.directoryRenames=true` uses a new algorithm for detecting renames by
19+
using entire directories at a time instead of single files at a time.
20+
+
21+
* `fetch.negotiationAlgorithm=skipping` may improve fetch negotiation times by
22+
skipping more commits at a time, reducing the number of round trips.
23+
724
feature.manyCommits::
825
Enable config options that optimize for repos with many commits. This
926
setting is recommended for repos with at least 100,000 commits. The

Documentation/config/fetch.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ fetch.negotiationAlgorithm::
5959
effort to converge faster, but may result in a larger-than-necessary
6060
packfile; The default is "default" which instructs Git to use the default algorithm
6161
that never skips commits (unless the server has acknowledged it or one
62-
of its descendants).
62+
of its descendants). If `feature.experimental` is enabled, then this
63+
setting defaults to "skipping".
6364
Unknown values will cause 'git fetch' to error out.
6465
+
6566
See also the `--negotiation-tip` option for linkgit:git-fetch[1].

Documentation/config/merge.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ merge.directoryRenames::
5454
moved into the new directory. If set to "conflict", a conflict
5555
will be reported for such paths. If merge.renames is false,
5656
merge.directoryRenames is ignored and treated as false. Defaults
57-
to "conflict".
57+
to "conflict" unless `feature.experimental` is enabled and the
58+
default is "true".
5859

5960
merge.renormalize::
6061
Tell Git that canonical representation of files in the

Documentation/config/pack.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ pack.useSparse::
112112
objects. This can have significant performance benefits when
113113
computing a pack to send a small change. However, it is possible
114114
that extra objects are added to the pack-file if the included
115-
commits contain certain types of direct renames.
115+
commits contain certain types of direct renames. Default is `false`
116+
unless `feature.experimental` is enabled.
116117

117118
pack.writeBitmaps (deprecated)::
118119
This is a deprecated synonym for `repack.writeBitmaps`.

fetch-negotiator.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22
#include "fetch-negotiator.h"
33
#include "negotiator/default.h"
44
#include "negotiator/skipping.h"
5+
#include "repository.h"
56

6-
void fetch_negotiator_init(struct fetch_negotiator *negotiator,
7-
const char *algorithm)
7+
void fetch_negotiator_init(struct repository *r,
8+
struct fetch_negotiator *negotiator)
89
{
9-
if (algorithm) {
10-
if (!strcmp(algorithm, "skipping")) {
11-
skipping_negotiator_init(negotiator);
12-
return;
13-
} else if (!strcmp(algorithm, "default")) {
14-
/* Fall through to default initialization */
15-
} else {
16-
die("unknown fetch negotiation algorithm '%s'", algorithm);
17-
}
10+
prepare_repo_settings(r);
11+
switch(r->settings.fetch_negotiation_algorithm) {
12+
case FETCH_NEGOTIATION_SKIPPING:
13+
skipping_negotiator_init(negotiator);
14+
return;
15+
16+
case FETCH_NEGOTIATION_DEFAULT:
17+
default:
18+
default_negotiator_init(negotiator);
19+
return;
1820
}
19-
default_negotiator_init(negotiator);
2021
}

fetch-negotiator.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define FETCH_NEGOTIATOR_H
33

44
struct commit;
5+
struct repository;
56

67
/*
78
* An object that supplies the information needed to negotiate the contents of
@@ -52,7 +53,7 @@ struct fetch_negotiator {
5253
void *data;
5354
};
5455

55-
void fetch_negotiator_init(struct fetch_negotiator *negotiator,
56-
const char *algorithm);
56+
void fetch_negotiator_init(struct repository *r,
57+
struct fetch_negotiator *negotiator);
5758

5859
#endif

fetch-pack.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ static int agent_supported;
3636
static int server_supports_filtering;
3737
static struct lock_file shallow_lock;
3838
static const char *alternate_shallow_file;
39-
static char *negotiation_algorithm;
4039
static struct strbuf fsck_msg_types = STRBUF_INIT;
4140

4241
/* Remember to update object flag allocation in object.h */
@@ -892,12 +891,13 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
892891
struct shallow_info *si,
893892
char **pack_lockfile)
894893
{
894+
struct repository *r = the_repository;
895895
struct ref *ref = copy_ref_list(orig_ref);
896896
struct object_id oid;
897897
const char *agent_feature;
898898
int agent_len;
899899
struct fetch_negotiator negotiator;
900-
fetch_negotiator_init(&negotiator, negotiation_algorithm);
900+
fetch_negotiator_init(r, &negotiator);
901901

902902
sort_ref_list(&ref, ref_compare_name);
903903
QSORT(sought, nr_sought, cmp_ref_by_name);
@@ -911,7 +911,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
911911

912912
if (server_supports("shallow"))
913913
print_verbose(args, _("Server supports %s"), "shallow");
914-
else if (args->depth > 0 || is_repository_shallow(the_repository))
914+
else if (args->depth > 0 || is_repository_shallow(r))
915915
die(_("Server does not support shallow clients"));
916916
if (args->depth > 0 || args->deepen_since || args->deepen_not)
917917
args->deepen = 1;
@@ -1379,14 +1379,15 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
13791379
struct shallow_info *si,
13801380
char **pack_lockfile)
13811381
{
1382+
struct repository *r = the_repository;
13821383
struct ref *ref = copy_ref_list(orig_ref);
13831384
enum fetch_state state = FETCH_CHECK_LOCAL;
13841385
struct oidset common = OIDSET_INIT;
13851386
struct packet_reader reader;
13861387
int in_vain = 0;
13871388
int haves_to_send = INITIAL_FLUSH;
13881389
struct fetch_negotiator negotiator;
1389-
fetch_negotiator_init(&negotiator, negotiation_algorithm);
1390+
fetch_negotiator_init(r, &negotiator);
13901391
packet_reader_init(&reader, fd[0], NULL, 0,
13911392
PACKET_READ_CHOMP_NEWLINE |
13921393
PACKET_READ_DIE_ON_ERR_PACKET);
@@ -1505,8 +1506,6 @@ static void fetch_pack_config(void)
15051506
git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
15061507
git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
15071508
git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
1508-
git_config_get_string("fetch.negotiationalgorithm",
1509-
&negotiation_algorithm);
15101509

15111510
git_config(fetch_pack_config_cb, NULL);
15121511
}

merge-recursive.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3662,15 +3662,6 @@ static void merge_recursive_config(struct merge_options *opt)
36623662
opt->merge_detect_rename = git_config_rename("merge.renames", value);
36633663
free(value);
36643664
}
3665-
if (!git_config_get_string("merge.directoryrenames", &value)) {
3666-
int boolval = git_parse_maybe_bool(value);
3667-
if (0 <= boolval) {
3668-
opt->detect_directory_renames = boolval ? 2 : 0;
3669-
} else if (!strcasecmp(value, "conflict")) {
3670-
opt->detect_directory_renames = 1;
3671-
} /* avoid erroring on values from future versions of git */
3672-
free(value);
3673-
}
36743665
git_config(git_xmerge_config, NULL);
36753666
}
36763667

@@ -3688,6 +3679,11 @@ void init_merge_options(struct merge_options *opt,
36883679
opt->diff_detect_rename = -1;
36893680
opt->merge_detect_rename = -1;
36903681
opt->detect_directory_renames = 1;
3682+
3683+
prepare_repo_settings(repo);
3684+
if (repo->settings.merge_directory_renames >= 0)
3685+
opt->detect_directory_renames = repo->settings.merge_directory_renames;
3686+
36913687
merge_recursive_config(opt);
36923688
merge_verbosity = getenv("GIT_MERGE_VERBOSITY");
36933689
if (merge_verbosity)

repo-settings.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ void prepare_repo_settings(struct repository *r)
3434
free(strval);
3535
}
3636

37+
if (!repo_config_get_maybe_bool(r, "merge.directoryrenames", &value))
38+
r->settings.merge_directory_renames = value ? MERGE_DIRECTORY_RENAMES_TRUE : 0;
39+
else if (!repo_config_get_string(r, "merge.directoryrenames", &strval)) {
40+
if (!strcasecmp(strval, "conflict"))
41+
r->settings.merge_directory_renames = MERGE_DIRECTORY_RENAMES_CONFLICT;
42+
}
43+
if (!repo_config_get_string(r, "fetch.negotiationalgorithm", &strval)) {
44+
if (!strcasecmp(strval, "skipping"))
45+
r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING;
46+
else
47+
r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_DEFAULT;
48+
}
3749

3850
if (!repo_config_get_bool(r, "pack.usesparse", &value))
3951
r->settings.pack_use_sparse = value;
@@ -46,11 +58,18 @@ void prepare_repo_settings(struct repository *r)
4658
UPDATE_DEFAULT(r->settings.index_version, 4);
4759
UPDATE_DEFAULT(r->settings.core_untracked_cache, UNTRACKED_CACHE_WRITE);
4860
}
61+
if (!repo_config_get_bool(r, "feature.experimental", &value) && value) {
62+
UPDATE_DEFAULT(r->settings.pack_use_sparse, 1);
63+
UPDATE_DEFAULT(r->settings.merge_directory_renames, MERGE_DIRECTORY_RENAMES_TRUE);
64+
UPDATE_DEFAULT(r->settings.fetch_negotiation_algorithm, FETCH_NEGOTIATION_SKIPPING);
65+
}
4966

5067
/* Hack for test programs like test-dump-untracked-cache */
5168
if (ignore_untracked_cache_config)
5269
r->settings.core_untracked_cache = UNTRACKED_CACHE_KEEP;
5370
else
5471
UPDATE_DEFAULT(r->settings.core_untracked_cache, UNTRACKED_CACHE_KEEP);
5572

73+
UPDATE_DEFAULT(r->settings.merge_directory_renames, MERGE_DIRECTORY_RENAMES_CONFLICT);
74+
UPDATE_DEFAULT(r->settings.fetch_negotiation_algorithm, FETCH_NEGOTIATION_DEFAULT);
5675
}

repository.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ enum untracked_cache_setting {
1919
UNTRACKED_CACHE_WRITE = 2
2020
};
2121

22+
enum merge_directory_renames_setting {
23+
MERGE_DIRECTORY_RENAMES_UNSET = -1,
24+
MERGE_DIRECTORY_RENAMES_NONE = 0,
25+
MERGE_DIRECTORY_RENAMES_CONFLICT = 1,
26+
MERGE_DIRECTORY_RENAMES_TRUE = 2,
27+
};
28+
29+
enum fetch_negotiation_setting {
30+
FETCH_NEGOTIATION_UNSET = -1,
31+
FETCH_NEGOTIATION_NONE = 0,
32+
FETCH_NEGOTIATION_DEFAULT = 1,
33+
FETCH_NEGOTIATION_SKIPPING = 2,
34+
};
35+
2236
struct repo_settings {
2337
int initialized;
2438

@@ -29,6 +43,8 @@ struct repo_settings {
2943
enum untracked_cache_setting core_untracked_cache;
3044

3145
int pack_use_sparse;
46+
enum merge_directory_renames_setting merge_directory_renames;
47+
enum fetch_negotiation_setting fetch_negotiation_algorithm;
3248
};
3349

3450
struct repository {

0 commit comments

Comments
 (0)