clone: do not use port number as dir name
authorPatrick Steinhardt <ps@pks.im>
Mon, 10 Aug 2015 15:48:24 +0000 (17:48 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 Aug 2015 18:02:07 +0000 (11:02 -0700)
If the URI contains a port number and the URI's path component is
empty we fail to guess a sensible directory name. E.g. cloning a
repository 'ssh://example.com:2222/' we guess a directory name
'2222' where we would want the hostname only, e.g. 'example.com'.

We need to take care to not drop trailing port-like numbers in
certain cases. E.g. when cloning a repository 'foo/bar:2222.git'
we want to guess the directory name '2222' instead of 'bar'.
Thus, we have to first check the stripped URI for path separators
and only strip port numbers if there are path separators present.
This heuristic breaks when cloning a repository 'bar:2222.git',
though.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/clone.c
t/t5603-clone-dirname.sh
index 6aa286fd7be6cc7e6de8194c4c37c84a474be6a2..c68eae13bfab940213e41064523baf24eb9fe642 100644 (file)
@@ -181,6 +181,23 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
                        end--;
        }
 
+       /*
+        * Strip trailing port number if we've got only a
+        * hostname (that is, there is no dir separator but a
+        * colon). This check is required such that we do not
+        * strip URI's like '/foo/bar:2222.git', which should
+        * result in a dir '2222' being guessed due to backwards
+        * compatibility.
+        */
+       if (memchr(start, '/', end - start) == NULL
+           && memchr(start, ':', end - start) != NULL) {
+               ptr = end;
+               while (start < ptr && isdigit(ptr[-1]) && ptr[-1] != ':')
+                       ptr--;
+               if (start < ptr && ptr[-1] == ':')
+                       end = ptr - 1;
+       }
+
        /*
         * Find last component. To remain backwards compatible we
         * also regard colons as path separators, such that
index 0307462b03688e1f364e5a3949b45a4445914133..d5af7581297d6167b82d029a015e367c057ff7af 100755 (executable)
@@ -76,17 +76,17 @@ test_clone_dir host:foo/.git/// foo
 
 # omitting the path should default to the hostname
 test_clone_dir ssh://host/ host
-test_clone_dir ssh://host:1234/ host fail
+test_clone_dir ssh://host:1234/ host
 test_clone_dir ssh://user@host/ host
-test_clone_dir host:/ host fail
+test_clone_dir host:/ host
 
 # auth materials should be redacted
 test_clone_dir ssh://user:password@host/ host
-test_clone_dir ssh://user:password@host:1234/ host fail
-test_clone_dir ssh://user:passw@rd@host:1234/ host fail
-test_clone_dir user@host:/ host fail
-test_clone_dir user:password@host:/ host fail
-test_clone_dir user:passw@rd@host:/ host fail
+test_clone_dir ssh://user:password@host:1234/ host
+test_clone_dir ssh://user:passw@rd@host:1234/ host
+test_clone_dir user@host:/ host
+test_clone_dir user:password@host:/ host
+test_clone_dir user:passw@rd@host:/ host
 
 # auth-like material should not be dropped
 test_clone_dir ssh://host/foo@bar foo@bar