partial-clone: define partial clone settings in config

Create get and set routines for "partial clone" config settings. These will be used in a future commit by clone and fetch to remember the promisor remote and the default filter-spec. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff Hostetler committed Dec 8, 2017 at 15:58 UTC 1e1e39b308fe9dd68a3312992a06270da7dd07af
5 files changed +88 -15
cache.h
+1
@@ -861,6 +861,7 @@ extern int grafts_replace_parents;
861 #define GIT_REPO_VERSION_READ 1
862 extern int repository_format_precious_objects;
863 extern char *repository_format_partial_clone;
864 +extern const char *core_partial_clone_filter_default;
865
866 struct repository_format {
867 int version;
config.c
+5
@@ -1241,6 +1241,11 @@ static int git_default_core_config(const char *var, const char *value)
1241 return 0;
1242 }
1243
1244 + if (!strcmp(var, "core.partialclonefilter")) {
1245 + return git_config_string(&core_partial_clone_filter_default,
1246 + var, value);
1247 + }
1248 +
1249 /* Add other config variables here and to Documentation/config.txt. */
1250 return 0;
1251 }
environment.c
+1
@@ -28,6 +28,7 @@ int warn_on_object_refname_ambiguity = 1;
28 int ref_paranoia = -1;
29 int repository_format_precious_objects;
30 char *repository_format_partial_clone;
31 +const char *core_partial_clone_filter_default;
32 const char *git_commit_encoding;
33 const char *git_log_output_encoding;
34 const char *apply_default_whitespace;
list-objects-filter-options.c
+75 -15
@@ -21,29 +21,36 @@
21 * subordinate commands when necessary. We also "intern" the arg for
22 * the convenience of the current command.
23 */
24 -int parse_list_objects_filter(struct list_objects_filter_options *filter_options,
25 - const char *arg)
24 +static int gently_parse_list_objects_filter(
25 + struct list_objects_filter_options *filter_options,
26 + const char *arg,
27 + struct strbuf *errbuf)
28 {
29 const char *v0;
30
29 - if (filter_options->choice)
30 - die(_("multiple object filter types cannot be combined"));
31 + if (filter_options->choice) {
32 + if (errbuf) {
33 + strbuf_init(errbuf, 0);
34 + strbuf_addstr(
35 + errbuf,
36 + _("multiple filter-specs cannot be combined"));
37 + }
38 + return 1;
39 + }
40
41 filter_options->filter_spec = strdup(arg);
42
43 if (!strcmp(arg, "blob:none")) {
44 filter_options->choice = LOFC_BLOB_NONE;
45 return 0;
37 - }
46
39 - if (skip_prefix(arg, "blob:limit=", &v0)) {
40 - if (!git_parse_ulong(v0, &filter_options->blob_limit_value))
41 - die(_("invalid filter-spec expression '%s'"), arg);
42 - filter_options->choice = LOFC_BLOB_LIMIT;
43 - return 0;
44 - }
47 + } else if (skip_prefix(arg, "blob:limit=", &v0)) {
48 + if (git_parse_ulong(v0, &filter_options->blob_limit_value)) {
49 + filter_options->choice = LOFC_BLOB_LIMIT;
50 + return 0;
51 + }
52
46 - if (skip_prefix(arg, "sparse:oid=", &v0)) {
53 + } else if (skip_prefix(arg, "sparse:oid=", &v0)) {
54 struct object_context oc;
55 struct object_id sparse_oid;
56
@@ -57,15 +64,27 @@ int parse_list_objects_filter(struct list_objects_filter_options *filter_options
64 filter_options->sparse_oid_value = oiddup(&sparse_oid);
65 filter_options->choice = LOFC_SPARSE_OID;
66 return 0;
60 - }
67
62 - if (skip_prefix(arg, "sparse:path=", &v0)) {
68 + } else if (skip_prefix(arg, "sparse:path=", &v0)) {
69 filter_options->choice = LOFC_SPARSE_PATH;
70 filter_options->sparse_path_value = strdup(v0);
71 return 0;
72 }
73
68 - die(_("invalid filter-spec expression '%s'"), arg);
74 + if (errbuf) {
75 + strbuf_init(errbuf, 0);
76 + strbuf_addf(errbuf, "invalid filter-spec '%s'", arg);
77 + }
78 + memset(filter_options, 0, sizeof(*filter_options));
79 + return 1;
80 +}
81 +
82 +int parse_list_objects_filter(struct list_objects_filter_options *filter_options,
83 + const char *arg)
84 +{
85 + struct strbuf buf = STRBUF_INIT;
86 + if (gently_parse_list_objects_filter(filter_options, arg, &buf))
87 + die("%s", buf.buf);
88 return 0;
89 }
90
@@ -90,3 +109,44 @@ void list_objects_filter_release(
109 free(filter_options->sparse_path_value);
110 memset(filter_options, 0, sizeof(*filter_options));
111 }
112 +
113 +void partial_clone_register(
114 + const char *remote,
115 + const struct list_objects_filter_options *filter_options)
116 +{
117 + /*
118 + * Record the name of the partial clone remote in the
119 + * config and in the global variable -- the latter is
120 + * used throughout to indicate that partial clone is
121 + * enabled and to expect missing objects.
122 + */
123 + if (repository_format_partial_clone &&
124 + *repository_format_partial_clone &&
125 + strcmp(remote, repository_format_partial_clone))
126 + die(_("cannot change partial clone promisor remote"));
127 +
128 + git_config_set("core.repositoryformatversion", "1");
129 + git_config_set("extensions.partialclone", remote);
130 +
131 + repository_format_partial_clone = xstrdup(remote);
132 +
133 + /*
134 + * Record the initial filter-spec in the config as
135 + * the default for subsequent fetches from this remote.
136 + */
137 + core_partial_clone_filter_default =
138 + xstrdup(filter_options->filter_spec);
139 + git_config_set("core.partialclonefilter",
140 + core_partial_clone_filter_default);
141 +}
142 +
143 +void partial_clone_get_default_filter_spec(
144 + struct list_objects_filter_options *filter_options)
145 +{
146 + /*
147 + * Parse default value, but silently ignore it if it is invalid.
148 + */
149 + gently_parse_list_objects_filter(filter_options,
150 + core_partial_clone_filter_default,
151 + NULL);
152 +}
list-objects-filter-options.h
+6
@@ -58,4 +58,10 @@ int opt_parse_list_objects_filter(const struct option *opt,
58 void list_objects_filter_release(
59 struct list_objects_filter_options *filter_options);
60
61 +void partial_clone_register(
62 + const char *remote,
63 + const struct list_objects_filter_options *filter_options);
64 +void partial_clone_get_default_filter_spec(
65 + struct list_objects_filter_options *filter_options);
66 +
67 #endif /* LIST_OBJECTS_FILTER_OPTIONS_H */