void test_checkout_index__options_dir_modes(void) { #ifndef GIT_WIN32 git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; struct stat st; git_oid oid; git_commit *commit; mode_t um; cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir")); cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); reset_index_to_treeish((git_object *)commit); opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; opts.dir_mode = 0701; cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); /* umask will influence actual directory creation mode */ (void)p_umask(um = p_umask(022)); cl_git_pass(p_stat("./testrepo/a", &st)); cl_assert_equal_i_fmt(st.st_mode, (GIT_FILEMODE_TREE | 0701) & ~um, "%07o"); /* File-mode test, since we're on the 'dir' branch */ cl_git_pass(p_stat("./testrepo/a/b.txt", &st)); cl_assert_equal_i_fmt(st.st_mode, GIT_FILEMODE_BLOB_EXECUTABLE, "%07o"); git_commit_free(commit); #endif }
void test_checkout_index__options_dir_modes(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; struct stat st; git_oid oid; git_commit *commit; mode_t um; if (!cl_is_chmod_supported()) return; cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir")); cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); reset_index_to_treeish((git_object *)commit); opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; opts.dir_mode = 0701; cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); /* umask will influence actual directory creation mode */ (void)p_umask(um = p_umask(022)); cl_git_pass(p_stat("./testrepo/a", &st)); /* Haiku & Hurd use other mode bits, so we must mask them out */ cl_assert_equal_i_fmt(st.st_mode & (S_IFMT | 07777), (GIT_FILEMODE_TREE | 0701) & ~um, "%07o"); /* File-mode test, since we're on the 'dir' branch */ cl_git_pass(p_stat("./testrepo/a/b.txt", &st)); cl_assert_equal_i_fmt(st.st_mode & (S_IFMT | 07777), GIT_FILEMODE_BLOB_EXECUTABLE & ~um, "%07o"); git_commit_free(commit); }
static void check_mode(mode_t expected, mode_t actual) { #ifdef GIT_WIN32 /* chmod on Win32 doesn't support exec bit, not group/world bits */ cl_assert_equal_i_fmt((expected & 0600), (actual & 0777), "%07o"); #else cl_assert_equal_i_fmt(expected, (actual & 0777), "%07o"); #endif }
static void assert_mode_seems_okay( const char *base, const char *path, git_filemode_t expect_mode, bool expect_setgid, bool core_filemode) { git_buf full = GIT_BUF_INIT; struct stat st; cl_git_pass(git_buf_joinpath(&full, base, path)); cl_git_pass(git_path_lstat(full.ptr, &st)); git_buf_free(&full); if (!core_filemode) { CLEAR_FOR_CORE_FILEMODE(expect_mode); CLEAR_FOR_CORE_FILEMODE(st.st_mode); expect_setgid = false; } if (S_ISGID != 0) cl_assert_equal_b(expect_setgid, (st.st_mode & S_ISGID) != 0); cl_assert_equal_b( GIT_PERMS_IS_EXEC(expect_mode), GIT_PERMS_IS_EXEC(st.st_mode)); cl_assert_equal_i_fmt( GIT_MODE_TYPE(expect_mode), GIT_MODE_TYPE(st.st_mode), "%07o"); }
static void assert_hooks_match( const char *template_dir, const char *repo_dir, const char *hook_path, bool core_filemode) { git_buf expected = GIT_BUF_INIT; git_buf actual = GIT_BUF_INIT; struct stat expected_st, st; cl_git_pass(git_buf_joinpath(&expected, template_dir, hook_path)); cl_git_pass(git_path_lstat(expected.ptr, &expected_st)); cl_git_pass(git_buf_joinpath(&actual, repo_dir, hook_path)); cl_git_pass(git_path_lstat(actual.ptr, &st)); cl_assert(expected_st.st_size == st.st_size); if (GIT_MODE_TYPE(expected_st.st_mode) != GIT_FILEMODE_LINK) { mode_t expected_mode = GIT_MODE_TYPE(expected_st.st_mode) | (GIT_PERMS_FOR_WRITE(expected_st.st_mode) & ~g_umask); if (!core_filemode) { CLEAR_FOR_CORE_FILEMODE(expected_mode); CLEAR_FOR_CORE_FILEMODE(st.st_mode); } cl_assert_equal_i_fmt(expected_mode, st.st_mode, "%07o"); } git_buf_free(&expected); git_buf_free(&actual); }
static void check_stat_data(git_index *index, const char *path, bool match) { const git_index_entry *entry; struct stat st; cl_must_pass(p_lstat(path, &st)); /* skip repo base dir name */ while (*path != '/') ++path; ++path; entry = git_index_get_bypath(index, path, 0); cl_assert(entry); if (match) { cl_assert(st.st_ctime == entry->ctime.seconds); cl_assert(st.st_mtime == entry->mtime.seconds); cl_assert(st.st_size == entry->file_size); cl_assert(st.st_uid == entry->uid); cl_assert(st.st_gid == entry->gid); cl_assert_equal_i_fmt( GIT_MODE_TYPE(st.st_mode), GIT_MODE_TYPE(entry->mode), "%07o"); if (cl_is_chmod_supported()) cl_assert_equal_b( GIT_PERMS_IS_EXEC(st.st_mode), GIT_PERMS_IS_EXEC(entry->mode)); } else { /* most things will still match */ cl_assert(st.st_size != entry->file_size); /* would check mtime, but with second resolution it won't work :( */ } }
void test_checkout_index__options_override_file_modes(void) { #ifndef GIT_WIN32 git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; struct stat st; opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; opts.file_mode = 0700; cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); cl_git_pass(p_stat("./testrepo/new.txt", &st)); cl_assert_equal_i_fmt(st.st_mode & GIT_MODE_PERMS_MASK, 0700, "%07o"); #endif }
void test_checkout_index__options_override_file_modes(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; struct stat st; if (!cl_is_chmod_supported()) return; opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; opts.file_mode = 0700; cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); cl_git_pass(p_stat("./testrepo/new.txt", &st)); cl_assert_equal_i_fmt(st.st_mode & GIT_MODE_PERMS_MASK, 0700, "%07o"); }