Commit 90befde4a1938641dfdb9a7bdb9f361d1de5c26f

Vicent Marti 2014-06-03T22:10:34

Merge pull request #2399 from libgit2/cmn/path-to-path clone: re-use the local transport's path resolution

diff --git a/src/clone.c b/src/clone.c
index 5aaa94f..6c4fb67 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -472,11 +472,10 @@ static bool can_link(const char *src, const char *dst, int link)
 
 int git_clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature)
 {
-	int error, root, flags;
+	int error, flags;
 	git_repository *src;
 	git_buf src_odb = GIT_BUF_INIT, dst_odb = GIT_BUF_INIT, src_path = GIT_BUF_INIT;
 	git_buf reflog_message = GIT_BUF_INIT;
-	const char *url;
 
 	assert(repo && remote);
 
@@ -490,19 +489,8 @@ int git_clone_local_into(git_repository *repo, git_remote *remote, const git_che
 	 * repo, if it's not rooted, the path should be relative to
 	 * the repository's worktree/gitdir.
 	 */
-	url = git_remote_url(remote);
-	if (!git__prefixcmp(url, "file://"))
-		root = strlen("file://");
-	else
-		root = git_path_root(url);
-
-	if (root >= 0)
-		git_buf_puts(&src_path, url + root);
-	else
-		git_buf_joinpath(&src_path, repository_base(repo), url);
-
-	if (git_buf_oom(&src_path))
-		return -1;
+	if ((error = git_path_from_url_or_path(&src_path, git_remote_url(remote))) < 0)
+		return error;
 
 	/* Copy .git/objects/ from the source to the target */
 	if ((error = git_repository_open(&src, git_buf_cstr(&src_path))) < 0) {
diff --git a/src/path.c b/src/path.c
index e0b00a0..5beab97 100644
--- a/src/path.c
+++ b/src/path.c
@@ -1127,3 +1127,21 @@ int git_path_dirload_with_stat(
 
 	return error;
 }
+
+int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path)
+{
+	int error;
+
+	/* If url_or_path begins with file:// treat it as a URL */
+	if (!git__prefixcmp(url_or_path, "file://")) {
+		if ((error = git_path_fromurl(local_path_out, url_or_path)) < 0) {
+			return error;
+		}
+	} else { /* We assume url_or_path is already a path */
+		if ((error = git_buf_sets(local_path_out, url_or_path)) < 0) {
+			return error;
+		}
+	}
+
+	return 0;
+}
diff --git a/src/path.h b/src/path.h
index 3213c51..3e6efe3 100644
--- a/src/path.h
+++ b/src/path.h
@@ -438,4 +438,7 @@ extern int git_path_iconv(git_path_iconv_t *ic, char **in, size_t *inlen);
 
 extern bool git_path_does_fs_decompose_unicode(const char *root);
 
+/* Used for paths to repositories on the filesystem */
+extern int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path);
+
 #endif
diff --git a/src/transports/local.c b/src/transports/local.c
index 038337d..f859f0b 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -175,24 +175,6 @@ on_error:
 	return -1;
 }
 
-static int path_from_url_or_path(git_buf *local_path_out, const char *url_or_path)
-{
-	int error;
-
-	/* If url_or_path begins with file:// treat it as a URL */
-	if (!git__prefixcmp(url_or_path, "file://")) {
-		if ((error = git_path_fromurl(local_path_out, url_or_path)) < 0) {
-			return error;
-		}
-	} else { /* We assume url_or_path is already a path */
-		if ((error = git_buf_sets(local_path_out, url_or_path)) < 0) {
-			return error;
-		}
-	}
-
-	return 0;
-}
-
 /*
  * Try to open the url as a git directory. The direction doesn't
  * matter in this case because we're calculating the heads ourselves.
@@ -222,7 +204,7 @@ static int local_connect(
 	t->flags = flags;
 
 	/* 'url' may be a url or path; convert to a path */
-	if ((error = path_from_url_or_path(&buf, url)) < 0) {
+	if ((error = git_path_from_url_or_path(&buf, url)) < 0) {
 		git_buf_free(&buf);
 		return error;
 	}
@@ -386,7 +368,7 @@ static int local_push(
 	size_t j;
 
 	/* 'push->remote->url' may be a url or path; convert to a path */
-	if ((error = path_from_url_or_path(&buf, push->remote->url)) < 0) {
+	if ((error = git_path_from_url_or_path(&buf, push->remote->url)) < 0) {
 		git_buf_free(&buf);
 		return error;
 	}