Merge branch 'ep/http-configure-ssl-version'
authorJunio C Hamano <gitster@pobox.com>
Wed, 26 Aug 2015 22:45:31 +0000 (15:45 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 26 Aug 2015 22:45:31 +0000 (15:45 -0700)
A new configuration variable http.sslVersion can be used to specify
what specific version of SSL/TLS to use to make a connection.

* ep/http-configure-ssl-version:
http: add support for specifying the SSL version

1  2 
Documentation/config.txt
contrib/completion/git-completion.bash
http.c
diff --combined Documentation/config.txt
index 75ec02e8e90a57a54a768677a272975487f664a8,8d334c50e0d0ad1c7d506d69a1bc2016e07540ba..be557f4eeaf1f953bcbe758f4a08ed23336547b1
@@@ -769,14 -769,6 +769,14 @@@ am.keepcr:
        by giving '--no-keep-cr' from the command line.
        See linkgit:git-am[1], linkgit:git-mailsplit[1].
  
 +am.threeWay::
 +      By default, `git am` will fail if the patch does not apply cleanly. When
 +      set to true, this setting tells `git am` to fall back on 3-way merge if
 +      the patch records the identity of blobs it is supposed to apply to and
 +      we have those blobs available locally (equivalent to giving the `--3way`
 +      option from the command line). Defaults to `false`.
 +      See linkgit:git-am[1].
 +
  apply.ignoreWhitespace::
        When set to 'change', tells 'git apply' to ignore changes in
        whitespace, in the same way as the '--ignore-space-change'
@@@ -1250,25 -1242,6 +1250,25 @@@ filter.<driver>.smudge:
        object to a worktree file upon checkout.  See
        linkgit:gitattributes[5] for details.
  
 +fsck.<msg-id>::
 +      Allows overriding the message type (error, warn or ignore) of a
 +      specific message ID such as `missingEmail`.
 ++
 +For convenience, fsck prefixes the error/warning with the message ID,
 +e.g.  "missingEmail: invalid author/committer line - missing email" means
 +that setting `fsck.missingEmail = ignore` will hide that issue.
 ++
 +This feature is intended to support working with legacy repositories
 +which cannot be repaired without disruptive changes.
 +
 +fsck.skipList::
 +      The path to a sorted list of object names (i.e. one SHA-1 per
 +      line) that are known to be broken in a non-fatal way and should
 +      be ignored. This feature is useful when an established project
 +      should be accepted despite early commits containing errors that
 +      can be safely ignored such as invalid committer email addresses.
 +      Note: corrupt objects cannot be skipped with this setting.
 +
  gc.aggressiveDepth::
        The depth parameter used in the delta compression
        algorithm used by 'git gc --aggressive'.  This defaults
@@@ -1307,24 -1280,20 +1307,24 @@@ gc.packRefs:
  gc.pruneExpire::
        When 'git gc' is run, it will call 'prune --expire 2.weeks.ago'.
        Override the grace period with this config variable.  The value
 -      "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.
 +      "now" may be used to disable this grace period and always prune
 +      unreachable objects immediately, or "never" may be used to
 +      suppress pruning.
 +
 +gc.worktreePruneExpire::
 +      When 'git gc' is run, it calls
 +      'git worktree prune --expire 3.months.ago'.
 +      This config variable can be used to set a different grace
 +      period. The value "now" may be used to disable the grace
 +      period and prune $GIT_DIR/worktrees immediately, or "never"
 +      may be used to suppress pruning.
  
  gc.reflogExpire::
  gc.<pattern>.reflogExpire::
        'git reflog expire' removes reflog entries older than
 -      this time; defaults to 90 days.  With "<pattern>" (e.g.
 +      this time; defaults to 90 days. The value "now" expires all
 +      entries immediately, and "never" suppresses expiration
 +      altogether. With "<pattern>" (e.g.
        "refs/stash") in the middle the setting applies only to
        the refs that match the <pattern>.
  
@@@ -1332,9 -1301,7 +1332,9 @@@ gc.reflogExpireUnreachable:
  gc.<ref>.reflogExpireUnreachable::
        'git reflog expire' removes reflog entries older than
        this time and are not reachable from the current tip;
 -      defaults to 30 days.  With "<pattern>" (e.g. "refs/stash")
 +      defaults to 30 days. The value "now" expires all entries
 +      immediately, and "never" suppresses expiration altogether.
 +      With "<pattern>" (e.g. "refs/stash")
        in the middle, the setting applies only to the refs that
        match the <pattern>.
  
@@@ -1609,6 -1576,29 +1609,29 @@@ 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.sslVersion::
+       The SSL version to use when negotiating an SSL connection, if you
+       want to force the default.  The available and default version
+       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_VERSION' option; see the libcurl
+       documentation for more details on the format of this option and
+       for the ssl version supported. Actually the possible values of
+       this option are:
+       - sslv2
+       - sslv3
+       - tlsv1
+       - tlsv1.0
+       - tlsv1.1
+       - tlsv1.2
+ +
+ Can be overridden by the 'GIT_SSL_VERSION' environment variable.
+ To force git to use libcurl's default ssl version and ignore any
+ explicit http.sslversion option, set 'GIT_SSL_VERSION' to the
+ empty string.
  http.sslCipherList::
    A list of SSL ciphers to use when negotiating an SSL connection.
    The available ciphers depend on whether libcurl was built against
@@@ -2194,22 -2184,6 +2217,22 @@@ rebase.autoStash:
        successful rebase might result in non-trivial conflicts.
        Defaults to false.
  
 +rebase.missingCommitsCheck::
 +      If set to "warn", git rebase -i will print a warning if some
 +      commits are removed (e.g. a line was deleted), however the
 +      rebase will still proceed. If set to "error", it will print
 +      the previous warning and stop the rebase, 'git rebase
 +      --edit-todo' can then be used to correct the error. If set to
 +      "ignore", no checking is done.
 +      To drop a commit without warning or error, use the `drop`
 +      command in the todo-list.
 +      Defaults to "ignore".
 +
 +rebase.instructionFormat
 +      A format string, as specified in linkgit:git-log[1], to be used for
 +      the instruction list during an interactive rebase.  The format will automatically
 +      have the long commit hash prepended to the format.
 +
  receive.advertiseAtomic::
        By default, git-receive-pack will advertise the atomic push
        capability to its clients. If you don't want to this capability
@@@ -2246,28 -2220,6 +2269,28 @@@ receive.fsckObjects:
        Defaults to false. If not set, the value of `transfer.fsckObjects`
        is used instead.
  
 +receive.fsck.<msg-id>::
 +      When `receive.fsckObjects` is set to true, errors can be switched
 +      to warnings and vice versa by configuring the `receive.fsck.<msg-id>`
 +      setting where the `<msg-id>` is the fsck message ID and the value
 +      is one of `error`, `warn` or `ignore`. For convenience, fsck prefixes
 +      the error/warning with the message ID, e.g. "missingEmail: invalid
 +      author/committer line - missing email" means that setting
 +      `receive.fsck.missingEmail = ignore` will hide that issue.
 ++
 +This feature is intended to support working with legacy repositories
 +which would not pass pushing when `receive.fsckObjects = true`, allowing
 +the host to accept repositories with certain known issues but still catch
 +other issues.
 +
 +receive.fsck.skipList::
 +      The path to a sorted list of object names (i.e. one SHA-1 per
 +      line) that are known to be broken in a non-fatal way and should
 +      be ignored. This feature is useful when an established project
 +      should be accepted despite early commits containing errors that
 +      can be safely ignored such as invalid committer email addresses.
 +      Note: corrupt objects cannot be skipped with this setting.
 +
  receive.unpackLimit::
        If the number of objects received in a push is below this
        limit then the objects will be unpacked into loose object
@@@ -2313,10 -2265,13 +2336,10 @@@ receive.denyNonFastForwards:
        set when initializing a shared repository.
  
  receive.hideRefs::
 -      String(s) `receive-pack` uses to decide which refs to omit
 -      from its initial advertisement.  Use more than one
 -      definitions to specify multiple prefix strings. A ref that
 -      are under the hierarchies listed on the value of this
 -      variable is excluded, and is hidden when responding to `git
 -      push`, and an attempt to update or delete a hidden ref by
 -      `git push` is rejected.
 +      This variable is the same as `transfer.hideRefs`, but applies
 +      only to `receive-pack` (and so affects pushes, but not fetches).
 +      An attempt to update or delete a hidden ref by `git push` is
 +      rejected.
  
  receive.updateServerInfo::
        If set to true, git-receive-pack will run git-update-server-info
@@@ -2604,18 -2559,9 +2627,18 @@@ transfer.fsckObjects:
        Defaults to false.
  
  transfer.hideRefs::
 -      This variable can be used to set both `receive.hideRefs`
 -      and `uploadpack.hideRefs` at the same time to the same
 -      values.  See entries for these other variables.
 +      String(s) `receive-pack` and `upload-pack` use to decide which
 +      refs to omit from their initial advertisements.  Use more than
 +      one definition to specify multiple prefix strings. A ref that is
 +      under the hierarchies listed in the value of this variable is
 +      excluded, and is hidden when responding to `git push` or `git
 +      fetch`.  See `receive.hideRefs` and `uploadpack.hideRefs` for
 +      program-specific versions of this config.
 ++
 +You may also include a `!` in front of the ref name to negate the entry,
 +explicitly exposing it, even if an earlier entry marked it as hidden.
 +If you have multiple hideRefs values, later entries override earlier ones
 +(and entries in more-specific config files override less-specific ones).
  
  transfer.unpackLimit::
        When `fetch.unpackLimit` or `receive.unpackLimit` are
@@@ -2630,10 -2576,13 +2653,10 @@@ uploadarchive.allowUnreachable:
        `false`.
  
  uploadpack.hideRefs::
 -      String(s) `upload-pack` uses to decide which refs to omit
 -      from its initial advertisement.  Use more than one
 -      definitions to specify multiple prefix strings. A ref that
 -      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`.
 +      This variable is the same as `transfer.hideRefs`, but applies
 +      only to `upload-pack` (and so affects only fetches, not pushes).
 +      An attempt to fetch a hidden ref by `git fetch` will fail.  See
 +      also `uploadpack.allowTipSHA1InWant`.
  
  uploadpack.allowTipSHA1InWant::
        When `uploadpack.hideRefs` is in effect, allow `upload-pack`
index 087771bb89d05b0353f6759cfd03da3a953a798b,6e9359c2901f4bc72a3e49c84cbfed17487a9dfc..3da7dc209d4dc79c078027cc0c17dc5df6911901
@@@ -1667,10 -1667,7 +1667,10 @@@ _git_push (
  _git_rebase ()
  {
        local dir="$(__gitdir)"
 -      if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
 +      if [ -f "$dir"/rebase-merge/interactive ]; then
 +              __gitcomp "--continue --skip --abort --edit-todo"
 +              return
 +      elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
                __gitcomp "--continue --skip --abort"
                return
        fi
@@@ -2121,6 -2118,7 +2121,7 @@@ _git_config (
                http.postBuffer
                http.proxy
                http.sslCipherList
+               http.sslVersion
                http.sslCAInfo
                http.sslCAPath
                http.sslCert
diff --combined http.c
index 8cd59f7f36a86b4d355bc6a3ff123c822bdc0078,f365360678fc7ef6c38d5b49a3ea4eaeb5b20c54..9dce38025c7b35f7f5ad19121c0529b442aec92d
--- 1/http.c
--- 2/http.c
+++ b/http.c
@@@ -37,6 -37,20 +37,20 @@@ static int curl_ssl_verify = -1
  static int curl_ssl_try;
  static const char *ssl_cert;
  static const char *ssl_cipherlist;
+ static const char *ssl_version;
+ static struct {
+       const char *name;
+       long ssl_version;
+ } sslversions[] = {
+       { "sslv2", CURL_SSLVERSION_SSLv2 },
+       { "sslv3", CURL_SSLVERSION_SSLv3 },
+       { "tlsv1", CURL_SSLVERSION_TLSv1 },
+ #if LIBCURL_VERSION_NUM >= 0x072200
+       { "tlsv1.0", CURL_SSLVERSION_TLSv1_0 },
+       { "tlsv1.1", CURL_SSLVERSION_TLSv1_1 },
+       { "tlsv1.2", CURL_SSLVERSION_TLSv1_2 },
+ #endif
+ };
  #if LIBCURL_VERSION_NUM >= 0x070903
  static const char *ssl_key;
  #endif
@@@ -190,6 -204,8 +204,8 @@@ static int http_options(const char *var
        }
        if (!strcmp("http.sslcipherlist", var))
                return git_config_string(&ssl_cipherlist, var, value);
+       if (!strcmp("http.sslversion", var))
+               return git_config_string(&ssl_version, var, value);
        if (!strcmp("http.sslcert", var))
                return git_config_string(&ssl_cert, var, value);
  #if LIBCURL_VERSION_NUM >= 0x070903
@@@ -364,9 -380,24 +380,24 @@@ static CURL *get_curl_handle(void
        if (http_proactive_auth)
                init_curl_http_auth(result);
  
+       if (getenv("GIT_SSL_VERSION"))
+               ssl_version = getenv("GIT_SSL_VERSION");
+       if (ssl_version && *ssl_version) {
+               int i;
+               for (i = 0; i < ARRAY_SIZE(sslversions); i++) {
+                       if (!strcmp(ssl_version, sslversions[i].name)) {
+                               curl_easy_setopt(result, CURLOPT_SSLVERSION,
+                                                sslversions[i].ssl_version);
+                               break;
+                       }
+               }
+               if (i == ARRAY_SIZE(sslversions))
+                       warning("unsupported ssl version %s: using default",
+                               ssl_version);
+       }
        if (getenv("GIT_SSL_CIPHER_LIST"))
                ssl_cipherlist = getenv("GIT_SSL_CIPHER_LIST");
        if (ssl_cipherlist != NULL && *ssl_cipherlist)
                curl_easy_setopt(result, CURLOPT_SSL_CIPHER_LIST,
                                ssl_cipherlist);
@@@ -1318,7 -1349,7 +1349,7 @@@ static int http_get_file(const char *ur
        ret = http_request_reauth(url, result, HTTP_REQUEST_FILE, options);
        fclose(result);
  
 -      if (ret == HTTP_OK && move_temp_to_file(tmpfile.buf, filename))
 +      if (ret == HTTP_OK && finalize_object_file(tmpfile.buf, filename))
                ret = HTTP_ERROR;
  cleanup:
        strbuf_release(&tmpfile);
@@@ -1405,7 -1436,7 +1436,7 @@@ static int fetch_and_setup_pack_index(s
        ret = verify_pack_index(new_pack);
        if (!ret) {
                close_pack_index(new_pack);
 -              ret = move_temp_to_file(tmp_idx, sha1_pack_index_name(sha1));
 +              ret = finalize_object_file(tmp_idx, sha1_pack_index_name(sha1));
        }
        free(tmp_idx);
        if (ret)
@@@ -1517,8 -1548,8 +1548,8 @@@ int finish_http_pack_request(struct htt
  
        unlink(sha1_pack_index_name(p->sha1));
  
 -      if (move_temp_to_file(preq->tmpfile, sha1_pack_name(p->sha1))
 -       || move_temp_to_file(tmp_idx, sha1_pack_index_name(p->sha1))) {
 +      if (finalize_object_file(preq->tmpfile, sha1_pack_name(p->sha1))
 +       || finalize_object_file(tmp_idx, sha1_pack_index_name(p->sha1))) {
                free(tmp_idx);
                return -1;
        }
@@@ -1782,7 -1813,7 +1813,7 @@@ int finish_http_object_request(struct h
                return -1;
        }
        freq->rename =
 -              move_temp_to_file(freq->tmpfile, sha1_file_name(freq->sha1));
 +              finalize_object_file(freq->tmpfile, sha1_file_name(freq->sha1));
  
        return freq->rename;
  }