Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2012-06-20 01:27:02 +0400
committerRussell Belfer <rb@github.com>2012-06-20 01:27:02 +0400
commitda825c92d92433240ceeaea70d7618395bcfb83d (patch)
tree1cdf8d9c08d101d0ebc40b7e07eb4ba1c41611b2 /tests-clar/index/filemodes.c
parent1b0ef5aa03fad68105784d5d4d87592ce005e03a (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.c212
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);
+}