This patch is just for discusstion. An option --deepen is added to 'git fetch'. When it comes to '--deepen', git should fetch N more commits ahead the local shallow commit, where N is indicated by '--depth=N'. [1] e.g. > (upstream) > ---o---o---o---A---B > > (you) > A---B After excuting "git fetch --depth=1 --deepen", (you) get one more tip and it becomes > (you) > o---A---B '--deepen' is designed to be a boolean option in this patch, which is a little different from [1]. It's designed in this way, because it can reuse '--depth' in the program, and just costs one more bit in some data structure, such as fetch_pack_args, git_transport_options. Of course, as a patch for discussion, it remains a long way to go before being complete. 1) Documents should be completed. 2) More test cases, expecially corner cases, should be added. 3) No need to get remote refs when it comes to '--deepen' option. 4) Validity on options combination should be checked. 5) smart-http protocol remains to be supported. [2] Besides, I still have one question: What does (you) exactly mean in [1]? The local branch or the local remote ref? I hope you could give me some comments and suggestions on this patch. I would like to know whether I'm off the right way. [1] http://article.gmane.org/gmane.comp.version-control.git/212950 [2] http://article.gmane.org/gmane.comp.version-control.git/265050 Helped-by: Duy Nguyen <pclouds@xxxxxxxxx> Signed-off-by: Dongcan Jiang <dongcan.jiang@xxxxxxxxx> --- builtin/fetch.c | 5 ++++- fetch-pack.c | 3 ++- fetch-pack.h | 1 + t/t5510-fetch.sh | 11 +++++++++++ transport.c | 4 ++++ transport.h | 4 ++++ upload-pack.c | 15 +++++++++++---- 7 files changed, 37 insertions(+), 6 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index f951265..6861207 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -33,7 +33,7 @@ static int fetch_prune_config = -1; /* unspecified */ static int prune = -1; /* unspecified */ #define PRUNE_BY_DEFAULT 0 /* do we prune by default? */ -static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity; +static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity, deepen; static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT; static int tags = TAGS_DEFAULT, unshallow, update_shallow; static const char *depth; @@ -111,6 +111,7 @@ static struct option builtin_fetch_options[] = { OPT_BOOL(0, "progress", &progress, N_("force progress reporting")), OPT_STRING(0, "depth", &depth, N_("depth"), N_("deepen history of shallow clone")), + OPT_BOOL(0, "deepen", &deepen, N_("deepen")), { OPTION_SET_INT, 0, "unshallow", &unshallow, NULL, N_("convert to a complete repository"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 }, @@ -853,6 +854,8 @@ static struct transport *prepare_transport(struct remote *remote) set_option(transport, TRANS_OPT_KEEP, "yes"); if (depth) set_option(transport, TRANS_OPT_DEPTH, depth); + if (deepen) + set_option(transport, TRANS_OPT_DEEPEN, "yes"); if (update_shallow) set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes"); return transport; diff --git a/fetch-pack.c b/fetch-pack.c index 655ee64..6f4adca 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -295,6 +295,7 @@ static int find_common(struct fetch_pack_args *args, if (no_done) strbuf_addstr(&c, " no-done"); if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k"); if (use_sideband == 1) strbuf_addstr(&c, " side-band"); + if (args->depth_deepen) strbuf_addstr(&c, " depth_deepen"); if (args->use_thin_pack) strbuf_addstr(&c, " thin-pack"); if (args->no_progress) strbuf_addstr(&c, " no-progress"); if (args->include_tag) strbuf_addstr(&c, " include-tag"); @@ -317,7 +318,7 @@ static int find_common(struct fetch_pack_args *args, if (is_repository_shallow()) write_shallow_commits(&req_buf, 1, NULL); if (args->depth > 0) - packet_buf_write(&req_buf, "deepen %d", args->depth); + packet_buf_write(&req_buf, "depth %d", args->depth); packet_buf_flush(&req_buf); state_len = req_buf.len; diff --git a/fetch-pack.h b/fetch-pack.h index bb7fd76..200ac78 100644 --- a/fetch-pack.h +++ b/fetch-pack.h @@ -10,6 +10,7 @@ struct fetch_pack_args { const char *uploadpack; int unpacklimit; int depth; + unsigned depth_deepen:1; unsigned quiet:1; unsigned keep_pack:1; unsigned lock_pack:1; diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index d78f320..6738006 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -708,4 +708,15 @@ test_expect_success 'fetching a one-level ref works' ' ) ' +test_expect_success 'fetching deepen' ' + git clone . deepen --depth=1 && + cd deepen && + git fetch .. foo --depth=1 + git show foo + test_must_fail git show foo~ + git fetch .. foo --depth=1 --deepen + git show foo~ + test_must_fail git show foo~2 +' + test_done diff --git a/transport.c b/transport.c index 0694a7c..53ee7b3 100644 --- a/transport.c +++ b/transport.c @@ -478,6 +478,9 @@ static int set_git_option(struct git_transport_options *opts, die("transport: invalid depth option '%s'", value); } return 0; + } else if (!strcmp(name, TRANS_OPT_DEEPEN)) { + opts->depth_deepen = !!value; + return 0; } else if (!strcmp(name, TRANS_OPT_PUSH_CERT)) { opts->push_cert = !!value; return 0; @@ -534,6 +537,7 @@ static int fetch_refs_via_pack(struct transport *transport, args.quiet = (transport->verbose < 0); args.no_progress = !transport->progress; args.depth = data->options.depth; + args.depth_deepen = data->options.depth_deepen; args.check_self_contained_and_connected = data->options.check_self_contained_and_connected; args.cloning = transport->cloning; diff --git a/transport.h b/transport.h index 18d2cf8..4f432fd 100644 --- a/transport.h +++ b/transport.h @@ -13,6 +13,7 @@ struct git_transport_options { unsigned self_contained_and_connected : 1; unsigned update_shallow : 1; unsigned push_cert : 1; + unsigned depth_deepen : 1; int depth; const char *uploadpack; const char *receivepack; @@ -153,6 +154,9 @@ struct transport *transport_get(struct remote *, const char *); /* Limit the depth of the fetch if not null */ #define TRANS_OPT_DEPTH "depth" +/* Limit the deepen of the fetch if not null */ +#define TRANS_OPT_DEEPEN "deepen" + /* Aggressively fetch annotated tags if possible */ #define TRANS_OPT_FOLLOWTAGS "followtags" diff --git a/upload-pack.c b/upload-pack.c index b531a32..8004f2f 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -31,6 +31,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=< static unsigned long oldest_have; +static int depth_deepen; static int multi_ack; static int no_done; static int use_thin_pack, use_ofs_delta, use_include_tag; @@ -563,11 +564,11 @@ static void receive_needs(void) } continue; } - if (starts_with(line, "deepen ")) { + if (starts_with(line, "depth ")) { char *end; - depth = strtol(line + 7, &end, 0); - if (end == line + 7 || depth <= 0) - die("Invalid deepen: %s", line); + depth = strtol(line + 6, &end, 0); + if (end == line + 6 || depth <= 0) + die("Invalid depth: %s", line); continue; } if (!starts_with(line, "want ") || @@ -577,6 +578,8 @@ static void receive_needs(void) features = line + 45; + if (parse_feature_request(features, "depth_deepen")) + depth_deepen = 1; if (parse_feature_request(features, "multi_ack_detailed")) multi_ack = 2; else if (parse_feature_request(features, "multi_ack")) @@ -631,6 +634,10 @@ static void receive_needs(void) struct object *object = shallows.objects[i].item; object->flags |= NOT_SHALLOW; } + else if (depth_deepen) + backup = result = + get_shallow_commits(&shallows, depth + 1, + SHALLOW, NOT_SHALLOW); else backup = result = get_shallow_commits(&want_obj, depth, -- 2.3.1.253.gb3fd89e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html