summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2018-07-02 12:57:56 -0700
committerEdward Thomson <ethomson@edwardthomson.com>2018-10-20 05:51:46 -0700
commite4ac40002865b3b8114ef434a97bcaedaafd324a (patch)
treeb1120b6f7853a0708db076c8277b90c87ba1e5db
parent7b6875f425a0a7acfc776cf213da4b200e9bb6e9 (diff)
downloadlibgit2-e4ac40002865b3b8114ef434a97bcaedaafd324a.tar.gz
checkout tests: test symlinks based on support, not platform
When testing whether symlinks are correctly checked out, examine the `core.symlinks` configuration option to determine if symlinks are supported in a repository, don't simply assume that Windows means that symbolic links are not supported. Further, when testing the expected default behavior of `core.symlinks`, test the filesystem's support to determine if symlinks are supported. Finally, ensure that `core.symlinks=true` fails on a system where symlinks are actually not supported. This aligns with the behavior of Git for Windows.
-rw-r--r--tests/checkout/conflict.c104
-rw-r--r--tests/checkout/icase.c21
-rw-r--r--tests/checkout/index.c68
3 files changed, 121 insertions, 72 deletions
diff --git a/tests/checkout/conflict.c b/tests/checkout/conflict.c
index 90603d4b7..6670b2ec7 100644
--- a/tests/checkout/conflict.c
+++ b/tests/checkout/conflict.c
@@ -2,6 +2,7 @@
#include "git2/repository.h"
#include "git2/sys/index.h"
#include "fileops.h"
+#include "repository.h"
static git_repository *g_repo;
static git_index *g_index;
@@ -184,28 +185,35 @@ static void ensure_workdir(const char *path, int mode, const char *oid_str)
ensure_workdir_oid(path, oid_str);
}
-static void ensure_workdir_link(const char *path, const char *target)
+static void ensure_workdir_link(
+ git_repository *repo,
+ const char *path,
+ const char *target)
{
-#ifdef GIT_WIN32
- ensure_workdir_contents(path, target);
-#else
- git_buf fullpath = GIT_BUF_INIT;
- char actual[1024];
- struct stat st;
- int len;
+ int symlinks;
- cl_git_pass(
- git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));
+ cl_git_pass(git_repository__cvar(&symlinks, repo, GIT_CVAR_SYMLINKS));
- cl_git_pass(p_lstat(git_buf_cstr(&fullpath), &st));
- cl_assert(S_ISLNK(st.st_mode));
+ if (!symlinks) {
+ ensure_workdir_contents(path, target);
+ } else {
+ git_buf fullpath = GIT_BUF_INIT;
+ char actual[1024];
+ struct stat st;
+ int len;
- cl_assert((len = p_readlink(git_buf_cstr(&fullpath), actual, 1024)) > 0);
- actual[len] = '\0';
- cl_assert(strcmp(actual, target) == 0);
+ cl_git_pass(
+ git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));
- git_buf_dispose(&fullpath);
-#endif
+ cl_git_pass(p_lstat(git_buf_cstr(&fullpath), &st));
+ cl_assert(S_ISLNK(st.st_mode));
+
+ cl_assert((len = p_readlink(git_buf_cstr(&fullpath), actual, 1024)) > 0);
+ actual[len] = '\0';
+ cl_assert(strcmp(actual, target) == 0);
+
+ git_buf_dispose(&fullpath);
+ }
}
void test_checkout_conflict__ignored(void)
@@ -415,8 +423,8 @@ void test_checkout_conflict__links(void)
cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
/* Conflicts with links always keep the ours side (even with -Xtheirs) */
- ensure_workdir_link("link-1", LINK_OURS_TARGET);
- ensure_workdir_link("link-2", LINK_OURS_TARGET);
+ ensure_workdir_link(g_repo, "link-1", LINK_OURS_TARGET);
+ ensure_workdir_link(g_repo, "link-2", LINK_OURS_TARGET);
}
void test_checkout_conflict__add_add(void)
@@ -684,7 +692,7 @@ void test_checkout_conflict__renames(void)
void test_checkout_conflict__rename_keep_ours(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
-
+
struct checkout_index_entry checkout_index_entries[] = {
{ 0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e", 0, "0a-no-change.txt" },
{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" },
@@ -728,122 +736,122 @@ void test_checkout_conflict__rename_keep_ours(void)
{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "7-both-renamed.txt" },
{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "7-both-renamed.txt" }
};
-
+
struct checkout_name_entry checkout_name_entries[] = {
{
"3a-renamed-in-ours-deleted-in-theirs.txt",
"3a-newname-in-ours-deleted-in-theirs.txt",
""
},
-
+
{
"3b-renamed-in-theirs-deleted-in-ours.txt",
"",
"3b-newname-in-theirs-deleted-in-ours.txt"
},
-
+
{
"4a-renamed-in-ours-added-in-theirs.txt",
"4a-newname-in-ours-added-in-theirs.txt",
""
},
-
+
{
"4b-renamed-in-theirs-added-in-ours.txt",
"",
"4b-newname-in-theirs-added-in-ours.txt"
},
-
+
{
"5a-renamed-in-ours-added-in-theirs.txt",
"5a-newname-in-ours-added-in-theirs.txt",
"5a-renamed-in-ours-added-in-theirs.txt"
},
-
+
{
"5b-renamed-in-theirs-added-in-ours.txt",
"5b-renamed-in-theirs-added-in-ours.txt",
"5b-newname-in-theirs-added-in-ours.txt"
},
-
+
{
"6-both-renamed-1-to-2.txt",
"6-both-renamed-1-to-2-ours.txt",
"6-both-renamed-1-to-2-theirs.txt"
},
-
+
{
"7-both-renamed-side-1.txt",
"7-both-renamed.txt",
"7-both-renamed-side-1.txt"
},
-
+
{
"7-both-renamed-side-2.txt",
"7-both-renamed-side-2.txt",
"7-both-renamed.txt"
}
};
-
+
opts.checkout_strategy |= GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS;
-
+
create_index(checkout_index_entries, 41);
create_index_names(checkout_name_entries, 9);
cl_git_pass(git_index_write(g_index));
-
+
cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
-
+
ensure_workdir("0a-no-change.txt",
0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e");
-
+
ensure_workdir("0b-duplicated-in-ours.txt",
0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6");
-
+
ensure_workdir("0b-rewritten-in-ours.txt",
0100644, "e376fbdd06ebf021c92724da9f26f44212734e3e");
-
+
ensure_workdir("0c-duplicated-in-theirs.txt",
0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31");
-
+
ensure_workdir("0c-rewritten-in-theirs.txt",
0100644, "efc9121fdedaf08ba180b53ebfbcf71bd488ed09");
-
+
ensure_workdir("1a-newname-in-ours-edited-in-theirs.txt",
0100644, "0d872f8e871a30208305978ecbf9e66d864f1638");
-
+
ensure_workdir("1a-newname-in-ours.txt",
0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb");
-
+
ensure_workdir("1b-newname-in-theirs-edited-in-ours.txt",
0100644, "ed9523e62e453e50dd9be1606af19399b96e397a");
-
+
ensure_workdir("1b-newname-in-theirs.txt",
0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136");
-
+
ensure_workdir("2-newname-in-both.txt",
0100644, "178940b450f238a56c0d75b7955cb57b38191982");
ensure_workdir("3a-newname-in-ours-deleted-in-theirs.txt",
0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9");
-
+
ensure_workdir("3b-newname-in-theirs-deleted-in-ours.txt",
0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495");
-
+
ensure_workdir("4a-newname-in-ours-added-in-theirs.txt",
0100644, "227792b52aaa0b238bea00ec7e509b02623f168c");
-
+
ensure_workdir("4b-newname-in-theirs-added-in-ours.txt",
0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9");
-
+
ensure_workdir("5a-newname-in-ours-added-in-theirs.txt",
0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436");
-
+
ensure_workdir("5b-newname-in-theirs-added-in-ours.txt",
0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced");
ensure_workdir("6-both-renamed-1-to-2-ours.txt",
0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450");
-
+
ensure_workdir("7-both-renamed.txt",
0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11");
}
diff --git a/tests/checkout/icase.c b/tests/checkout/icase.c
index d804d086e..4aa78a869 100644
--- a/tests/checkout/icase.c
+++ b/tests/checkout/icase.c
@@ -3,6 +3,7 @@
#include "git2/checkout.h"
#include "refs.h"
#include "path.h"
+#include "repository.h"
#ifdef GIT_WIN32
# include <windows.h>
@@ -91,6 +92,18 @@ static void assert_name_is(const char *expected)
free(actual);
}
+static int symlink_or_fake(git_repository *repo, const char *a, const char *b)
+{
+ int symlinks;
+
+ cl_git_pass(git_repository__cvar(&symlinks, repo, GIT_CVAR_SYMLINKS));
+
+ if (symlinks)
+ return p_symlink(a, b);
+ else
+ return git_futils_fake_symlink(a, b);
+}
+
void test_checkout_icase__refuses_to_overwrite_files_for_files(void)
{
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
@@ -117,7 +130,7 @@ void test_checkout_icase__refuses_to_overwrite_links_for_files(void)
{
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
- cl_must_pass(p_symlink("../tmp", "testrepo/BRANCH_FILE.txt"));
+ cl_must_pass(symlink_or_fake(repo, "../tmp", "testrepo/BRANCH_FILE.txt"));
cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
@@ -129,7 +142,7 @@ void test_checkout_icase__overwrites_links_for_files_when_forced(void)
{
checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
- cl_must_pass(p_symlink("../tmp", "testrepo/NEW.txt"));
+ cl_must_pass(symlink_or_fake(repo, "../tmp", "testrepo/NEW.txt"));
cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
@@ -205,7 +218,7 @@ void test_checkout_icase__refuses_to_overwrite_links_for_folders(void)
{
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
- cl_must_pass(p_symlink("..", "testrepo/A"));
+ cl_must_pass(symlink_or_fake(repo, "..", "testrepo/A"));
cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
@@ -217,7 +230,7 @@ void test_checkout_icase__overwrites_links_for_folders_when_forced(void)
{
checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
- cl_must_pass(p_symlink("..", "testrepo/A"));
+ cl_must_pass(symlink_or_fake(repo, "..", "testrepo/A"));
cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
diff --git a/tests/checkout/index.c b/tests/checkout/index.c
index 69252e3d9..452362662 100644
--- a/tests/checkout/index.c
+++ b/tests/checkout/index.c
@@ -136,6 +136,25 @@ void test_checkout_index__honor_coreautocrlf_setting_set_to_true(void)
#endif
}
+static bool supports_symlinks(const char *dir)
+{
+ git_buf path = GIT_BUF_INIT;
+ struct stat st;
+ bool supports_symlinks = 1;
+
+ cl_git_pass(git_buf_joinpath(&path, dir, "test"));
+
+ /* see if symlinks are supported in the "symlink" directory */
+ if (p_symlink("target", path.ptr) < 0 ||
+ p_lstat(path.ptr, &st) < 0 ||
+ ! (S_ISLNK(st.st_mode)))
+ supports_symlinks = 0;
+
+ git_buf_dispose(&path);
+
+ return supports_symlinks;
+}
+
void test_checkout_index__honor_coresymlinks_default(void)
{
git_repository *repo;
@@ -162,10 +181,9 @@ void test_checkout_index__honor_coresymlinks_default(void)
git_object_free(target);
git_repository_free(repo);
-#ifdef GIT_WIN32
- check_file_contents("./symlink/link_to_new.txt", "new.txt");
-#else
- {
+ if (!supports_symlinks("symlink")) {
+ check_file_contents("./symlink/link_to_new.txt", "new.txt");
+ } else {
char link_data[1024];
size_t link_size = 1024;
@@ -175,14 +193,33 @@ void test_checkout_index__honor_coresymlinks_default(void)
cl_assert_equal_s(link_data, "new.txt");
check_file_contents("./symlink/link_to_new.txt", "my new file\n");
}
-#endif
cl_fixture_cleanup("symlink");
}
+void test_checkout_index__coresymlinks_set_to_true_fails_when_unsupported(void)
+{
+ git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+ if (supports_symlinks("testrepo")) {
+ cl_skip();
+ }
+
+ cl_repo_set_bool(g_repo, "core.symlinks", true);
+
+ opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+ cl_git_fail(git_checkout_index(g_repo, NULL, &opts));
+}
+
void test_checkout_index__honor_coresymlinks_setting_set_to_true(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+ char link_data[GIT_PATH_MAX];
+ size_t link_size = GIT_PATH_MAX;
+
+ if (!supports_symlinks("testrepo")) {
+ cl_skip();
+ }
cl_repo_set_bool(g_repo, "core.symlinks", true);
@@ -190,20 +227,11 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_true(void)
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
-#ifdef GIT_WIN32
- check_file_contents("./testrepo/link_to_new.txt", "new.txt");
-#else
- {
- char link_data[1024];
- size_t link_size = 1024;
-
- link_size = p_readlink("./testrepo/link_to_new.txt", link_data, link_size);
- link_data[link_size] = '\0';
- cl_assert_equal_i(link_size, strlen("new.txt"));
- cl_assert_equal_s(link_data, "new.txt");
- check_file_contents("./testrepo/link_to_new.txt", "my new file\n");
- }
-#endif
+ link_size = p_readlink("./testrepo/link_to_new.txt", link_data, link_size);
+ link_data[link_size] = '\0';
+ cl_assert_equal_i(link_size, strlen("new.txt"));
+ cl_assert_equal_s(link_data, "new.txt");
+ check_file_contents("./testrepo/link_to_new.txt", "my new file\n");
}
void test_checkout_index__honor_coresymlinks_setting_set_to_false(void)
@@ -474,7 +502,7 @@ void test_checkout_index__can_overcome_name_clashes(void)
cl_assert(git_path_isfile("./testrepo/path0/file0"));
opts.checkout_strategy =
- GIT_CHECKOUT_SAFE |
+ GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING |
GIT_CHECKOUT_ALLOW_CONFLICTS;
cl_git_pass(git_checkout_index(g_repo, index, &opts));