Skip to content

Commit a45a260

Browse files
pcloudsgitster
authored andcommitted
fetch: define shallow boundary with --shallow-exclude
Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 269a7a8 commit a45a260

File tree

11 files changed

+89
-4
lines changed

11 files changed

+89
-4
lines changed

Documentation/fetch-options.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
Deepen or shorten the history of a shallow repository to
1919
include all reachable commits after <date>.
2020

21+
--shallow-exclude=<revision>::
22+
Deepen or shorten the history of a shallow repository to
23+
exclude commits reachable from a specified remote branch or tag.
24+
This option can be specified multiple times.
25+
2126
--unshallow::
2227
If the source repository is complete, convert a shallow
2328
repository to a complete one, removing all the limitations

Documentation/git-fetch-pack.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ be in a separate packet, and the list must end with a flush packet.
9191
Deepen or shorten the history of a shallow'repository to
9292
include all reachable commits after <date>.
9393

94+
--shallow-exclude=<revision>::
95+
Deepen or shorten the history of a shallow repository to
96+
exclude commits reachable from a specified remote branch or tag.
97+
This option can be specified multiple times.
98+
9499
--no-progress::
95100
Do not show the progress.
96101

Documentation/gitremote-helpers.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,10 @@ set by Git if the remote helper has the 'option' capability.
418418
'option deepen-since <timestamp>::
419419
Deepens the history of a shallow repository based on time.
420420

421+
'option deepen-not <ref>::
422+
Deepens the history of a shallow repository excluding ref.
423+
Multiple options add up.
424+
421425
'option followtags' {'true'|'false'}::
422426
If enabled the helper should automatically fetch annotated
423427
tag objects if the object the tag points at was transferred

builtin/fetch-pack.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
5050
struct child_process *conn;
5151
struct fetch_pack_args args;
5252
struct sha1_array shallow = SHA1_ARRAY_INIT;
53+
struct string_list deepen_not = STRING_LIST_INIT_DUP;
5354

5455
packet_trace_identity("fetch-pack");
5556

@@ -108,6 +109,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
108109
args.deepen_since = xstrdup(arg);
109110
continue;
110111
}
112+
if (skip_prefix(arg, "--shallow-exclude=", &arg)) {
113+
string_list_append(&deepen_not, arg);
114+
continue;
115+
}
111116
if (!strcmp("--no-progress", arg)) {
112117
args.no_progress = 1;
113118
continue;
@@ -135,6 +140,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
135140
}
136141
usage(fetch_pack_usage);
137142
}
143+
if (deepen_not.nr)
144+
args.deepen_not = &deepen_not;
138145

139146
if (i < argc)
140147
dest = argv[i++];

builtin/fetch.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static int max_children = 1;
4141
static const char *depth;
4242
static const char *deepen_since;
4343
static const char *upload_pack;
44+
static struct string_list deepen_not = STRING_LIST_INIT_NODUP;
4445
static struct strbuf default_rla = STRBUF_INIT;
4546
static struct transport *gtransport;
4647
static struct transport *gsecondary;
@@ -118,6 +119,8 @@ static struct option builtin_fetch_options[] = {
118119
N_("deepen history of shallow clone")),
119120
OPT_STRING(0, "shallow-since", &deepen_since, N_("time"),
120121
N_("deepen history of shallow repository based on time")),
122+
OPT_STRING_LIST(0, "shallow-exclude", &deepen_not, N_("revision"),
123+
N_("deepen history of shallow clone by excluding rev")),
121124
{ OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
122125
N_("convert to a complete repository"),
123126
PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
@@ -875,6 +878,9 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
875878
set_option(transport, TRANS_OPT_DEPTH, depth);
876879
if (deepen && deepen_since)
877880
set_option(transport, TRANS_OPT_DEEPEN_SINCE, deepen_since);
881+
if (deepen && deepen_not.nr)
882+
set_option(transport, TRANS_OPT_DEEPEN_NOT,
883+
(const char *)&deepen_not);
878884
if (update_shallow)
879885
set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
880886
return transport;
@@ -889,9 +895,10 @@ static void backfill_tags(struct transport *transport, struct ref *ref_map)
889895
* when remote helper is used (setting it to an empty string
890896
* is not unsetting). We could extend the remote helper
891897
* protocol for that, but for now, just force a new connection
892-
* without deepen-since.
898+
* without deepen-since. Similar story for deepen-not.
893899
*/
894-
cannot_reuse = transport->cannot_reuse || deepen_since;
900+
cannot_reuse = transport->cannot_reuse ||
901+
deepen_since || deepen_not.nr;
895902
if (cannot_reuse) {
896903
gsecondary = prepare_transport(transport->remote, 0);
897904
transport = gsecondary;
@@ -1182,7 +1189,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
11821189
/* no need to be strict, transport_set_option() will validate it again */
11831190
if (depth && atoi(depth) < 1)
11841191
die(_("depth %s is not a positive number"), depth);
1185-
if (depth || deepen_since)
1192+
if (depth || deepen_since || deepen_not.nr)
11861193
deepen = 1;
11871194

11881195
if (recurse_submodules != RECURSE_SUBMODULES_OFF) {

fetch-pack.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ static int unpack_limit = 100;
2222
static int prefer_ofs_delta = 1;
2323
static int no_done;
2424
static int deepen_since_ok;
25+
static int deepen_not_ok;
2526
static int fetch_fsck_objects = -1;
2627
static int transfer_fsck_objects = -1;
2728
static int agent_supported;
@@ -328,6 +329,7 @@ static int find_common(struct fetch_pack_args *args,
328329
if (args->include_tag) strbuf_addstr(&c, " include-tag");
329330
if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
330331
if (deepen_since_ok) strbuf_addstr(&c, " deepen-since");
332+
if (deepen_not_ok) strbuf_addstr(&c, " deepen-not");
331333
if (agent_supported) strbuf_addf(&c, " agent=%s",
332334
git_user_agent_sanitized());
333335
packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
@@ -351,6 +353,13 @@ static int find_common(struct fetch_pack_args *args,
351353
unsigned long max_age = approxidate(args->deepen_since);
352354
packet_buf_write(&req_buf, "deepen-since %lu", max_age);
353355
}
356+
if (args->deepen_not) {
357+
int i;
358+
for (i = 0; i < args->deepen_not->nr; i++) {
359+
struct string_list_item *s = args->deepen_not->items + i;
360+
packet_buf_write(&req_buf, "deepen-not %s", s->string);
361+
}
362+
}
354363
packet_buf_flush(&req_buf);
355364
state_len = req_buf.len;
356365

@@ -818,7 +827,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
818827

819828
if ((args->depth > 0 || is_repository_shallow()) && !server_supports("shallow"))
820829
die(_("Server does not support shallow clients"));
821-
if (args->depth > 0 || args->deepen_since)
830+
if (args->depth > 0 || args->deepen_since || args->deepen_not)
822831
args->deepen = 1;
823832
if (server_supports("multi_ack_detailed")) {
824833
print_verbose(args, _("Server supports multi_ack_detailed"));
@@ -870,6 +879,10 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
870879
deepen_since_ok = 1;
871880
else if (args->deepen_since)
872881
die(_("Server does not support --shallow-since"));
882+
if (server_supports("deepen-not"))
883+
deepen_not_ok = 1;
884+
else if (args->deepen_not)
885+
die(_("Server does not support --shallow-exclude"));
873886

874887
if (everything_local(args, &ref, sought, nr_sought)) {
875888
packet_flush(fd[1]);

fetch-pack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ struct fetch_pack_args {
1111
int unpacklimit;
1212
int depth;
1313
const char *deepen_since;
14+
const struct string_list *deepen_not;
1415
unsigned quiet:1;
1516
unsigned keep_pack:1;
1617
unsigned lock_pack:1;

remote-curl.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct options {
2121
int verbosity;
2222
unsigned long depth;
2323
char *deepen_since;
24+
struct string_list deepen_not;
2425
unsigned progress : 1,
2526
check_self_contained_and_connected : 1,
2627
cloning : 1,
@@ -65,6 +66,10 @@ static int set_option(const char *name, const char *value)
6566
options.deepen_since = xstrdup(value);
6667
return 0;
6768
}
69+
else if (!strcmp(name, "deepen-not")) {
70+
string_list_append(&options.deepen_not, value);
71+
return 0;
72+
}
6873
else if (!strcmp(name, "followtags")) {
6974
if (!strcmp(value, "true"))
7075
options.followtags = 1;
@@ -753,6 +758,9 @@ static int fetch_git(struct discovery *heads,
753758
argv_array_pushf(&args, "--depth=%lu", options.depth);
754759
if (options.deepen_since)
755760
argv_array_pushf(&args, "--shallow-since=%s", options.deepen_since);
761+
for (i = 0; i < options.deepen_not.nr; i++)
762+
argv_array_pushf(&args, "--shallow-exclude=%s",
763+
options.deepen_not.items[i].string);
756764
argv_array_push(&args, url.buf);
757765

758766
for (i = 0; i < nr_heads; i++) {
@@ -973,6 +981,7 @@ int main(int argc, const char **argv)
973981
options.verbosity = 1;
974982
options.progress = !!isatty(2);
975983
options.thin = 1;
984+
string_list_init(&options.deepen_not, 1);
976985

977986
remote = remote_get(argv[1]);
978987

transport-helper.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,26 @@ static int strbuf_set_helper_option(struct helper_data *data,
282282
return ret;
283283
}
284284

285+
static int string_list_set_helper_option(struct helper_data *data,
286+
const char *name,
287+
struct string_list *list)
288+
{
289+
struct strbuf buf = STRBUF_INIT;
290+
int i, ret = 0;
291+
292+
for (i = 0; i < list->nr; i++) {
293+
strbuf_addf(&buf, "option %s ", name);
294+
quote_c_style(list->items[i].string, &buf, NULL, 0);
295+
strbuf_addch(&buf, '\n');
296+
297+
if ((ret = strbuf_set_helper_option(data, &buf)))
298+
break;
299+
strbuf_reset(&buf);
300+
}
301+
strbuf_release(&buf);
302+
return ret;
303+
}
304+
285305
static int set_helper_option(struct transport *transport,
286306
const char *name, const char *value)
287307
{
@@ -294,6 +314,10 @@ static int set_helper_option(struct transport *transport,
294314
if (!data->option)
295315
return 1;
296316

317+
if (!strcmp(name, "deepen-not"))
318+
return string_list_set_helper_option(data, name,
319+
(struct string_list *)value);
320+
297321
for (i = 0; i < ARRAY_SIZE(unsupported_options); i++) {
298322
if (!strcmp(name, unsupported_options[i]))
299323
return 1;

transport.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ static int set_git_option(struct git_transport_options *opts,
154154
} else if (!strcmp(name, TRANS_OPT_DEEPEN_SINCE)) {
155155
opts->deepen_since = value;
156156
return 0;
157+
} else if (!strcmp(name, TRANS_OPT_DEEPEN_NOT)) {
158+
opts->deepen_not = (const struct string_list *)value;
159+
return 0;
157160
}
158161
return 1;
159162
}
@@ -209,6 +212,7 @@ static int fetch_refs_via_pack(struct transport *transport,
209212
args.no_progress = !transport->progress;
210213
args.depth = data->options.depth;
211214
args.deepen_since = data->options.deepen_since;
215+
args.deepen_not = data->options.deepen_not;
212216
args.check_self_contained_and_connected =
213217
data->options.check_self_contained_and_connected;
214218
args.cloning = transport->cloning;

0 commit comments

Comments
 (0)