From 58448910a0591c38959bd26de23cbe97e243b0af Mon Sep 17 00:00:00 2001 From: Ryan Wilcox Date: Wed, 29 Feb 2012 17:37:18 -0500 Subject: [PATCH] implement support for username@host:path URLs in transport_find_fn() --- src/transport.c | 28 +++++++++++++++++++++++++--- tests-clar/network/remotes.c | 10 ++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/transport.c b/src/transport.c index 672eb6e8a..523a9fce2 100644 --- a/src/transport.c +++ b/src/transport.c @@ -10,6 +10,8 @@ #include "git2/net.h" #include "transport.h" +#include + static struct { char *prefix; git_transport_cb fn; @@ -28,15 +30,35 @@ static struct { static git_transport_cb transport_find_fn(const char *url) { size_t i = 0; + regex_t preg; + int error; + git_transport_cb output = NULL; - /* TODO: Parse "example.com:project.git" as an SSH URL */ - + // First, check to see if it's an obvious URL, which a URL scheme for (i = 0; i < GIT_TRANSPORT_COUNT; ++i) { if (!strncasecmp(url, transports[i].prefix, strlen(transports[i].prefix))) return transports[i].fn; } - return NULL; + + // next, see if it matches un-schemed SSH paths used by Git + // if it does not match, it must be a local transport method + // use the slightly old fashioned :alnum: instead of \w or :word:, because + // both are Perl extensions to the Regular Expression language (and not available here) + error = regcomp(&preg, "^[[:alnum:]_]+@[[:alnum:]_]+\\.[[:alnum:]_]+:.+\\.git$", REG_EXTENDED); + if (error < 0) + goto cleanup; + + int rc = regexec(&preg, url, 0, NULL, 0); + if ( rc == REG_NOMATCH ) + output = NULL; // a match was not found - it's probably a file system path + else + output = &git_transport_git; // a match was found! + +cleanup: + regfree(&preg); + + return output; } /************** diff --git a/tests-clar/network/remotes.c b/tests-clar/network/remotes.c index 36b945f9a..4cf473d70 100644 --- a/tests-clar/network/remotes.c +++ b/tests-clar/network/remotes.c @@ -30,6 +30,16 @@ void test_network_remotes__parsing(void) cl_assert(!strcmp(git_remote_url(_remote), "git://github.com/libgit2/libgit2")); } +void test_network_remotes__parsing_ssh_remote(void) +{ + cl_assert( git_remote_valid_url("git@github.com:libgit2/libgit2.git") ); +} + +void test_network_remotes__parsing_local_path(void) +{ + cl_assert( !git_remote_valid_url("/home/git/repos/libgit2.git") ); +} + void test_network_remotes__refspec_parsing(void) { cl_assert(!strcmp(git_refspec_src(_refspec), "refs/heads/*"));