aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-11-07 21:25:52 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-11-08 16:36:27 +0300
commitcc66b4c93bea20220de9ebd4a0b3f686da1d0453 (patch)
tree7abc36a4236b410cd2a9ee350b52fef84ae7c35b
parentdfabdad54e9a2fc15e37d0b407448390ea701f09 (diff)
Add support for ssh:// git protocol
-rw-r--r--bpkg/common.cli4
-rw-r--r--bpkg/fetch-git.cxx18
-rw-r--r--bpkg/repository-types.cli21
-rw-r--r--tests/remote-git.testscript7
-rw-r--r--tests/rep-fetch-git-refname.testscript1
-rw-r--r--tests/rep-fetch-git.testscript2
-rw-r--r--tests/rep-fetch.testscript8
7 files changed, 48 insertions, 13 deletions
diff --git a/bpkg/common.cli b/bpkg/common.cli
index a8c363e..646cb2b 100644
--- a/bpkg/common.cli
+++ b/bpkg/common.cli
@@ -140,8 +140,8 @@ namespace bpkg
\cb{curl} and to the \cb{--timeout} option for \cb{wget} and
\cb{fetch}. For \cb{git} over HTTP/HTTPS this semantics is achieved
using the \cb{http.lowSpeedLimit}=\i{1} \cb{http.lowSpeedTime}=\i{sec}
- configuration values (the \cb{git://} protocol currently does not
- support timeouts).
+ configuration values (the \cb{git://} and \cb{ssh://} protocols
+ currently do not support timeouts).
See \cb{--fetch} and \cb{--git} for more information on the fetch
programs."
diff --git a/bpkg/fetch-git.cxx b/bpkg/fetch-git.cxx
index 2cf526d..c2e1b36 100644
--- a/bpkg/fetch-git.cxx
+++ b/bpkg/fetch-git.cxx
@@ -63,6 +63,21 @@ namespace bpkg
warn << "--fetch-timeout is not supported by the git protocol";
break;
}
+ case repository_protocol::ssh:
+ {
+ // The way to support timeout for the ssh protocol would be using the
+ // '-c core.sshCommand=...' git option (relying on ConnectTimeout and
+ // ServerAlive* options for OpenSSH). To do it cleanly, we would need
+ // to determine the ssh program path and kind (ssh, putty, plink, etc)
+ // that git will use to communicate with the repository server. And it
+ // looks like there is no easy way to do it (see the core.sshCommand
+ // and ssh.variant git configuration options for details). So we will
+ // not support the ssh protocol timeout for now. Note that the user
+ // can always specify the timeout in git or ssh configuration.
+ //
+ warn << "--fetch-timeout is not supported by the ssh protocol";
+ break;
+ }
case repository_protocol::file: return strings (); // Local communications.
}
@@ -401,7 +416,7 @@ namespace bpkg
//
// Protocols other than HTTP(S) are considered smart but without the
// unadvertised refs (note that this is a pessimistic assumption for
- // git://).
+ // git:// and ssh://).
//
// For HTTP(S) sense the protocol type by sending the first HTTP request of
// the fetch operation handshake and analyzing the first line of the
@@ -429,6 +444,7 @@ namespace bpkg
switch (url.scheme)
{
case repository_protocol::git:
+ case repository_protocol::ssh:
case repository_protocol::file: return capabilities::smart;
case repository_protocol::http:
case repository_protocol::https: break; // Ask the server (see below).
diff --git a/bpkg/repository-types.cli b/bpkg/repository-types.cli
index f0e07be..79c50f8 100644
--- a/bpkg/repository-types.cli
+++ b/bpkg/repository-types.cli
@@ -155,11 +155,11 @@ plus (\cb{+}) is treated as an inclusion filter. For example:
.../foo.git#++x - include +x
\
-Currently supported \cb{git} protocols are \cb{git://}, \cb{http://}, and
-\cb{https://} for remote repositories and \cb{file://} for local
-repositories. While \cb{bpkg} tries to minimize the amount of information
-(history) fetched, it is not always possible for some protocols and/or server
-configurations, as discussed next.
+Currently supported \cb{git} protocols are \cb{git://}, \cb{ssh://} (but not
+\c{scp} pseudo-URL syntax), \cb{http://}, and \cb{https://} for remote
+repositories and \cb{file://} for local repositories. While \cb{bpkg} tries to
+minimize the amount of information (history) fetched, it is not always
+possible for some protocols and/or server configurations, as discussed next.
A \cb{git} repository accessible via \cb{http(s)://} can use either \i{dumb}
or \i{smart} protocol (refer to the \cb{git} documentation for details). The
@@ -173,11 +173,12 @@ whether the server is configured to allow fetching unadvertised commits. For
details, refer to the \cb{uploadpack.allowReachableSHA1InWant} and
\cb{uploadpack.allowAnySHA1InWant} \cb{git} configuration values.
-The \cb{git://} protocol is similar to smart \cb{http://} in that it supports
-fetching minimal history for tags and branches and may or may not support this
-for commit ids depending on the server configuration. Note, however, that
-unlike for \cb{http(s)://}, for this protocol \cb{bpkg} does not try to sense
-if fetching unadvertised commits is allowed and always assumes that it is not.
+The \cb{git://} and \cb{ssh://} protocols are similar to smart \cb{http://} in
+that they support fetching minimal history for tags and branches and may or
+may not support this for commit ids depending on the server configuration.
+Note, however, that unlike for \cb{http(s)://}, for these protocols \cb{bpkg}
+does not try to sense if fetching unadvertised commits is allowed and always
+assumes that it is not.
Based on this information, to achieve optimal results the recommended protocol
for remote repositories is smart \cb{https://}. Additionally, if you are
diff --git a/tests/remote-git.testscript b/tests/remote-git.testscript
index 595220d..a5d3e75 100644
--- a/tests/remote-git.testscript
+++ b/tests/remote-git.testscript
@@ -54,10 +54,17 @@ remote = $config.bpkg.test.remote
mkdir -p $out_git
else
+ # If $git_ssh is not true then testscripts must skip tests that use the ssh
+ # protocol. Otherwise, it is assumed that the password-less ssh
+ # authentication is arranged for git.build2.org.
+ #
+ git_ssh = $config.bpkg.test.git.ssh
+
rep_git_https_dumb = "https://build2.org/bpkg/git/$cmd"
rep_git_https_smart = "https://git.build2.org/testing/bpkg/advonly/$cmd"
rep_git_https_smart_unadv = "https://git.build2.org/testing/bpkg/unadv/$cmd"
rep_git_git = "git://git.build2.org/testing/bpkg/unadv/$cmd"
+ rep_git_ssh = "ssh://git.build2.org/var/scm/testing/bpkg/unadv/$cmd"
rep_git = $rep_git_https_dumb # Default remote repository URL.
end
diff --git a/tests/rep-fetch-git-refname.testscript b/tests/rep-fetch-git-refname.testscript
index 88f1e2a..6bb9d57 100644
--- a/tests/rep-fetch-git-refname.testscript
+++ b/tests/rep-fetch-git-refname.testscript
@@ -65,6 +65,7 @@
if ($git_protocol == 'local' || \
$git_protocol == 'https-smart' || \
+ $git_protocol == 'ssh' || \
$git_protocol == 'git')
warn2 = "$warn_repo_hist for submodule 'doc/style/basic'$reason_unadv"
elif ($git_protocol == 'https-dumb')
diff --git a/tests/rep-fetch-git.testscript b/tests/rep-fetch-git.testscript
index 3fe0287..8e9d957 100644
--- a/tests/rep-fetch-git.testscript
+++ b/tests/rep-fetch-git.testscript
@@ -29,6 +29,8 @@ elif ($git_protocol == 'https-smart-unadv')
rep = "$rep_git_https_smart_unadv"
elif ($git_protocol == 'git')
rep = "$rep_git_git"
+elif ($git_protocol == 'ssh')
+ rep = "$rep_git_ssh"
else
exit "unexpected git protocol '$git_protocol'"
end
diff --git a/tests/rep-fetch.testscript b/tests/rep-fetch.testscript
index c1828a8..8320f70 100644
--- a/tests/rep-fetch.testscript
+++ b/tests/rep-fetch.testscript
@@ -732,6 +732,14 @@ else
git_protocol = 'git'
.include rep-fetch-git.testscript
}
+
+ : ssh
+ :
+ if ($git_ssh == true)
+ {
+ git_protocol = 'ssh'
+ .include rep-fetch-git.testscript
+ }
}
: strip-ext