diff options
author | Russell Belfer <rb@github.com> | 2012-06-20 01:27:02 +0400 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2012-06-20 01:27:02 +0400 |
commit | da825c92d92433240ceeaea70d7618395bcfb83d (patch) | |
tree | 1cdf8d9c08d101d0ebc40b7e07eb4ba1c41611b2 /tests-clar/index/filemodes.c | |
parent | 1b0ef5aa03fad68105784d5d4d87592ce005e03a (diff) |
Make index add/append support core.filemode flag
This fixes git_index_add and git_index_append to behave more like
core git, preserving old filemode data in the index when adding
and/or appending with core.filemode = false.
This also has placeholder support for core.symlinks and
core.ignorecase, but those flags are not implemented (well,
symlinks has partial support for preserving mode information in
the same way that git does, but it isn't tested).
Diffstat (limited to 'tests-clar/index/filemodes.c')
-rw-r--r-- | tests-clar/index/filemodes.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/tests-clar/index/filemodes.c b/tests-clar/index/filemodes.c new file mode 100644 index 000000000..8bd35ddab --- /dev/null +++ b/tests-clar/index/filemodes.c @@ -0,0 +1,212 @@ +#include "clar_libgit2.h" +#include "buffer.h" +#include "posix.h" +#include "index.h" + +static git_repository *g_repo = NULL; + +void test_index_filemodes__initialize(void) +{ + g_repo = cl_git_sandbox_init("filemodes"); +} + +void test_index_filemodes__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_index_filemodes__read(void) +{ + git_index *index; + unsigned int i; + static bool expected[6] = { 0, 1, 0, 1, 0, 1 }; + + cl_git_pass(git_repository_index(&index, g_repo)); + cl_assert_equal_i(6, git_index_entrycount(index)); + + for (i = 0; i < 6; ++i) { + git_index_entry *entry = git_index_get(index, i); + cl_assert(entry != NULL); + cl_assert(((entry->mode & 0100) ? 1 : 0) == expected[i]); + } + + git_index_free(index); +} + +static void replace_file_with_mode( + const char *filename, const char *backup, unsigned int create_mode) +{ + git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT; + + cl_git_pass(git_buf_joinpath(&path, "filemodes", filename)); + cl_git_pass(git_buf_printf(&content, "%s as %08u (%d)", + filename, create_mode, rand())); + + cl_git_pass(p_rename(path.ptr, backup)); + cl_git_write2file( + path.ptr, content.ptr, O_WRONLY|O_CREAT|O_TRUNC, create_mode); + + git_buf_free(&path); + git_buf_free(&content); +} + +static void add_and_check_mode( + git_index *index, const char *filename, unsigned int expect_mode) +{ + int pos; + git_index_entry *entry; + + cl_git_pass(git_index_add(index, filename, 0)); + + pos = git_index_find(index, filename); + cl_assert(pos >= 0); + + entry = git_index_get(index, pos); + cl_assert(entry->mode == expect_mode); +} + +static void append_and_check_mode( + git_index *index, const char *filename, unsigned int expect_mode) +{ + unsigned int before, after; + git_index_entry *entry; + + before = git_index_entrycount(index); + + cl_git_pass(git_index_append(index, filename, 0)); + + after = git_index_entrycount(index); + cl_assert_equal_i(before + 1, after); + + /* bypass git_index_get since that resorts the index */ + entry = (git_index_entry *)git_vector_get(&index->entries, after - 1); + + cl_assert_equal_s(entry->path, filename); + cl_assert(expect_mode == entry->mode); +} + +void test_index_filemodes__untrusted(void) +{ + git_config *cfg; + git_index *index; + bool can_filemode = cl_is_chmod_supported(); + + cl_git_pass(git_repository_config(&cfg, g_repo)); + cl_git_pass(git_config_set_bool(cfg, "core.filemode", false)); + git_config_free(cfg); + + cl_git_pass(git_repository_index(&index, g_repo)); + cl_assert((git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE) != 0); + + /* 1 - add 0644 over existing 0644 -> expect 0644 */ + replace_file_with_mode("exec_off", "filemodes/exec_off.0", 0644); + add_and_check_mode(index, "exec_off", 0100644); + + /* 2 - add 0644 over existing 0755 -> expect 0755 */ + replace_file_with_mode("exec_on", "filemodes/exec_on.0", 0644); + add_and_check_mode(index, "exec_on", 0100755); + + /* 3 - add 0755 over existing 0644 -> expect 0644 */ + replace_file_with_mode("exec_off", "filemodes/exec_off.1", 0755); + add_and_check_mode(index, "exec_off", 0100644); + + /* 4 - add 0755 over existing 0755 -> expect 0755 */ + replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755); + add_and_check_mode(index, "exec_on", 0100755); + + /* 5 - append 0644 over existing 0644 -> expect 0644 */ + replace_file_with_mode("exec_off", "filemodes/exec_off.2", 0644); + append_and_check_mode(index, "exec_off", 0100644); + + /* 6 - append 0644 over existing 0755 -> expect 0755 */ + replace_file_with_mode("exec_on", "filemodes/exec_on.2", 0644); + append_and_check_mode(index, "exec_on", 0100755); + + /* 7 - append 0755 over existing 0644 -> expect 0644 */ + replace_file_with_mode("exec_off", "filemodes/exec_off.3", 0755); + append_and_check_mode(index, "exec_off", 0100644); + + /* 8 - append 0755 over existing 0755 -> expect 0755 */ + replace_file_with_mode("exec_on", "filemodes/exec_on.3", 0755); + append_and_check_mode(index, "exec_on", 0100755); + + /* 9 - add new 0644 -> expect 0644 */ + cl_git_write2file("filemodes/new_off", "blah", + O_WRONLY | O_CREAT | O_TRUNC, 0644); + add_and_check_mode(index, "new_off", 0100644); + + /* this test won't give predictable results on a platform + * that doesn't support filemodes correctly, so skip it. + */ + if (can_filemode) { + /* 10 - add 0755 -> expect 0755 */ + cl_git_write2file("filemodes/new_on", "blah", + O_WRONLY | O_CREAT | O_TRUNC, 0755); + add_and_check_mode(index, "new_on", 0100755); + } + + git_index_free(index); +} + +void test_index_filemodes__trusted(void) +{ + git_config *cfg; + git_index *index; + + /* Only run these tests on platforms where I can actually + * chmod a file and get the stat results I expect! + */ + if (!cl_is_chmod_supported()) + return; + + cl_git_pass(git_repository_config(&cfg, g_repo)); + cl_git_pass(git_config_set_bool(cfg, "core.filemode", true)); + git_config_free(cfg); + + cl_git_pass(git_repository_index(&index, g_repo)); + cl_assert((git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE) == 0); + + /* 1 - add 0644 over existing 0644 -> expect 0644 */ + replace_file_with_mode("exec_off", "filemodes/exec_off.0", 0644); + add_and_check_mode(index, "exec_off", 0100644); + + /* 2 - add 0644 over existing 0755 -> expect 0644 */ + replace_file_with_mode("exec_on", "filemodes/exec_on.0", 0644); + add_and_check_mode(index, "exec_on", 0100644); + + /* 3 - add 0755 over existing 0644 -> expect 0755 */ + replace_file_with_mode("exec_off", "filemodes/exec_off.1", 0755); + add_and_check_mode(index, "exec_off", 0100755); + + /* 4 - add 0755 over existing 0755 -> expect 0755 */ + replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755); + add_and_check_mode(index, "exec_on", 0100755); + + /* 5 - append 0644 over existing 0644 -> expect 0644 */ + replace_file_with_mode("exec_off", "filemodes/exec_off.2", 0644); + append_and_check_mode(index, "exec_off", 0100644); + + /* 6 - append 0644 over existing 0755 -> expect 0644 */ + replace_file_with_mode("exec_on", "filemodes/exec_on.2", 0644); + append_and_check_mode(index, "exec_on", 0100644); + + /* 7 - append 0755 over existing 0644 -> expect 0755 */ + replace_file_with_mode("exec_off", "filemodes/exec_off.3", 0755); + append_and_check_mode(index, "exec_off", 0100755); + + /* 8 - append 0755 over existing 0755 -> expect 0755 */ + replace_file_with_mode("exec_on", "filemodes/exec_on.3", 0755); + append_and_check_mode(index, "exec_on", 0100755); + + /* 9 - add new 0644 -> expect 0644 */ + cl_git_write2file("filemodes/new_off", "blah", + O_WRONLY | O_CREAT | O_TRUNC, 0644); + add_and_check_mode(index, "new_off", 0100644); + + /* 10 - add 0755 -> expect 0755 */ + cl_git_write2file("filemodes/new_on", "blah", + O_WRONLY | O_CREAT | O_TRUNC, 0755); + add_and_check_mode(index, "new_on", 0100755); + + git_index_free(index); +} |