Blame tests/checkout/icase.c

Packit Service 20376f
#include "clar_libgit2.h"
Packit Service 20376f
Packit Service 20376f
#include "git2/checkout.h"
Packit Service 20376f
#include "refs.h"
Packit Service 20376f
#include "path.h"
Packit Service 20376f
Packit Service 20376f
#ifdef GIT_WIN32
Packit Service 20376f
# include <windows.h>
Packit Service 20376f
#else
Packit Service 20376f
# include <dirent.h>
Packit Service 20376f
#endif
Packit Service 20376f
Packit Service 20376f
static git_repository *repo;
Packit Service 20376f
static git_object *obj;
Packit Service 20376f
static git_checkout_options checkout_opts;
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__initialize(void)
Packit Service 20376f
{
Packit Service 20376f
	git_oid id;
Packit Service 20376f
	git_config *cfg;
Packit Service 20376f
	int icase = 0;
Packit Service 20376f
Packit Service 20376f
	repo = cl_git_sandbox_init("testrepo");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_repository_config_snapshot(&cfg, repo));
Packit Service 20376f
	git_config_get_bool(&icase, cfg, "core.ignorecase");
Packit Service 20376f
	git_config_free(cfg);
Packit Service 20376f
Packit Service 20376f
	if (!icase)
Packit Service 20376f
		cl_skip();
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_reference_name_to_id(&id, repo, "refs/heads/dir"));
Packit Service 20376f
	cl_git_pass(git_object_lookup(&obj, repo, &id, GIT_OBJ_ANY));
Packit Service 20376f
Packit Service 20376f
	git_checkout_init_options(&checkout_opts, GIT_CHECKOUT_OPTIONS_VERSION);
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__cleanup(void)
Packit Service 20376f
{
Packit Service 20376f
	git_object_free(obj);
Packit Service 20376f
	cl_git_sandbox_cleanup();
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static char *get_filename(const char *in)
Packit Service 20376f
{
Packit Service 20376f
#ifdef GIT_WIN32
Packit Service 20376f
	HANDLE fh;
Packit Service 20376f
	HMODULE kerneldll;
Packit Service 20376f
	char *filename;
Packit Service 20376f
Packit Service 20376f
	typedef DWORD (__stdcall *getfinalpathname)(HANDLE, LPSTR, DWORD, DWORD);
Packit Service 20376f
	getfinalpathname getfinalpathfn;
Packit Service 20376f
Packit Service 20376f
	cl_assert(filename = malloc(MAX_PATH));
Packit Service 20376f
	cl_assert(kerneldll = LoadLibrary("kernel32.dll"));
Packit Service 20376f
	cl_assert(getfinalpathfn = (getfinalpathname)GetProcAddress(kerneldll, "GetFinalPathNameByHandleA"));
Packit Service 20376f
Packit Service 20376f
	cl_assert(fh = CreateFileA(in, FILE_READ_ATTRIBUTES | STANDARD_RIGHTS_READ, FILE_SHARE_READ,
Packit Service 20376f
		NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL));
Packit Service 20376f
Packit Service 20376f
	cl_win32_pass(getfinalpathfn(fh, filename, MAX_PATH, VOLUME_NAME_DOS));
Packit Service 20376f
Packit Service 20376f
	CloseHandle(fh);
Packit Service 20376f
Packit Service 20376f
	git_path_mkposix(filename);
Packit Service 20376f
Packit Service 20376f
	return filename;
Packit Service 20376f
#else
Packit Service 20376f
	char *search_dirname, *search_filename, *filename = NULL;
Packit Service 20376f
	git_buf out = GIT_BUF_INIT;
Packit Service 20376f
	DIR *dir;
Packit Service 20376f
	struct dirent *de;
Packit Service 20376f
Packit Service 20376f
	cl_assert(search_dirname = git_path_dirname(in));
Packit Service 20376f
	cl_assert(search_filename = git_path_basename(in));
Packit Service 20376f
Packit Service 20376f
	cl_assert(dir = opendir(search_dirname));
Packit Service 20376f
Packit Service 20376f
	while ((de = readdir(dir))) {
Packit Service 20376f
		if (strcasecmp(de->d_name, search_filename) == 0) {
Packit Service 20376f
			git_buf_join(&out, '/', search_dirname, de->d_name);
Packit Service 20376f
			filename = git_buf_detach(&out;;
Packit Service 20376f
			break;
Packit Service 20376f
		}
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	closedir(dir);
Packit Service 20376f
Packit Service 20376f
	git__free(search_dirname);
Packit Service 20376f
	git__free(search_filename);
Packit Service 20376f
	git_buf_free(&out;;
Packit Service 20376f
Packit Service 20376f
	return filename;
Packit Service 20376f
#endif
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static void assert_name_is(const char *expected)
Packit Service 20376f
{
Packit Service 20376f
	char *actual;
Packit Service 20376f
	size_t actual_len, expected_len, start;
Packit Service 20376f
Packit Service 20376f
	cl_assert(actual = get_filename(expected));
Packit Service 20376f
Packit Service 20376f
	expected_len = strlen(expected);
Packit Service 20376f
	actual_len = strlen(actual);
Packit Service 20376f
	cl_assert(actual_len >= expected_len);
Packit Service 20376f
Packit Service 20376f
	start = actual_len - expected_len;
Packit Service 20376f
	cl_assert_equal_s(expected, actual + start);
Packit Service 20376f
Packit Service 20376f
	if (start)
Packit Service 20376f
		cl_assert_equal_strn("/", actual + (start - 1), 1);
Packit Service 20376f
Packit Service 20376f
	free(actual);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__refuses_to_overwrite_files_for_files(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
Packit Service 20376f
Packit Service 20376f
	cl_git_write2file("testrepo/BRANCH_FILE.txt", "neue file\n", 10, \
Packit Service 20376f
		O_WRONLY | O_CREAT | O_TRUNC, 0644);
Packit Service 20376f
Packit Service 20376f
	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
	assert_name_is("testrepo/BRANCH_FILE.txt");
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__overwrites_files_for_files_when_forced(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
Packit Service 20376f
Packit Service 20376f
	cl_git_write2file("testrepo/NEW.txt", "neue file\n", 10, \
Packit Service 20376f
		O_WRONLY | O_CREAT | O_TRUNC, 0644);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
	assert_name_is("testrepo/new.txt");
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__refuses_to_overwrite_links_for_files(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_symlink("../tmp", "testrepo/BRANCH_FILE.txt"));
Packit Service 20376f
Packit Service 20376f
	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
Packit Service 20376f
	cl_assert(!git_path_exists("tmp"));
Packit Service 20376f
	assert_name_is("testrepo/BRANCH_FILE.txt");
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__overwrites_links_for_files_when_forced(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_symlink("../tmp", "testrepo/NEW.txt"));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
Packit Service 20376f
	cl_assert(!git_path_exists("tmp"));
Packit Service 20376f
	assert_name_is("testrepo/new.txt");
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__overwrites_empty_folders_for_files(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_mkdir("testrepo/NEW.txt", 0777));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
Packit Service 20376f
	assert_name_is("testrepo/new.txt");
Packit Service 20376f
	cl_assert(!git_path_isdir("testrepo/new.txt"));
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__refuses_to_overwrite_populated_folders_for_files(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_mkdir("testrepo/BRANCH_FILE.txt", 0777));
Packit Service 20376f
	cl_git_write2file("testrepo/BRANCH_FILE.txt/foobar", "neue file\n", 10, \
Packit Service 20376f
		O_WRONLY | O_CREAT | O_TRUNC, 0644);
Packit Service 20376f
Packit Service 20376f
	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
Packit Service 20376f
	assert_name_is("testrepo/BRANCH_FILE.txt");
Packit Service 20376f
	cl_assert(git_path_isdir("testrepo/BRANCH_FILE.txt"));
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__overwrites_folders_for_files_when_forced(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_mkdir("testrepo/NEW.txt", 0777));
Packit Service 20376f
	cl_git_write2file("testrepo/NEW.txt/foobar", "neue file\n", 10, \
Packit Service 20376f
		O_WRONLY | O_CREAT | O_TRUNC, 0644);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
Packit Service 20376f
	assert_name_is("testrepo/new.txt");
Packit Service 20376f
	cl_assert(!git_path_isdir("testrepo/new.txt"));
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__refuses_to_overwrite_files_for_folders(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
Packit Service 20376f
Packit Service 20376f
	cl_git_write2file("testrepo/A", "neue file\n", 10, \
Packit Service 20376f
		O_WRONLY | O_CREAT | O_TRUNC, 0644);
Packit Service 20376f
Packit Service 20376f
	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
	assert_name_is("testrepo/A");
Packit Service 20376f
	cl_assert(!git_path_isdir("testrepo/A"));
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__overwrites_files_for_folders_when_forced(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
Packit Service 20376f
Packit Service 20376f
	cl_git_write2file("testrepo/A", "neue file\n", 10, \
Packit Service 20376f
		O_WRONLY | O_CREAT | O_TRUNC, 0644);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
	assert_name_is("testrepo/a");
Packit Service 20376f
	cl_assert(git_path_isdir("testrepo/a"));
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__refuses_to_overwrite_links_for_folders(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_symlink("..", "testrepo/A"));
Packit Service 20376f
Packit Service 20376f
	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
Packit Service 20376f
	cl_assert(!git_path_exists("b.txt"));
Packit Service 20376f
	assert_name_is("testrepo/A");
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__overwrites_links_for_folders_when_forced(void)
Packit Service 20376f
{
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_symlink("..", "testrepo/A"));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
Packit Service 20376f
Packit Service 20376f
	cl_assert(!git_path_exists("b.txt"));
Packit Service 20376f
	assert_name_is("testrepo/a");
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__ignores_unstaged_casechange(void)
Packit Service 20376f
{
Packit Service 20376f
	git_reference *orig_ref, *br2_ref;
Packit Service 20376f
	git_commit *orig, *br2;
Packit Service 20376f
	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
Packit Service 20376f
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_reference_lookup_resolved(&orig_ref, repo, "HEAD", 100));
Packit Service 20376f
	cl_git_pass(git_commit_lookup(&orig, repo, git_reference_target(orig_ref)));
Packit Service 20376f
	cl_git_pass(git_reset(repo, (git_object *)orig, GIT_RESET_HARD, NULL));
Packit Service 20376f
Packit Service 20376f
	cl_rename("testrepo/branch_file.txt", "testrepo/Branch_File.txt");
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_reference_lookup_resolved(&br2_ref, repo, "refs/heads/br2", 100));
Packit Service 20376f
	cl_git_pass(git_commit_lookup(&br2, repo, git_reference_target(br2_ref)));
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_checkout_tree(repo, (const git_object *)br2, &checkout_opts));
Packit Service 20376f
Packit Service 20376f
	git_commit_free(orig);
Packit Service 20376f
	git_commit_free(br2);
Packit Service 20376f
	git_reference_free(orig_ref);
Packit Service 20376f
	git_reference_free(br2_ref);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void test_checkout_icase__conflicts_with_casechanged_subtrees(void)
Packit Service 20376f
{
Packit Service 20376f
	git_reference *orig_ref;
Packit Service 20376f
	git_object *orig, *subtrees;
Packit Service 20376f
	git_oid oid;
Packit Service 20376f
	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
Packit Service 20376f
Packit Service 20376f
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_reference_lookup_resolved(&orig_ref, repo, "HEAD", 100));
Packit Service 20376f
	cl_git_pass(git_object_lookup(&orig, repo, git_reference_target(orig_ref), GIT_OBJ_COMMIT));
Packit Service 20376f
	cl_git_pass(git_reset(repo, (git_object *)orig, GIT_RESET_HARD, NULL));
Packit Service 20376f
Packit Service 20376f
	cl_must_pass(p_mkdir("testrepo/AB", 0777));
Packit Service 20376f
	cl_must_pass(p_mkdir("testrepo/AB/C", 0777));
Packit Service 20376f
	cl_git_write2file("testrepo/AB/C/3.txt", "Foobar!\n", 8, O_RDWR|O_CREAT, 0666);
Packit Service 20376f
Packit Service 20376f
	cl_git_pass(git_reference_name_to_id(&oid, repo, "refs/heads/subtrees"));
Packit Service 20376f
	cl_git_pass(git_object_lookup(&subtrees, repo, &oid, GIT_OBJ_ANY));
Packit Service 20376f
Packit Service 20376f
	cl_git_fail(git_checkout_tree(repo, subtrees, &checkout_opts));
Packit Service 20376f
Packit Service 20376f
	git_object_free(orig);
Packit Service 20376f
	git_object_free(subtrees);
Packit Service 20376f
    git_reference_free(orig_ref);
Packit Service 20376f
}
Packit Service 20376f