Merge branch 'jn/ssh-wrappers'
authorJunio C Hamano <gitster@pobox.com>
Wed, 6 Dec 2017 17:23:45 +0000 (09:23 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 6 Dec 2017 17:23:45 +0000 (09:23 -0800)
The ssh-variant 'simple' introduced earlier broke existing
installations by not passing --port/-4/-6 and not diagnosing an
attempt to pass these as an error. Instead, default to
automatically detect how compatible the GIT_SSH/GIT_SSH_COMMAND is
to OpenSSH convention and then error out an invocation to make it
easier to diagnose connection errors.

* jn/ssh-wrappers:
connect: correct style of C-style comment
ssh: 'simple' variant does not support --port
ssh: 'simple' variant does not support -4/-6
ssh: 'auto' variant to select between 'ssh' and 'simple'
connect: split ssh option computation to its own function
connect: split ssh command line options into separate function
connect: split git:// setup into a separate function
connect: move no_fork fallback to git_tcp_connect
ssh test: make copy_ssh_wrapper_as clean up after itself

1  2 
Documentation/config.txt
t/t5601-clone.sh
diff --combined Documentation/config.txt
index 64bdce84356291a8c6eec7f37b75b53f7d548225,0c371ad7863841a265eebf1a267dd6fcc79a2a0d..c1598ee7039fca0439a18b31f186052bbb40bbce
@@@ -351,9 -351,6 +351,9 @@@ advice.*:
        addEmbeddedRepo::
                Advice on what to do when you've accidentally added one
                git repo inside of another.
 +      ignoredHook::
 +              Advice shown if an hook is ignored because the hook is not
 +              set as executable.
  --
  
  core.fileMode::
@@@ -416,13 -413,6 +416,13 @@@ core.protectNTFS:
        8.3 "short" names.
        Defaults to `true` on Windows, and `false` elsewhere.
  
 +core.fsmonitor::
 +      If set, the value of this variable is used as a command which
 +      will identify all files that may have changed since the
 +      requested date/time. This information is used to speed up git by
 +      avoiding unnecessary processing of files that have not changed.
 +      See the "fsmonitor-watchman" section of linkgit:githooks[5].
 +
  core.trustctime::
        If false, the ctime differences between the index and the
        working tree are ignored; useful when the inode change time
@@@ -959,23 -949,6 +959,23 @@@ apply.whitespace:
        Tells 'git apply' how to handle whitespaces, in the same way
        as the `--whitespace` option. See linkgit:git-apply[1].
  
 +blame.showRoot::
 +      Do not treat root commits as boundaries in linkgit:git-blame[1].
 +      This option defaults to false.
 +
 +blame.blankBoundary::
 +      Show blank commit object name for boundary commits in
 +      linkgit:git-blame[1]. This option defaults to false.
 +
 +blame.showEmail::
 +      Show the author email instead of author name in linkgit:git-blame[1].
 +      This option defaults to false.
 +
 +blame.date::
 +      Specifies the format used to output dates in linkgit:git-blame[1].
 +      If unset the iso format is used. For supported values,
 +      see the discussion of the `--date` option at linkgit:git-log[1].
 +
  branch.autoSetupMerge::
        Tells 'git branch' and 'git checkout' to set up new branches
        so that linkgit:git-pull[1] will appropriately merge from the
@@@ -2108,16 -2081,22 +2108,22 @@@ matched against are those given directl
  visited as a result of a redirection do not participate in matching.
  
  ssh.variant::
-       Depending on the value of the environment variables `GIT_SSH` or
-       `GIT_SSH_COMMAND`, or the config setting `core.sshCommand`, Git
-       auto-detects whether to adjust its command-line parameters for use
-       with ssh (OpenSSH), plink or tortoiseplink, as opposed to the default
-       (simple).
- +
- The config variable `ssh.variant` can be set to override this auto-detection;
- valid values are `ssh`, `simple`, `plink`, `putty` or `tortoiseplink`. Any
- other value will be treated as normal ssh. This setting can be overridden via
- the environment variable `GIT_SSH_VARIANT`.
+       By default, Git determines the command line arguments to use
+       based on the basename of the configured SSH command (configured
+       using the environment variable `GIT_SSH` or `GIT_SSH_COMMAND` or
+       the config setting `core.sshCommand`). If the basename is
+       unrecognized, Git will attempt to detect support of OpenSSH
+       options by first invoking the configured SSH command with the
+       `-G` (print configuration) option and will subsequently use
+       OpenSSH options (if that is successful) or no options besides
+       the host and remote command (if it fails).
+ +
+ The config variable `ssh.variant` can be set to override this detection.
+ Valid values are `ssh` (to use OpenSSH options), `plink`, `putty`,
+ `tortoiseplink`, `simple` (no options except the host and remote command).
+ The default auto-detection can be explicitly requested using the value
+ `auto`.  Any other value is treated as `ssh`.  This setting can also be
+ overridden via the environment variable `GIT_SSH_VARIANT`.
  +
  The current command-line parameters used for each variant are as
  follows:
@@@ -2684,35 -2663,6 +2690,35 @@@ push.gpgSign:
        override a value from a lower-priority config file. An explicit
        command-line flag always overrides this config option.
  
 +push.pushOption::
 +      When no `--push-option=<option>` argument is given from the
 +      command line, `git push` behaves as if each <value> of
 +      this variable is given as `--push-option=<value>`.
 ++
 +This is a multi-valued variable, and an empty value can be used in a
 +higher priority configuration file (e.g. `.git/config` in a
 +repository) to clear the values inherited from a lower priority
 +configuration files (e.g. `$HOME/.gitconfig`).
 ++
 +--
 +
 +Example:
 +
 +/etc/gitconfig
 +  push.pushoption = a
 +  push.pushoption = b
 +
 +~/.gitconfig
 +  push.pushoption = c
 +
 +repo/.git/config
 +  push.pushoption =
 +  push.pushoption = b
 +
 +This will result in only b (a and c are cleared).
 +
 +--
 +
  push.recurseSubmodules::
        Make sure all submodule commits used by the revisions to be pushed
        are available on a remote-tracking branch. If the value is 'check'
@@@ -3043,7 -2993,6 +3049,7 @@@ sendemail.smtpPass:
  sendemail.suppresscc::
  sendemail.suppressFrom::
  sendemail.to::
 +sendemail.tocmd::
  sendemail.smtpDomain::
  sendemail.smtpServer::
  sendemail.smtpServerPort::
@@@ -3178,14 -3127,10 +3184,14 @@@ submodule.<name>.url:
        See linkgit:git-submodule[1] and linkgit:gitmodules[5] for details.
  
  submodule.<name>.update::
 -      The default update procedure for a submodule. This variable
 -      is populated by `git submodule init` from the
 -      linkgit:gitmodules[5] file. See description of 'update'
 -      command in linkgit:git-submodule[1].
 +      The method by which a submodule is updated by 'git submodule update',
 +      which is the only affected command, others such as
 +      'git checkout --recurse-submodules' are unaffected. It exists for
 +      historical reasons, when 'git submodule' was the only command to
 +      interact with submodules; settings like `submodule.active`
 +      and `pull.rebase` are more specific. It is populated by
 +      `git submodule init` from the linkgit:gitmodules[5] file.
 +      See description of 'update' command in linkgit:git-submodule[1].
  
  submodule.<name>.branch::
        The remote branch name for a submodule, used by `git submodule
diff --combined t/t5601-clone.sh
index ef94af9fccf1f76f4b0b86994ea823a37e996b33,66784fc8ff2ec8cf24cdb70348e70995c333d233..0f895478f02bcf4cc4408ce065e79e0314b66793
@@@ -306,23 -306,20 +306,21 @@@ test_expect_success 'clone checking ou
        test_cmp fetch.expected fetch.actual
  '
  
- setup_ssh_wrapper () {
-       test_expect_success 'setup ssh wrapper' '
-               rm -f "$TRASH_DIRECTORY/ssh$X" &&
-               cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \
-                       "$TRASH_DIRECTORY/ssh$X" &&
-               GIT_SSH="$TRASH_DIRECTORY/ssh$X" &&
-               export GIT_SSH &&
-               export TRASH_DIRECTORY &&
-               >"$TRASH_DIRECTORY"/ssh-output
-       '
- }
+ test_expect_success 'set up ssh wrapper' '
+       cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \
+               "$TRASH_DIRECTORY/ssh$X" &&
+       GIT_SSH="$TRASH_DIRECTORY/ssh$X" &&
+       export GIT_SSH &&
+       export TRASH_DIRECTORY &&
+       >"$TRASH_DIRECTORY"/ssh-output
+ '
  
  copy_ssh_wrapper_as () {
 +      rm -f "${1%$X}$X" &&
        cp "$TRASH_DIRECTORY/ssh$X" "${1%$X}$X" &&
+       test_when_finished "rm $(git rev-parse --sq-quote "${1%$X}$X")" &&
        GIT_SSH="${1%$X}$X" &&
-       export GIT_SSH
+       test_when_finished "GIT_SSH=\"\$TRASH_DIRECTORY/ssh\$X\""
  }
  
  expect_ssh () {
        (cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output)
  }
  
- setup_ssh_wrapper
  test_expect_success 'clone myhost:src uses ssh' '
        git clone myhost:src ssh-clone &&
        expect_ssh myhost src
@@@ -369,23 -364,50 +365,50 @@@ test_expect_success 'OpenSSH variant pa
        expect_ssh "-4 -p 123" myhost src
  '
  
- test_expect_success 'variant can be overriden' '
-       git -c ssh.variant=simple clone -4 "[myhost:123]:src" ssh-simple-clone &&
-       expect_ssh myhost src
+ test_expect_success 'variant can be overridden' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/putty" &&
+       git -c ssh.variant=putty clone -4 "[myhost:123]:src" ssh-putty-clone &&
+       expect_ssh "-4 -P 123" myhost src
  '
  
- test_expect_success 'simple is treated as simple' '
+ test_expect_success 'variant=auto picks based on basename' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
+       git -c ssh.variant=auto clone -4 "[myhost:123]:src" ssh-auto-clone &&
+       expect_ssh "-4 -P 123" myhost src
+ '
+ test_expect_success 'simple does not support -4/-6' '
        copy_ssh_wrapper_as "$TRASH_DIRECTORY/simple" &&
-       git clone -4 "[myhost:123]:src" ssh-bracket-clone-simple &&
-       expect_ssh myhost src
+       test_must_fail git clone -4 "myhost:src" ssh-4-clone-simple
+ '
+ test_expect_success 'simple does not support port' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/simple" &&
+       test_must_fail git clone "[myhost:123]:src" ssh-bracket-clone-simple
  '
  
  test_expect_success 'uplink is treated as simple' '
        copy_ssh_wrapper_as "$TRASH_DIRECTORY/uplink" &&
-       git clone "[myhost:123]:src" ssh-bracket-clone-uplink &&
+       test_must_fail git clone "[myhost:123]:src" ssh-bracket-clone-uplink &&
+       git clone "myhost:src" ssh-clone-uplink &&
        expect_ssh myhost src
  '
  
+ test_expect_success 'OpenSSH-like uplink is treated as ssh' '
+       write_script "$TRASH_DIRECTORY/uplink" <<-EOF &&
+       if test "\$1" = "-G"
+       then
+               exit 0
+       fi &&
+       exec "\$TRASH_DIRECTORY/ssh$X" "\$@"
+       EOF
+       test_when_finished "rm -f \"\$TRASH_DIRECTORY/uplink\"" &&
+       GIT_SSH="$TRASH_DIRECTORY/uplink" &&
+       test_when_finished "GIT_SSH=\"\$TRASH_DIRECTORY/ssh\$X\"" &&
+       git clone "[myhost:123]:src" ssh-bracket-clone-sshlike-uplink &&
+       expect_ssh "-p 123" myhost src
+ '
  test_expect_success 'plink is treated specially (as putty)' '
        copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
        git clone "[myhost:123]:src" ssh-bracket-clone-plink-0 &&
@@@ -434,12 -456,14 +457,14 @@@ test_expect_success 'ssh.variant overri
  '
  
  test_expect_success 'GIT_SSH_VARIANT overrides plink detection to plink' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
        GIT_SSH_VARIANT=plink \
        git clone "[myhost:123]:src" ssh-bracket-clone-variant-3 &&
        expect_ssh "-P 123" myhost src
  '
  
  test_expect_success 'GIT_SSH_VARIANT overrides plink to tortoiseplink' '
+       copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
        GIT_SSH_VARIANT=tortoiseplink \
        git clone "[myhost:123]:src" ssh-bracket-clone-variant-4 &&
        expect_ssh "-batch -P 123" myhost src
@@@ -451,9 -475,6 +476,6 @@@ test_expect_success 'clean failure on b
                git clone "[myhost:123]:src" sq-failure
  '
  
- # Reset the GIT_SSH environment variable for clone tests.
- setup_ssh_wrapper
  counter=0
  # $1 url
  # $2 none|host