git fetch: support host:/~repo

The documentation (in urls.txt) says that "ssh://host:/~repo", "host:/~repo" or "host:~repo" specify the repository "repo" in the home directory at "host". This has not been working for "host:/~repo". Before commit 356bec "Support [address] in URLs", the comparison "url != hostname" could be used to determine if the URL had a scheme or not: "ssh://host/host" != "host". However, after 356bec "[::1]" was converted into "::1", yielding url != hostname as well. To fix this regression, don't use "if (url != hostname)", but look at the separator instead. Rename the variable "c" into "separator" to make it easier to read. Signed-off-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Torsten Bögershausen committed Nov 28, 2013 at 20:49 UTC 6a59974869c0a6e9399101bc02223b4c00a8aff2
3 files changed +33 -17
connect.c
+7 -7
@@ -567,7 +567,7 @@ static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
567 char *url;
568 char *host, *path;
569 char *end;
570 - int c;
570 + int separator;
571 enum protocol protocol = PROTO_LOCAL;
572 int free_path = 0;
573 char *port = NULL;
@@ -582,10 +582,10 @@ static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
582 *host = '\0';
583 protocol = get_protocol(url);
584 host += 3;
585 - c = '/';
585 + separator = '/';
586 } else {
587 host = url;
588 - c = ':';
588 + separator = ':';
589 }
590
591 /*
@@ -605,9 +605,9 @@ static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
605 } else
606 end = host;
607
608 - path = strchr(end, c);
608 + path = strchr(end, separator);
609 if (path && !has_dos_drive_prefix(end)) {
610 - if (c == ':') {
610 + if (separator == ':') {
611 if (host != url || path < strchrnul(host, '/')) {
612 protocol = PROTO_SSH;
613 *path++ = '\0';
@@ -624,7 +624,7 @@ static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
624 * null-terminate hostname and point path to ~ for URL's like this:
625 * ssh://host.xz/~user/repo
626 */
627 - if (protocol != PROTO_LOCAL && host != url) {
627 + if (protocol != PROTO_LOCAL) {
628 char *ptr = path;
629 if (path[1] == '~')
630 path++;
@@ -639,7 +639,7 @@ static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
639 /*
640 * Add support for ssh port: ssh://host.xy:<port>/...
641 */
642 - if (protocol == PROTO_SSH && host != url)
642 + if (protocol == PROTO_SSH && separator == '/')
643 port = get_port(end);
644
645 *ret_host = xstrdup(host);
t/t5500-fetch-pack.sh
+24
@@ -589,6 +589,30 @@ do
589 check_prot_path $p://$h/~$r $p "/~$r"
590 '
591 done
592 + # file without scheme
593 + for h in nohost nohost:12 [::1] [::1]:23 [ [:aa
594 + do
595 + test_expect_success "fetch-pack --diag-url ./$h:$r" '
596 + check_prot_path ./$h:$r $p "./$h:$r"
597 + '
598 + # No "/~" -> "~" conversion for file
599 + test_expect_success "fetch-pack --diag-url ./$p:$h/~$r" '
600 + check_prot_path ./$p:$h/~$r $p "./$p:$h/~$r"
601 + '
602 + done
603 + #ssh without scheme
604 + p=ssh
605 + for h in host [::1]
606 + do
607 + hh=$(echo $h | tr -d "[]")
608 + test_expect_success "fetch-pack --diag-url $h:$r" '
609 + check_prot_path $h:$r $p "$r"
610 + '
611 + # Do "/~" -> "~" conversion
612 + test_expect_success "fetch-pack --diag-url $h:/~$r" '
613 + check_prot_host_path $h:/~$r $p "$hh" "~$r"
614 + '
615 + done
616 done
617
618 test_done
t/t5601-clone.sh
+2 -10
@@ -348,7 +348,7 @@ test_expect_success MINGW 'clone c:temp is dos drive' '
348 '
349
350 #ip v4
351 -for repo in rep rep/home/project /~proj 123
351 +for repo in rep rep/home/project 123
352 do
353 test_expect_success "clone host:$repo" '
354 test_clone_url host:$repo host $repo
@@ -356,14 +356,6 @@ do
356 done
357
358 #ipv6
359 -# failing
360 -for repo in /~proj
361 -do
362 - test_expect_failure "clone [::1]:$repo" '
363 - test_clone_url [::1]:$repo ::1 $repo
364 - '
365 -done
366 -
359 for repo in rep rep/home/project 123
360 do
361 test_expect_success "clone [::1]:$repo" '
@@ -373,7 +365,7 @@ done
365
366 # Corner cases
367 # failing
376 -for repo in [foo]bar/baz:qux [foo/bar]:baz
368 +for url in [foo]bar/baz:qux [foo/bar]:baz
369 do
370 test_expect_failure "clone $url is not ssh" '
371 test_clone_url $url none