Merge branch 'nd/shallow-deepen'
authorJunio C Hamano <gitster@pobox.com>
Mon, 10 Oct 2016 21:03:50 +0000 (14:03 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 Oct 2016 21:03:50 +0000 (14:03 -0700)
The existing "git fetch --depth=<n>" option was hard to use
correctly when making the history of an existing shallow clone
deeper. A new option, "--deepen=<n>", has been added to make this
easier to use. "git clone" also learned "--shallow-since=<date>"
and "--shallow-exclude=<tag>" options to make it easier to specify
"I am interested only in the recent N months worth of history" and
"Give me only the history since that version".

* nd/shallow-deepen: (27 commits)
fetch, upload-pack: --deepen=N extends shallow boundary by N commits
upload-pack: add get_reachable_list()
upload-pack: split check_unreachable() in two, prep for get_reachable_list()
t5500, t5539: tests for shallow depth excluding a ref
clone: define shallow clone boundary with --shallow-exclude
fetch: define shallow boundary with --shallow-exclude
upload-pack: support define shallow boundary by excluding revisions
refs: add expand_ref()
t5500, t5539: tests for shallow depth since a specific date
clone: define shallow clone boundary based on time with --shallow-since
fetch: define shallow boundary with --shallow-since
upload-pack: add deepen-since to cut shallow repos based on time
shallow.c: implement a generic shallow boundary finder based on rev-list
fetch-pack: use a separate flag for fetch in deepening mode
fetch-pack.c: mark strings for translating
fetch-pack: use a common function for verbose printing
fetch-pack: use skip_prefix() instead of starts_with()
upload-pack: move rev-list code out of check_non_tip()
upload-pack: make check_non_tip() clean things up on error
upload-pack: tighten number parsing at "deepen" lines
...

20 files changed:
1  2 
Documentation/fetch-options.txt
Documentation/git-clone.txt
Documentation/git-fetch-pack.txt
Documentation/gitremote-helpers.txt
Documentation/technical/pack-protocol.txt
Documentation/technical/protocol-capabilities.txt
builtin/clone.c
builtin/fetch-pack.c
builtin/fetch.c
commit.h
fetch-pack.c
refs.c
refs.h
remote-curl.c
shallow.c
t/t5500-fetch-pack.sh
transport-helper.c
transport.c
transport.h
upload-pack.c
Simple merge
index e316c4bd51a64fb9df87ce003f2edffad38b63ad,5049663f3b4d80bf90e9ba4ed696c493981e9a94..35cc34b2fb9a0e696eb86e208416fa93aae3c0c5
@@@ -194,9 -191,16 +194,17 @@@ objects from the source repository int
        Create a 'shallow' clone with a history truncated to the
        specified number of commits. Implies `--single-branch` unless
        `--no-single-branch` is given to fetch the histories near the
 -      tips of all branches.
 +      tips of all branches. If you want to clone submodules shallowly,
 +      also pass `--shallow-submodules`.
  
+ --shallow-since=<date>::
+       Create a shallow clone with a history after the specified time.
+ --shallow-exclude=<revision>::
+       Create a shallow clone with a history, excluding commits
+       reachable from a specified remote branch or tag.  This option
+       can be specified multiple times.
  --[no-]single-branch::
        Clone only the history leading to the tip of a single branch,
        either specified by the `--branch` option or the primary
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc builtin/clone.c
index fb75f7ee64a29e4bb79f163e82c73bb8a7bd5280,38492315a6d30087ff7a86a1a2dc67e5d6747357..6c80690adf32dfe55a3a587a85f36e279ccd150e
@@@ -40,10 -40,11 +40,12 @@@ static const char * const builtin_clone
  
  static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;
  static int option_local = -1, option_no_hardlinks, option_shared, option_recursive;
- static char *option_template, *option_depth;
 +static int option_shallow_submodules;
+ static int deepen;
+ static char *option_template, *option_depth, *option_since;
  static char *option_origin = NULL;
  static char *option_branch = NULL;
+ static struct string_list option_not = STRING_LIST_INIT_NODUP;
  static const char *real_git_dir;
  static char *option_upload_pack = "git-upload-pack";
  static int option_verbosity;
@@@ -94,10 -88,12 +96,14 @@@ static struct option builtin_clone_opti
                   N_("path to git-upload-pack on the remote")),
        OPT_STRING(0, "depth", &option_depth, N_("depth"),
                    N_("create a shallow clone of that depth")),
+       OPT_STRING(0, "shallow-since", &option_since, N_("time"),
+                   N_("create a shallow clone since a specific time")),
+       OPT_STRING_LIST(0, "shallow-exclude", &option_not, N_("revision"),
+                       N_("deepen history of shallow clone by excluding rev")),
        OPT_BOOL(0, "single-branch", &option_single_branch,
                    N_("clone only one branch, HEAD or --branch")),
 +      OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules,
 +                  N_("any cloned submodules will be shallow")),
        OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
                   N_("separate git dir from working tree")),
        OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
Simple merge
diff --cc builtin/fetch.c
index 164623bb6f2eb3ffad3eac59b8ec440b9cf60d9c,7b0ea1c86ea8c3528d109faa4b9210c0d9cab875..d5329f915e57225e5046f33fae89f6348263f191
@@@ -35,13 -34,14 +35,15 @@@ static int fetch_prune_config = -1; /* 
  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_relative;
  static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
- static int tags = TAGS_DEFAULT, unshallow, update_shallow;
+ static int tags = TAGS_DEFAULT, unshallow, update_shallow, deepen;
 -static int max_children = 1;
 +static int max_children = -1;
 +static enum transport_family family;
  static const char *depth;
+ static const char *deepen_since;
  static const char *upload_pack;
+ static struct string_list deepen_not = STRING_LIST_INIT_NODUP;
  static struct strbuf default_rla = STRBUF_INIT;
  static struct transport *gtransport;
  static struct transport *gsecondary;
@@@ -875,10 -762,9 +883,10 @@@ static int quickfetch(struct ref *ref_m
         * really need to perform.  Claiming failure now will ensure
         * we perform the network exchange to deepen our history.
         */
-       if (depth)
+       if (deepen)
                return -1;
 -      return check_everything_connected(iterate_ref_map, 1, &rm);
 +      opt.quiet = 1;
 +      return check_connected(iterate_ref_map, &rm, &opt);
  }
  
  static int fetch_refs(struct transport *transport, struct ref *ref_map)
diff --cc commit.h
Simple merge
diff --cc fetch-pack.c
index 300763fae1e5b602108ad15020d4f50152778b2b,e2a235f536a2448feb9a396019ec6da5e3b9d609..cb45c346ea97059b66642b458c7ca372ece67aaa
@@@ -710,10 -717,8 +730,9 @@@ static int get_pack(struct fetch_pack_a
                demux.proc = sideband_demux;
                demux.data = xd;
                demux.out = -1;
 +              demux.isolate_sigpipe = 1;
                if (start_async(&demux))
-                       die("fetch-pack: unable to fork off sideband"
-                           " demultiplexer");
+                       die(_("fetch-pack: unable to fork off sideband demultiplexer"));
        }
        else
                demux.out = xd[0];
@@@ -819,17 -824,17 +838,17 @@@ static struct ref *do_fetch_pack(struc
        int agent_len;
  
        sort_ref_list(&ref, ref_compare_name);
 -      qsort(sought, nr_sought, sizeof(*sought), cmp_ref_by_name);
 +      QSORT(sought, nr_sought, cmp_ref_by_name);
  
        if ((args->depth > 0 || is_repository_shallow()) && !server_supports("shallow"))
-               die("Server does not support shallow clients");
+               die(_("Server does not support shallow clients"));
+       if (args->depth > 0 || args->deepen_since || args->deepen_not)
+               args->deepen = 1;
        if (server_supports("multi_ack_detailed")) {
-               if (args->verbose)
-                       fprintf(stderr, "Server supports multi_ack_detailed\n");
+               print_verbose(args, _("Server supports multi_ack_detailed"));
                multi_ack = 2;
                if (server_supports("no-done")) {
-                       if (args->verbose)
-                               fprintf(stderr, "Server supports no-done\n");
+                       print_verbose(args, _("Server supports no-done"));
                        if (args->stateless_rpc)
                                no_done = 1;
                }
diff --cc refs.c
Simple merge
diff --cc refs.h
index fe51280fc61d24eccca0e38f8fc75ecee7fcb751,31a2fa68a37306f9d707d89c7dea8a022a9a44a8..69478439137d64f6dab7f20d4f157f6c7a982ac2
--- 1/refs.h
--- 2/refs.h
+++ b/refs.h
@@@ -92,10 -88,11 +92,11 @@@ int resolve_gitlink_ref(const char *sub
   * full_name according to the rules defined by ref_rev_parse_rules in
   * refs.c.
   */
 -extern int refname_match(const char *abbrev_name, const char *full_name);
 +int refname_match(const char *abbrev_name, const char *full_name);
  
 -extern int expand_ref(const char *str, int len, unsigned char *sha1, char **ref);
 -extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
 -extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
++int expand_ref(const char *str, int len, unsigned char *sha1, char **ref);
 +int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
 +int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
  
  /*
   * A ref_transaction represents a collection of ref updates
diff --cc remote-curl.c
index 6b83b7783e9c62fcf623acd0ba034dd1c0b9bd10,d56412deb14237fcb4c5dca1f11cda1ae8f4fcdf..f14c41f4c0d6d6c9bbfd18d6417d16f0e6068c1d
@@@ -721,12 -716,11 +741,12 @@@ static int rpc_service(struct rpc_stat
  static int fetch_dumb(int nr_heads, struct ref **to_fetch)
  {
        struct walker *walker;
 -      char **targets = xmalloc(nr_heads * sizeof(char*));
 +      char **targets;
        int ret, i;
  
-       if (options.depth)
-               die("dumb http transport does not support --depth");
 +      ALLOC_ARRAY(targets, nr_heads);
+       if (options.depth || options.deepen_since)
+               die("dumb http transport does not support shallow capabilities");
        for (i = 0; i < nr_heads; i++)
                targets[i] = xstrdup(oid_to_hex(&to_fetch[i]->old_oid));
  
diff --cc shallow.c
Simple merge
Simple merge
Simple merge
diff --cc transport.c
index 94d6dc3725a2bb091df66ce6fe266ddd5317ed02,3e76a9af4d58fba352bcb89f0ea158f0b24b270a..a85801042b012c2e2684cbb4e5e3dc1925e43582
@@@ -148,9 -148,18 +148,18 @@@ static int set_git_option(struct git_tr
                        char *end;
                        opts->depth = strtol(value, &end, 0);
                        if (*end)
 -                              die("transport: invalid depth option '%s'", value);
 +                              die(_("transport: invalid depth option '%s'"), value);
                }
                return 0;
+       } else if (!strcmp(name, TRANS_OPT_DEEPEN_SINCE)) {
+               opts->deepen_since = value;
+               return 0;
+       } else if (!strcmp(name, TRANS_OPT_DEEPEN_NOT)) {
+               opts->deepen_not = (const struct string_list *)value;
+               return 0;
+       } else if (!strcmp(name, TRANS_OPT_DEEPEN_RELATIVE)) {
+               opts->deepen_relative = !!value;
+               return 0;
        }
        return 1;
  }
diff --cc transport.h
Simple merge
diff --cc upload-pack.c
index ca7f9417800bfb27a7dbc0559df8bec772c267fa,e40d15adaff6d164d72156ebddb9b4f152d92d96..5ec21e61d916999f4639162b8086115ad382f877
  #include "sigchain.h"
  #include "version.h"
  #include "string-list.h"
 +#include "parse-options.h"
+ #include "argv-array.h"
  
 -static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<n>] <dir>";
 +static const char * const upload_pack_usage[] = {
 +      N_("git upload-pack [<options>] <dir>"),
 +      NULL
 +};
  
  /* Remember to update object flag allocation in object.h */
  #define THEY_HAVE     (1u << 11)