summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2013-12-23 11:12:31 +0000
committerCarlos Martín Nieto <cmn@dwim.me>2014-05-28 15:40:22 +0200
commit121b26738e6a5e6eadeb2a2bc666956ae21cb92b (patch)
tree9f97b747cf21db85b255ae19b5b86ad768a7ba04
parenta0b5f7854c2302105e1029933df5d94a765cb89f (diff)
downloadlibgit2-121b26738e6a5e6eadeb2a2bc666956ae21cb92b.tar.gz
clone: add flags to override whether to perform a local clone
-rw-r--r--include/git2/clone.h7
-rw-r--r--src/clone.c25
-rw-r--r--src/clone.h12
-rw-r--r--tests/clone/local.c29
4 files changed, 72 insertions, 1 deletions
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));
+}