fetch: define shallow boundary with --shallow-since

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Jun 12, 2016 at 17:53 UTC 508ea88226bbdd25ac0aac4f9c8a65a2c3b5be5c
10 files changed +67 -9
Documentation/fetch-options.txt
+4
@@ -14,6 +14,10 @@
14 linkgit:git-clone[1]), deepen or shorten the history to the specified
15 number of commits. Tags for the deepened commits are not fetched.
16
17 +--shallow-since=<date>::
18 + Deepen or shorten the history of a shallow repository to
19 + include all reachable commits after <date>.
20 +
21 --unshallow::
22 If the source repository is complete, convert a shallow
23 repository to a complete one, removing all the limitations
Documentation/git-fetch-pack.txt
+4
@@ -87,6 +87,10 @@ be in a separate packet, and the list must end with a flush packet.
87 'git-upload-pack' treats the special depth 2147483647 as
88 infinite even if there is an ancestor-chain that long.
89
90 +--shallow-since=<date>::
91 + Deepen or shorten the history of a shallow'repository to
92 + include all reachable commits after <date>.
93 +
94 --no-progress::
95 Do not show the progress.
96
Documentation/gitremote-helpers.txt
+3
@@ -415,6 +415,9 @@ set by Git if the remote helper has the 'option' capability.
415 'option depth' <depth>::
416 Deepens the history of a shallow repository.
417
418 +'option deepen-since <timestamp>::
419 + Deepens the history of a shallow repository based on time.
420 +
421 'option followtags' {'true'|'false'}::
422 If enabled the helper should automatically fetch annotated
423 tag objects if the object the tag points at was transferred
builtin/fetch-pack.c
+4
@@ -104,6 +104,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
104 args.depth = strtol(arg, NULL, 0);
105 continue;
106 }
107 + if (skip_prefix(arg, "--shallow-since=", &arg)) {
108 + args.deepen_since = xstrdup(arg);
109 + continue;
110 + }
111 if (!strcmp("--no-progress", arg)) {
112 args.no_progress = 1;
113 continue;
builtin/fetch.c
+23 -6
@@ -36,9 +36,10 @@ static int prune = -1; /* unspecified */
36
37 static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;
38 static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
39 -static int tags = TAGS_DEFAULT, unshallow, update_shallow;
39 +static int tags = TAGS_DEFAULT, unshallow, update_shallow, deepen;
40 static int max_children = 1;
41 static const char *depth;
42 +static const char *deepen_since;
43 static const char *upload_pack;
44 static struct strbuf default_rla = STRBUF_INIT;
45 static struct transport *gtransport;
@@ -115,6 +116,8 @@ static struct option builtin_fetch_options[] = {
116 OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
117 OPT_STRING(0, "depth", &depth, N_("depth"),
118 N_("deepen history of shallow clone")),
119 + OPT_STRING(0, "shallow-since", &deepen_since, N_("time"),
120 + N_("deepen history of shallow repository based on time")),
121 { OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
122 N_("convert to a complete repository"),
123 PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
@@ -754,7 +757,7 @@ static int quickfetch(struct ref *ref_map)
757 * really need to perform. Claiming failure now will ensure
758 * we perform the network exchange to deepen our history.
759 */
757 - if (depth)
760 + if (deepen)
761 return -1;
762 return check_everything_connected(iterate_ref_map, 1, &rm);
763 }
@@ -859,7 +862,7 @@ static void set_option(struct transport *transport, const char *name, const char
862 name, transport->url);
863 }
864
862 -static struct transport *prepare_transport(struct remote *remote)
865 +static struct transport *prepare_transport(struct remote *remote, int deepen)
866 {
867 struct transport *transport;
868 transport = transport_get(remote, NULL);
@@ -870,6 +873,8 @@ static struct transport *prepare_transport(struct remote *remote)
873 set_option(transport, TRANS_OPT_KEEP, "yes");
874 if (depth)
875 set_option(transport, TRANS_OPT_DEPTH, depth);
876 + if (deepen && deepen_since)
877 + set_option(transport, TRANS_OPT_DEEPEN_SINCE, deepen_since);
878 if (update_shallow)
879 set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
880 return transport;
@@ -877,8 +882,18 @@ static struct transport *prepare_transport(struct remote *remote)
882
883 static void backfill_tags(struct transport *transport, struct ref *ref_map)
884 {
880 - if (transport->cannot_reuse) {
881 - gsecondary = prepare_transport(transport->remote);
885 + int cannot_reuse;
886 +
887 + /*
888 + * Once we have set TRANS_OPT_DEEPEN_SINCE, we can't unset it
889 + * when remote helper is used (setting it to an empty string
890 + * is not unsetting). We could extend the remote helper
891 + * protocol for that, but for now, just force a new connection
892 + * without deepen-since.
893 + */
894 + cannot_reuse = transport->cannot_reuse || deepen_since;
895 + if (cannot_reuse) {
896 + gsecondary = prepare_transport(transport->remote, 0);
897 transport = gsecondary;
898 }
899
@@ -1095,7 +1110,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
1110 die(_("No remote repository specified. Please, specify either a URL or a\n"
1111 "remote name from which new revisions should be fetched."));
1112
1098 - gtransport = prepare_transport(remote);
1113 + gtransport = prepare_transport(remote, 1);
1114
1115 if (prune < 0) {
1116 /* no command line request */
@@ -1167,6 +1182,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
1182 /* no need to be strict, transport_set_option() will validate it again */
1183 if (depth && atoi(depth) < 1)
1184 die(_("depth %s is not a positive number"), depth);
1185 + if (depth || deepen_since)
1186 + deepen = 1;
1187
1188 if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
1189 if (recurse_submodules_default) {
fetch-pack.c
+11 -1
@@ -21,6 +21,7 @@ static int fetch_unpack_limit = -1;
21 static int unpack_limit = 100;
22 static int prefer_ofs_delta = 1;
23 static int no_done;
24 +static int deepen_since_ok;
25 static int fetch_fsck_objects = -1;
26 static int transfer_fsck_objects = -1;
27 static int agent_supported;
@@ -326,6 +327,7 @@ static int find_common(struct fetch_pack_args *args,
327 if (args->no_progress) strbuf_addstr(&c, " no-progress");
328 if (args->include_tag) strbuf_addstr(&c, " include-tag");
329 if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
330 + if (deepen_since_ok) strbuf_addstr(&c, " deepen-since");
331 if (agent_supported) strbuf_addf(&c, " agent=%s",
332 git_user_agent_sanitized());
333 packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
@@ -345,6 +347,10 @@ static int find_common(struct fetch_pack_args *args,
347 write_shallow_commits(&req_buf, 1, NULL);
348 if (args->depth > 0)
349 packet_buf_write(&req_buf, "deepen %d", args->depth);
350 + if (args->deepen_since) {
351 + unsigned long max_age = approxidate(args->deepen_since);
352 + packet_buf_write(&req_buf, "deepen-since %lu", max_age);
353 + }
354 packet_buf_flush(&req_buf);
355 state_len = req_buf.len;
356
@@ -812,7 +818,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
818
819 if ((args->depth > 0 || is_repository_shallow()) && !server_supports("shallow"))
820 die(_("Server does not support shallow clients"));
815 - if (args->depth > 0)
821 + if (args->depth > 0 || args->deepen_since)
822 args->deepen = 1;
823 if (server_supports("multi_ack_detailed")) {
824 print_verbose(args, _("Server supports multi_ack_detailed"));
@@ -860,6 +866,10 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
866 print_verbose(args, _("Server version is %.*s"),
867 agent_len, agent_feature);
868 }
869 + if (server_supports("deepen-since"))
870 + deepen_since_ok = 1;
871 + else if (args->deepen_since)
872 + die(_("Server does not support --shallow-since"));
873
874 if (everything_local(args, &ref, sought, nr_sought)) {
875 packet_flush(fd[1]);
fetch-pack.h
+1
@@ -10,6 +10,7 @@ struct fetch_pack_args {
10 const char *uploadpack;
11 int unpacklimit;
12 int depth;
13 + const char *deepen_since;
14 unsigned quiet:1;
15 unsigned keep_pack:1;
16 unsigned lock_pack:1;
remote-curl.c
+9 -2
@@ -20,6 +20,7 @@ static struct strbuf url = STRBUF_INIT;
20 struct options {
21 int verbosity;
22 unsigned long depth;
23 + char *deepen_since;
24 unsigned progress : 1,
25 check_self_contained_and_connected : 1,
26 cloning : 1,
@@ -60,6 +61,10 @@ static int set_option(const char *name, const char *value)
61 options.depth = v;
62 return 0;
63 }
64 + else if (!strcmp(name, "deepen-since")) {
65 + options.deepen_since = xstrdup(value);
66 + return 0;
67 + }
68 else if (!strcmp(name, "followtags")) {
69 if (!strcmp(value, "true"))
70 options.followtags = 1;
@@ -699,8 +704,8 @@ static int fetch_dumb(int nr_heads, struct ref **to_fetch)
704 char **targets = xmalloc(nr_heads * sizeof(char*));
705 int ret, i;
706
702 - if (options.depth)
703 - die("dumb http transport does not support --depth");
707 + if (options.depth || options.deepen_since)
708 + die("dumb http transport does not support shallow capabilities");
709 for (i = 0; i < nr_heads; i++)
710 targets[i] = xstrdup(oid_to_hex(&to_fetch[i]->old_oid));
711
@@ -746,6 +751,8 @@ static int fetch_git(struct discovery *heads,
751 argv_array_push(&args, "--no-progress");
752 if (options.depth)
753 argv_array_pushf(&args, "--depth=%lu", options.depth);
754 + if (options.deepen_since)
755 + argv_array_pushf(&args, "--shallow-since=%s", options.deepen_since);
756 argv_array_push(&args, url.buf);
757
758 for (i = 0; i < nr_heads; i++) {
transport.c
+4
@@ -151,6 +151,9 @@ static int set_git_option(struct git_transport_options *opts,
151 die("transport: invalid depth option '%s'", value);
152 }
153 return 0;
154 + } else if (!strcmp(name, TRANS_OPT_DEEPEN_SINCE)) {
155 + opts->deepen_since = value;
156 + return 0;
157 }
158 return 1;
159 }
@@ -205,6 +208,7 @@ static int fetch_refs_via_pack(struct transport *transport,
208 args.quiet = (transport->verbose < 0);
209 args.no_progress = !transport->progress;
210 args.depth = data->options.depth;
211 + args.deepen_since = data->options.deepen_since;
212 args.check_self_contained_and_connected =
213 data->options.check_self_contained_and_connected;
214 args.cloning = transport->cloning;
transport.h
+4
@@ -13,6 +13,7 @@ struct git_transport_options {
13 unsigned self_contained_and_connected : 1;
14 unsigned update_shallow : 1;
15 int depth;
16 + const char *deepen_since;
17 const char *uploadpack;
18 const char *receivepack;
19 struct push_cas_option *cas;
@@ -171,6 +172,9 @@ int transport_restrict_protocols(void);
172 /* Limit the depth of the fetch if not null */
173 #define TRANS_OPT_DEPTH "depth"
174
175 +/* Limit the depth of the fetch based on time if not null */
176 +#define TRANS_OPT_DEEPEN_SINCE "deepen-since"
177 +
178 /* Aggressively fetch annotated tags if possible */
179 #define TRANS_OPT_FOLLOWTAGS "followtags"
180