summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fileops.c19
-rw-r--r--src/fileops.h15
-rw-r--r--src/repo_template.h10
-rw-r--r--src/repository.c13
4 files changed, 31 insertions, 26 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 2b2db4b37..90ca11fb7 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -693,7 +693,7 @@ static int _cp_r_mkdir(cp_r_info *info, git_buf *from)
if ((info->flags & GIT_CPDIR__MKDIR_DONE_FOR_TO_ROOT) == 0) {
error = git_futils_mkdir(
info->to_root, NULL, info->dirmode,
- ((info->flags & GIT_CPDIR_CHMOD) != 0) ? GIT_MKDIR_CHMOD : 0);
+ (info->flags & GIT_CPDIR_CHMOD_DIRS) ? GIT_MKDIR_CHMOD : 0);
info->flags |= GIT_CPDIR__MKDIR_DONE_FOR_TO_ROOT;
}
@@ -738,7 +738,7 @@ static int _cp_r_callback(void *ref, git_buf *from)
mode_t oldmode = info->dirmode;
/* if we are not chmod'ing, then overwrite dirmode */
- if ((info->flags & GIT_CPDIR_CHMOD) == 0)
+ if ((info->flags & GIT_CPDIR_CHMOD_DIRS) == 0)
info->dirmode = from_st.st_mode;
/* make directory now if CREATE_EMPTY_DIRS is requested and needed */
@@ -783,17 +783,10 @@ static int _cp_r_callback(void *ref, git_buf *from)
else {
mode_t usemode = from_st.st_mode;
- /* if chmod'ing, then blend dirmode & from_st bits */
- if ((info->flags & GIT_CPDIR_CHMOD) != 0)
- usemode = (info->dirmode & 0666) | (usemode & ~0666);
+ if ((info->flags & GIT_CPDIR_SIMPLE_TO_MODE) != 0)
+ usemode = (usemode & 0111) ? 0777 : 0666;
error = git_futils_cp(from->ptr, info->to.ptr, usemode);
-
- if (!error &&
- (info->flags & GIT_CPDIR_CHMOD) != 0 &&
- (error = p_chmod(info->to.ptr, usemode)) < 0)
- giterr_set(GITERR_OS, "Failed to set permissions on '%s'",
- info->to.ptr);
}
return error;
@@ -824,12 +817,12 @@ int git_futils_cp_r(
* demand right before files are copied.
*/
info.mkdir_flags = GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST;
- if ((flags & GIT_CPDIR_CHMOD) != 0)
+ if ((flags & GIT_CPDIR_CHMOD_DIRS) != 0)
info.mkdir_flags |= GIT_MKDIR_CHMOD_PATH;
} else {
/* otherwise, we will do simple mkdir as directories are encountered */
info.mkdir_flags =
- ((flags & GIT_CPDIR_CHMOD) != 0) ? GIT_MKDIR_CHMOD : 0;
+ ((flags & GIT_CPDIR_CHMOD_DIRS) != 0) ? GIT_MKDIR_CHMOD : 0;
}
error = _cp_r_callback(&info, &path);
diff --git a/src/fileops.h b/src/fileops.h
index 9e1f7440e..988cc661a 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -162,13 +162,26 @@ extern int git_futils_cp(
/**
* Flags that can be passed to `git_futils_cp_r`.
+ *
+ * - GIT_CPDIR_CREATE_EMPTY_DIRS: create directories even if there are no
+ * files under them (otherwise directories will only be created lazily
+ * when a file inside them is copied).
+ * - GIT_CPDIR_COPY_SYMLINKS: copy symlinks, otherwise they are ignored.
+ * - GIT_CPDIR_COPY_DOTFILES: copy files with leading '.', otherwise ignored.
+ * - GIT_CPDIR_OVERWRITE: overwrite pre-existing files with source content,
+ * otherwise they are silently skipped.
+ * - GIT_CPDIR_CHMOD_DIRS: explicitly chmod directories to `dirmode`
+ * - GIT_CPDIR_SIMPLE_TO_MODE: default tries to replicate the mode of the
+ * source file to the target; with this flag, always use 0666 (or 0777 if
+ * source has exec bits set) for target.
*/
typedef enum {
GIT_CPDIR_CREATE_EMPTY_DIRS = (1u << 0),
GIT_CPDIR_COPY_SYMLINKS = (1u << 1),
GIT_CPDIR_COPY_DOTFILES = (1u << 2),
GIT_CPDIR_OVERWRITE = (1u << 3),
- GIT_CPDIR_CHMOD = (1u << 4),
+ GIT_CPDIR_CHMOD_DIRS = (1u << 4),
+ GIT_CPDIR_SIMPLE_TO_MODE = (1u << 5),
} git_futils_cpdir_flags;
/**
diff --git a/src/repo_template.h b/src/repo_template.h
index 90ffe851b..099279aa7 100644
--- a/src/repo_template.h
+++ b/src/repo_template.h
@@ -11,10 +11,10 @@
#define GIT_OBJECTS_PACK_DIR GIT_OBJECTS_DIR "pack/"
#define GIT_HOOKS_DIR "hooks/"
-#define GIT_HOOKS_DIR_MODE 0755
+#define GIT_HOOKS_DIR_MODE 0777
#define GIT_HOOKS_README_FILE GIT_HOOKS_DIR "README.sample"
-#define GIT_HOOKS_README_MODE 0755
+#define GIT_HOOKS_README_MODE 0777
#define GIT_HOOKS_README_CONTENT \
"#!/bin/sh\n"\
"#\n"\
@@ -23,16 +23,16 @@
"# more information.\n"
#define GIT_INFO_DIR "info/"
-#define GIT_INFO_DIR_MODE 0755
+#define GIT_INFO_DIR_MODE 0777
#define GIT_INFO_EXCLUDE_FILE GIT_INFO_DIR "exclude"
-#define GIT_INFO_EXCLUDE_MODE 0644
+#define GIT_INFO_EXCLUDE_MODE 0666
#define GIT_INFO_EXCLUDE_CONTENT \
"# File patterns to ignore; see `git help ignore` for more information.\n"\
"# Lines that start with '#' are comments.\n"
#define GIT_DESC_FILE "description"
-#define GIT_DESC_MODE 0644
+#define GIT_DESC_MODE 0666
#define GIT_DESC_CONTENT \
"Unnamed repository; edit this file 'description' to name the repository.\n"
diff --git a/src/repository.c b/src/repository.c
index e120c5836..cd1e658cf 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -934,7 +934,7 @@ static int repo_write_gitlink(
error = git_buf_printf(&buf, "%s %s", GIT_FILE_CONTENT_PREFIX, to_repo);
if (!error)
- error = repo_write_template(in_dir, true, DOT_GIT, 0644, true, buf.ptr);
+ error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr);
cleanup:
git_buf_free(&buf);
@@ -944,7 +944,7 @@ cleanup:
static mode_t pick_dir_mode(git_repository_init_options *opts)
{
if (opts->mode == GIT_REPOSITORY_INIT_SHARED_UMASK)
- return 0755;
+ return 0777;
if (opts->mode == GIT_REPOSITORY_INIT_SHARED_GROUP)
return (0775 | S_ISGID);
if (opts->mode == GIT_REPOSITORY_INIT_SHARED_ALL)
@@ -1006,7 +1006,8 @@ static int repo_init_structure(
}
error = git_futils_cp_r(tdir, repo_dir,
- GIT_CPDIR_COPY_SYMLINKS | GIT_CPDIR_CHMOD, dmode);
+ GIT_CPDIR_COPY_SYMLINKS | GIT_CPDIR_CHMOD_DIRS |
+ GIT_CPDIR_SIMPLE_TO_MODE, dmode);
if (error < 0) {
if (strcmp(tdir, GIT_TEMPLATE_DIR) != 0)
@@ -1168,10 +1169,8 @@ static int repo_init_directories(
has_dotgit)
{
/* create path #1 */
- if ((error = git_futils_mkdir(
- repo_path->ptr, NULL, dirmode,
- GIT_MKDIR_VERIFY_DIR | GIT_MKDIR_CHMOD)) < 0)
- return error;
+ error = git_futils_mkdir(repo_path->ptr, NULL, dirmode,
+ GIT_MKDIR_VERIFY_DIR | ((dirmode & S_ISGID) ? GIT_MKDIR_CHMOD : 0));
}
/* prettify both directories now that they are created */