summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorVicent Marti <vicent@github.com>2014-05-29 14:50:57 +0200
committerVicent Marti <vicent@github.com>2014-05-29 14:50:57 +0200
commit31c551528b3f3bc7bd1d944ed582fc7a379806c6 (patch)
tree76e857c2908c710ba61d8ecdf7d5b604f73a8802 /tests
parent065a00e2c93087353741a95cfd4a1bf40df954c4 (diff)
parentbc9f67fa8524a8bcf343af6a721f57b52334810b (diff)
downloadlibgit2-31c551528b3f3bc7bd1d944ed582fc7a379806c6.tar.gz
Merge pull request #2011 from libgit2/cmn/clone-local
Local clone
Diffstat (limited to 'tests')
-rw-r--r--tests/clone/local.c105
-rw-r--r--tests/core/copy.c26
2 files changed, 131 insertions, 0 deletions
diff --git a/tests/clone/local.c b/tests/clone/local.c
new file mode 100644
index 000000000..a4406c1cc
--- /dev/null
+++ b/tests/clone/local.c
@@ -0,0 +1,105 @@
+#include "clar_libgit2.h"
+
+#include "git2/clone.h"
+#include "clone.h"
+#include "buffer.h"
+#include "path.h"
+#include "posix.h"
+#include "fileops.h"
+
+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(true, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
+ 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(true, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_NO_LINKS));
+ cl_assert_equal_i(false, git_clone__should_clone_local(path, GIT_CLONE_NO_LOCAL));
+}
+
+void test_clone_local__hardlinks(void)
+{
+ git_repository *repo;
+ git_remote *remote;
+ git_signature *sig;
+ git_buf buf = GIT_BUF_INIT;
+ struct stat st;
+
+
+ /*
+ * In this first clone, we just copy over, since the temp dir
+ * will often be in a different filesystem, so we cannot
+ * link. It also allows us to control the number of links
+ */
+ cl_git_pass(git_repository_init(&repo, "./clone.git", true));
+ cl_git_pass(git_remote_create(&remote, repo, "origin", cl_fixture("testrepo.git")));
+ cl_git_pass(git_signature_now(&sig, "foo", "bar"));
+ cl_git_pass(git_clone_local_into(repo, remote, NULL, NULL, false, sig));
+
+ git_remote_free(remote);
+ git_repository_free(repo);
+
+ /* This second clone is in the same filesystem, so we can hardlink */
+
+ cl_git_pass(git_repository_init(&repo, "./clone2.git", true));
+ cl_git_pass(git_buf_puts(&buf, cl_git_path_url("clone.git")));
+ cl_git_pass(git_remote_create(&remote, repo, "origin", buf.ptr));
+ cl_git_pass(git_clone_local_into(repo, remote, NULL, NULL, true, sig));
+
+#ifndef GIT_WIN32
+ git_buf_clear(&buf);
+ cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
+
+ cl_git_pass(p_stat(buf.ptr, &st));
+ cl_assert_equal_i(2, st.st_nlink);
+#endif
+
+ git_remote_free(remote);
+ git_repository_free(repo);
+ git_buf_clear(&buf);
+
+ cl_git_pass(git_repository_init(&repo, "./clone3.git", true));
+ cl_git_pass(git_buf_puts(&buf, cl_git_path_url("clone.git")));
+ cl_git_pass(git_remote_create(&remote, repo, "origin", buf.ptr));
+ cl_git_pass(git_clone_local_into(repo, remote, NULL, NULL, false, sig));
+
+ git_buf_clear(&buf);
+ cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
+
+ cl_git_pass(p_stat(buf.ptr, &st));
+ cl_assert_equal_i(1, st.st_nlink);
+
+ git_remote_free(remote);
+ git_repository_free(repo);
+
+ /* this one should automatically use links */
+ cl_git_pass(git_clone(&repo, "./clone.git", "./clone4.git", NULL));
+
+#ifndef GIT_WIN32
+ git_buf_clear(&buf);
+ cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
+
+ cl_git_pass(p_stat(buf.ptr, &st));
+ cl_assert_equal_i(3, st.st_nlink);
+#endif
+
+ git_buf_free(&buf);
+ git_signature_free(sig);
+ git_repository_free(repo);
+
+ cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
+ cl_git_pass(git_futils_rmdir_r("./clone2.git", NULL, GIT_RMDIR_REMOVE_FILES));
+ cl_git_pass(git_futils_rmdir_r("./clone3.git", NULL, GIT_RMDIR_REMOVE_FILES));
+ cl_git_pass(git_futils_rmdir_r("./clone4.git", NULL, GIT_RMDIR_REMOVE_FILES));
+}
diff --git a/tests/core/copy.c b/tests/core/copy.c
index c0c59c056..04b2dfab5 100644
--- a/tests/core/copy.c
+++ b/tests/core/copy.c
@@ -45,6 +45,16 @@ void test_core_copy__file_in_dir(void)
cl_assert(!git_path_isdir("an_dir"));
}
+void assert_hard_link(const char *path)
+{
+ /* we assert this by checking that there's more than one link to the file */
+ struct stat st;
+
+ cl_assert(git_path_isfile(path));
+ cl_git_pass(p_stat(path, &st));
+ cl_assert(st.st_nlink > 1);
+}
+
void test_core_copy__tree(void)
{
struct stat st;
@@ -122,5 +132,21 @@ void test_core_copy__tree(void)
cl_git_pass(git_futils_rmdir_r("t2", NULL, GIT_RMDIR_REMOVE_FILES));
cl_assert(!git_path_isdir("t2"));
+#ifndef GIT_WIN32
+ cl_git_pass(git_futils_cp_r("src", "t3", GIT_CPDIR_CREATE_EMPTY_DIRS | GIT_CPDIR_LINK_FILES, 0));
+ cl_assert(git_path_isdir("t3"));
+
+ cl_assert(git_path_isdir("t3"));
+ cl_assert(git_path_isdir("t3/b"));
+ cl_assert(git_path_isdir("t3/c"));
+ cl_assert(git_path_isdir("t3/c/d"));
+ cl_assert(git_path_isdir("t3/c/e"));
+
+ assert_hard_link("t3/f1");
+ assert_hard_link("t3/b/f2");
+ assert_hard_link("t3/c/f3");
+ assert_hard_link("t3/c/d/f4");
+#endif
+
cl_git_pass(git_futils_rmdir_r("src", NULL, GIT_RMDIR_REMOVE_FILES));
}