Skip to content

Commit 6000334

Browse files
pcloudsgitster
authored andcommitted
clone: allow cloning local paths with colons in them
Usually "foo:bar" is interpreted as an ssh url. This patch allows to clone from such paths by putting at least one slash before the colon (i.e. /path/to/foo:bar or just ./foo:bar). file://foo:bar should also work, but local optimizations are off in that case, which may be unwanted. While at there, warn the users about --local being ignored in this case. Reported-by: William Giokas <[email protected]> Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 239222f commit 6000334

File tree

4 files changed

+18
-2
lines changed

4 files changed

+18
-2
lines changed

Documentation/urls.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ An alternative scp-like syntax may also be used with the ssh protocol:
2323

2424
- {startsb}user@{endsb}host.xz:path/to/repo.git/
2525

26+
This syntax is only recognized if there are no slashes before the
27+
first colon. This helps differentiate a local path that contains a
28+
colon. For example the local path `foo:bar` could be specified as an
29+
absolute path or `./foo:bar` to avoid being misinterpreted as an ssh
30+
url.
31+
2632
The ssh and git protocols additionally support ~username expansion:
2733

2834
- ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/~{startsb}user{endsb}/path/to/repo.git/

builtin/clone.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
724724
is_local = option_local != 0 && path && !is_bundle;
725725
if (is_local && option_depth)
726726
warning(_("--depth is ignored in local clones; use file:// instead."));
727+
if (option_local > 0 && !is_local)
728+
warning(_("--local is ignored"));
727729

728730
if (argc == 2)
729731
dir = xstrdup(argv[1]);

connect.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,8 +550,11 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
550550
path = strchr(end, c);
551551
if (path && !has_dos_drive_prefix(end)) {
552552
if (c == ':') {
553-
protocol = PROTO_SSH;
554-
*path++ = '\0';
553+
if (path < strchrnul(host, '/')) {
554+
protocol = PROTO_SSH;
555+
*path++ = '\0';
556+
} else /* '/' in the host part, assume local path */
557+
path = end;
555558
}
556559
} else
557560
path = end;

t/t5601-clone.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,4 +280,9 @@ test_expect_success 'clone checking out a tag' '
280280
test_cmp fetch.expected fetch.actual
281281
'
282282

283+
test_expect_success NOT_MINGW,NOT_CYGWIN 'clone local path foo:bar' '
284+
cp -R src "foo:bar" &&
285+
git clone "./foo:bar" foobar
286+
'
287+
283288
test_done

0 commit comments

Comments
 (0)