Merge branch 'fm/fetch-raw-sha1'
authorJunio C Hamano <gitster@pobox.com>
Mon, 1 Jun 2015 19:45:19 +0000 (12:45 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 1 Jun 2015 19:45:19 +0000 (12:45 -0700)
"git upload-pack" that serves "git fetch" can be told to serve
commits that are not at the tip of any ref, as long as they are
reachable from a ref, with uploadpack.allowReachableSHA1InWant
configuration variable.

* fm/fetch-raw-sha1:
upload-pack: optionally allow fetching reachable sha1
upload-pack: prepare to extend allow-tip-sha1-in-want
config.txt: clarify allowTipSHA1InWant with camelCase

1  2 
Documentation/config.txt
upload-pack.c
diff --combined Documentation/config.txt
index 5f76e8cf4e5251d4bd414f9739247c752366070d,980520b655909753a2efc3f1510d2ef85679fcc9..4d21ce1647f6125584872c8c67823ae8368b1132
@@@ -453,8 -453,6 +453,8 @@@ false), while all other repositories ar
  
  core.worktree::
        Set the path to the root of the working tree.
 +      If GIT_COMMON_DIR environment variable is set, core.worktree
 +      is ignored and not used for determining the root of working tree.
        This can be overridden by the GIT_WORK_TREE environment
        variable and the '--work-tree' command-line option.
        The value can be an absolute path or relative to the path to
@@@ -624,12 -622,6 +624,12 @@@ core.commentChar:
  If set to "auto", `git-commit` would select a character that is not
  the beginning character of any line in existing commit messages.
  
 +core.packedRefsTimeout::
 +      The length of time, in milliseconds, to retry when trying to
 +      lock the `packed-refs` file. Value 0 means not to retry at
 +      all; -1 means to try indefinitely. Default is 1000 (i.e.,
 +      retry for 1 second).
 +
  sequence.editor::
        Text editor used by `git rebase -i` for editing the rebase instruction file.
        The value is meant to be interpreted by the shell when it is used.
@@@ -1282,13 -1274,6 +1282,13 @@@ gc.pruneExpire:
        "now" may be used to disable this  grace period and always prune
        unreachable objects immediately.
  
 +gc.pruneWorktreesExpire::
 +      When 'git gc' is run, it will call
 +      'prune --worktrees --expire 3.months.ago'.
 +      Override the grace period with this config variable. The value
 +      "now" may be used to disable the grace period and prune
 +      $GIT_DIR/worktrees immediately.
 +
  gc.reflogExpire::
  gc.<pattern>.reflogExpire::
        'git reflog expire' removes reflog entries older than
@@@ -1575,19 -1560,6 +1575,19 @@@ http.saveCookies:
        If set, store cookies received during requests to the file specified by
        http.cookieFile. Has no effect if http.cookieFile is unset.
  
 +http.sslCipherList::
 +  A list of SSL ciphers to use when negotiating an SSL connection.
 +  The available ciphers depend on whether libcurl was built against
 +  NSS or OpenSSL and the particular configuration of the crypto
 +  library in use.  Internally this sets the 'CURLOPT_SSL_CIPHER_LIST'
 +  option; see the libcurl documentation for more details on the format
 +  of this list.
 ++
 +Can be overridden by the 'GIT_SSL_CIPHER_LIST' environment variable.
 +To force git to use libcurl's default cipher list and ignore any
 +explicit http.sslCipherList option, set 'GIT_SSL_CIPHER_LIST' to the
 +empty string.
 +
  http.sslVerify::
        Whether to verify the SSL certificate when fetching or pushing
        over HTTPS. Can be overridden by the 'GIT_SSL_NO_VERIFY' environment
@@@ -2061,7 -2033,7 +2061,7 @@@ pull.ff:
        a case (equivalent to giving the `--no-ff` option from the command
        line). When set to `only`, only such fast-forward merges are
        allowed (equivalent to giving the `--ff-only` option from the
 -      command line).
 +      command line). This setting overrides `merge.ff` when pulling.
  
  pull.rebase::
        When true, rebase branches on top of the fetched branch, instead
@@@ -2298,18 -2270,18 +2298,18 @@@ remote.<name>.skipFetchAll:
  
  remote.<name>.receivepack::
        The default program to execute on the remote side when pushing.  See
 -      option \--receive-pack of linkgit:git-push[1].
 +      option --receive-pack of linkgit:git-push[1].
  
  remote.<name>.uploadpack::
        The default program to execute on the remote side when fetching.  See
 -      option \--upload-pack of linkgit:git-fetch-pack[1].
 +      option --upload-pack of linkgit:git-fetch-pack[1].
  
  remote.<name>.tagOpt::
 -      Setting this value to \--no-tags disables automatic tag following when
 -      fetching from remote <name>. Setting it to \--tags will fetch every
 +      Setting this value to --no-tags disables automatic tag following when
 +      fetching from remote <name>. Setting it to --tags will fetch every
        tag from remote <name>, even if they are not reachable from remote
        branch heads. Passing these flags directly to linkgit:git-fetch[1] can
 -      override this setting. See options \--tags and \--no-tags of
 +      override this setting. See options --tags and --no-tags of
        linkgit:git-fetch[1].
  
  remote.<name>.vcs::
@@@ -2558,14 -2530,20 +2558,20 @@@ uploadpack.hideRefs:
        are under the hierarchies listed on the value of this
        variable is excluded, and is hidden from `git ls-remote`,
        `git fetch`, etc.  An attempt to fetch a hidden ref by `git
-       fetch` will fail.  See also `uploadpack.allowtipsha1inwant`.
+       fetch` will fail.  See also `uploadpack.allowTipSHA1InWant`.
  
- uploadpack.allowtipsha1inwant::
+ uploadpack.allowTipSHA1InWant::
        When `uploadpack.hideRefs` is in effect, allow `upload-pack`
        to accept a fetch request that asks for an object at the tip
        of a hidden ref (by default, such a request is rejected).
        see also `uploadpack.hideRefs`.
  
+ uploadpack.allowReachableSHA1InWant::
+       Allow `upload-pack` to accept a fetch request that asks for an
+       object that is reachable from any ref tip. However, note that
+       calculating object reachability is computationally expensive.
+       Defaults to `false`.
  uploadpack.keepAlive::
        When `upload-pack` has started `pack-objects`, there may be a
        quiet period while `pack-objects` prepares the pack. Normally
diff --combined upload-pack.c
index 745fda8515313fa0629489f36aee0ba49fb7d822,5cb4ac4ccc319970d677cf470cdc889933fc5332..640eae1bbe7e3837bd06b8b5675299f29f7e6021
@@@ -35,7 -35,11 +35,11 @@@ static int multi_ack
  static int no_done;
  static int use_thin_pack, use_ofs_delta, use_include_tag;
  static int no_progress, daemon_mode;
- static int allow_tip_sha1_in_want;
+ /* Allow specifying sha1 if it is a ref tip. */
+ #define ALLOW_TIP_SHA1        01
+ /* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
+ #define ALLOW_REACHABLE_SHA1  02
+ static unsigned int allow_unadvertised_object_request;
  static int shallow_nr;
  static struct object_array have_obj;
  static struct object_array want_obj;
@@@ -74,7 -78,7 +78,7 @@@ static int write_one_shallow(const stru
  {
        FILE *fp = cb_data;
        if (graft->nr_parent == -1)
 -              fprintf(fp, "--shallow %s\n", sha1_to_hex(graft->sha1));
 +              fprintf(fp, "--shallow %s\n", oid_to_hex(&graft->oid));
        return 0;
  }
  
@@@ -442,8 -446,9 +446,9 @@@ static int get_common_commits(void
  
  static int is_our_ref(struct object *o)
  {
-       return o->flags &
-               ((allow_tip_sha1_in_want ? HIDDEN_REF : 0) | OUR_REF);
+       int allow_hidden_ref = (allow_unadvertised_object_request &
+                       (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1));
+       return o->flags & ((allow_hidden_ref ? HIDDEN_REF : 0) | OUR_REF);
  }
  
  static void check_non_tip(void)
        char namebuf[42]; /* ^ + SHA-1 + LF */
        int i;
  
-       /* In the normal in-process case non-tip request can never happen */
-       if (!stateless_rpc)
+       /*
+        * In the normal in-process case without
+        * uploadpack.allowReachableSHA1InWant,
+        * non-tip requests can never happen.
+        */
+       if (!stateless_rpc && !(allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1))
                goto error;
  
        cmd.argv = argv;
@@@ -724,10 -733,13 +733,13 @@@ static int send_ref(const char *refname
                struct strbuf symref_info = STRBUF_INIT;
  
                format_symref_info(&symref_info, cb_data);
-               packet_write(1, "%s %s%c%s%s%s%s agent=%s\n",
+               packet_write(1, "%s %s%c%s%s%s%s%s agent=%s\n",
                             sha1_to_hex(sha1), refname_nons,
                             0, capabilities,
-                            allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "",
+                            (allow_unadvertised_object_request & ALLOW_TIP_SHA1) ?
+                                    " allow-tip-sha1-in-want" : "",
+                            (allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1) ?
+                                    " allow-reachable-sha1-in-want" : "",
                             stateless_rpc ? " no-done" : "",
                             symref_info.buf,
                             git_user_agent_sanitized());
@@@ -787,9 -799,17 +799,17 @@@ static void upload_pack(void
  
  static int upload_pack_config(const char *var, const char *value, void *unused)
  {
-       if (!strcmp("uploadpack.allowtipsha1inwant", var))
-               allow_tip_sha1_in_want = git_config_bool(var, value);
-       else if (!strcmp("uploadpack.keepalive", var)) {
+       if (!strcmp("uploadpack.allowtipsha1inwant", var)) {
+               if (git_config_bool(var, value))
+                       allow_unadvertised_object_request |= ALLOW_TIP_SHA1;
+               else
+                       allow_unadvertised_object_request &= ~ALLOW_TIP_SHA1;
+       } else if (!strcmp("uploadpack.allowreachablesha1inwant", var)) {
+               if (git_config_bool(var, value))
+                       allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
+               else
+                       allow_unadvertised_object_request &= ~ALLOW_REACHABLE_SHA1;
+       } else if (!strcmp("uploadpack.keepalive", var)) {
                keepalive = git_config_int(var, value);
                if (!keepalive)
                        keepalive = -1;