From 121b26738e6a5e6eadeb2a2bc666956ae21cb92b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 23 Dec 2013 11:12:31 +0000 Subject: [PATCH] clone: add flags to override whether to perform a local clone --- include/git2/clone.h | 7 +++++++ src/clone.c | 25 ++++++++++++++++++++++++- src/clone.h | 12 ++++++++++++ tests/clone/local.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/clone.h create mode 100644 tests/clone/local.c diff --git a/include/git2/clone.h b/include/git2/clone.h index ceb1a53bb..71e8e72f2 100644 --- a/include/git2/clone.h +++ b/include/git2/clone.h @@ -23,6 +23,12 @@ */ GIT_BEGIN_DECL +typedef enum { + GIT_CLONE_LOCAL_AUTO, + GIT_CLONE_LOCAL, + GIT_CLONE_NO_LOCAL, +} git_clone_local_t; + /** * Clone options structure * @@ -57,6 +63,7 @@ typedef struct git_clone_options { int bare; int ignore_cert_errors; + git_clone_local_t local; const char *remote_name; const char* checkout_branch; git_signature *signature; diff --git a/src/clone.c b/src/clone.c index b6f8c7e85..58430f63a 100644 --- a/src/clone.c +++ b/src/clone.c @@ -347,6 +347,29 @@ cleanup: return error; } +int git_clone__should_clone_local(const char *url, git_clone_local_t local) +{ + const char *path; + int is_url; + + if (local == GIT_CLONE_NO_LOCAL) + return false; + + is_url = !git__prefixcmp(url, "file://"); + + if (is_url && local != GIT_CLONE_LOCAL) + return false; + + path = url; + if (is_url) + path = url + strlen("file://"); + + if ((git_path_exists(path) && git_path_isdir(path)) && local != GIT_CLONE_NO_LOCAL) + return true; + + return false; +} + int git_clone( git_repository **out, const char *url, @@ -381,7 +404,7 @@ int git_clone( return error; if (!(error = create_and_configure_origin(&origin, repo, url, &options))) { - if (git_path_exists(url) && git_path_isdir(url)) { + if (git_clone__should_clone_local(url, options.local)) { error = git_clone_local_into( repo, origin, &options.checkout_opts, options.checkout_branch, options.signature); diff --git a/src/clone.h b/src/clone.h new file mode 100644 index 000000000..14ca5d44c --- /dev/null +++ b/src/clone.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_clone_h__ +#define INCLUDE_clone_h__ + +extern int git_clone__should_clone_local(const char *url, git_clone_local_t local); + +#endif diff --git a/tests/clone/local.c b/tests/clone/local.c new file mode 100644 index 000000000..478bbb673 --- /dev/null +++ b/tests/clone/local.c @@ -0,0 +1,29 @@ +#include "clar_libgit2.h" + +#include "git2/clone.h" +#include "clone.h" +#include "buffer.h" + +void assert_clone(const char *path, git_clone_local_t opt, int val) +{ + cl_assert_equal_i(val, git_clone__should_clone_local(path, opt)); +} + +void test_clone_local__should_clone_local(void) +{ + git_buf buf = GIT_BUF_INIT; + const char *path; + + /* we use a fixture path because it needs to exist for us to want to clone */ + + cl_git_pass(git_buf_printf(&buf, "file://%s", cl_fixture("testrepo.git"))); + cl_assert_equal_i(false, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO)); + cl_assert_equal_i(true, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL)); + cl_assert_equal_i(false, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL)); + git_buf_free(&buf); + + path = cl_fixture("testrepo.git"); + cl_assert_equal_i(true, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_AUTO)); + cl_assert_equal_i(true, git_clone__should_clone_local(path, GIT_CLONE_LOCAL)); + cl_assert_equal_i(false, git_clone__should_clone_local(path, GIT_CLONE_NO_LOCAL)); +}