From: Junio C Hamano Date: Sat, 10 Jun 2006 08:31:58 +0000 (-0700) Subject: Merge branch 'jc/shared' into next X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=67d4160712ef07bc7a5bc6790f166ba39d45a82a;hp=55becd7b5fdbd93a2928a659a670d004d30d7c37;p=git.git Merge branch 'jc/shared' into next * jc/shared: shared repository: optionally allow reading to "others". git-clone: fix --bare over dumb-http shared repository - add a few missing calls to adjust_shared_perm(). Fix formatting of Documentation/git-clone.txt builtin-init-db: spell the in-program configuration variable in lowercase. --- diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 7572e4b8..a90521e5 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -95,8 +95,8 @@ OPTIONS defined default, typically `/usr/share/git-core/templates`. --use-separate-remote:: - Save remotes heads under `$GIT_DIR/remotes/origin/' instead - of `$GIT_DIR/refs/heads/'. Only the master branch is saved + Save remotes heads under `$GIT_DIR/remotes/origin/` instead + of `$GIT_DIR/refs/heads/`. Only the master branch is saved in the latter. :: diff --git a/builtin-init-db.c b/builtin-init-db.c index 2a1384cc..7fdd2fa9 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -199,6 +199,21 @@ static void create_default_files(const char *git_dir, const char *template_path) git_config(git_default_config); /* + * We would have created the above under user's umask -- under + * shared-repository settings, we would need to fix them up. + */ + if (shared_repository) { + path[len] = 0; + adjust_shared_perm(path); + strcpy(path + len, "refs"); + adjust_shared_perm(path); + strcpy(path + len, "refs/heads"); + adjust_shared_perm(path); + strcpy(path + len, "refs/tags"); + adjust_shared_perm(path); + } + + /* * Create the default symlink from ".git/HEAD" to the "master" * branch, if it does not exist yet. */ @@ -248,7 +263,9 @@ int cmd_init_db(int argc, const char **argv, char **envp) if (!strncmp(arg, "--template=", 11)) template_dir = arg+11; else if (!strcmp(arg, "--shared")) - shared_repository = 1; + shared_repository = PERM_GROUP; + else if (!strncmp(arg, "--shared=", 9)) + shared_repository = git_config_perm("arg", arg+9); else die(init_db_usage); } @@ -286,8 +303,15 @@ int cmd_init_db(int argc, const char **argv, char **envp) strcpy(path+len, "/info"); safe_create_dir(path, 1); - if (shared_repository) - git_config_set("core.sharedRepository", "true"); + if (shared_repository) { + char buf[10]; + /* We do not spell "group" and such, so that + * the configuration can be read by older version + * of git. + */ + sprintf(buf, "%d", shared_repository); + git_config_set("core.sharedrepository", buf); + } return 0; } diff --git a/cache.h b/cache.h index d5d7fe4f..1b8e053f 100644 --- a/cache.h +++ b/cache.h @@ -208,6 +208,12 @@ extern const unsigned char null_sha1[20]; int git_mkstemp(char *path, size_t n, const char *template); +enum sharedrepo { + PERM_UMASK = 0, + PERM_GROUP, + PERM_EVERYBODY +}; +int git_config_perm(const char *var, const char *value); int adjust_shared_perm(const char *path); int safe_create_leading_directories(char *path); char *safe_strncpy(char *, const char *, size_t); diff --git a/config.c b/config.c index 2ae6153e..c4749700 100644 --- a/config.c +++ b/config.c @@ -536,7 +536,7 @@ int git_config_set_multivar(const char* key, const char* value, * contents of .git/config will be written into it. */ fd = open(lock_file, O_WRONLY | O_CREAT | O_EXCL, 0666); - if (fd < 0) { + if (fd < 0 || adjust_shared_perm(lock_file)) { fprintf(stderr, "could not lock config file\n"); free(store.key); ret = -1; diff --git a/environment.c b/environment.c index 2e79eab1..3de8eb3b 100644 --- a/environment.c +++ b/environment.c @@ -18,7 +18,7 @@ int log_all_ref_updates = 0; int warn_ambiguous_refs = 1; int repository_format_version = 0; char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8"; -int shared_repository = 0; +int shared_repository = PERM_UMASK; const char *apply_default_whitespace = NULL; static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir, diff --git a/git-clone.sh b/git-clone.sh index 64318b4d..6fa0daaa 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -29,7 +29,7 @@ http_fetch () { clone_dumb_http () { # $1 - remote, $2 - local cd "$2" && - clone_tmp='.git/clone-tmp' && + clone_tmp="$GIT_DIR/clone-tmp" && mkdir -p "$clone_tmp" || exit 1 http_fetch "$1/info/refs" "$clone_tmp/refs" || { echo >&2 "Cannot get remote repository information. @@ -207,15 +207,11 @@ mkdir -p "$dir" && D=$(cd "$dir" && pwd) && trap 'err=$?; cd ..; rm -r "$D"; exit $err' 0 case "$bare" in -yes) GIT_DIR="$D" ;; -*) GIT_DIR="$D/.git" ;; -esac && export GIT_DIR && git-init-db ${template+"$template"} || usage -case "$bare" in yes) GIT_DIR="$D" ;; *) GIT_DIR="$D/.git" ;; -esac +esac && export GIT_DIR && git-init-db ${template+"$template"} || usage if test -n "$reference" then diff --git a/lockfile.c b/lockfile.c index 9bc60837..2346e0e9 100644 --- a/lockfile.c +++ b/lockfile.c @@ -27,11 +27,16 @@ int hold_lock_file_for_update(struct lock_file *lk, const char *path) int fd; sprintf(lk->filename, "%s.lock", path); fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666); - if (fd >=0 && !lk->next) { - lk->next = lock_file_list; - lock_file_list = lk; - signal(SIGINT, remove_lock_file_on_signal); - atexit(remove_lock_file); + if (0 <= fd) { + if (!lk->next) { + lk->next = lock_file_list; + lock_file_list = lk; + signal(SIGINT, remove_lock_file_on_signal); + atexit(remove_lock_file); + } + if (adjust_shared_perm(lk->filename)) + return error("cannot fix permission bits on %s", + lk->filename); } return fd; } diff --git a/path.c b/path.c index 334b2bd1..5d82503b 100644 --- a/path.c +++ b/path.c @@ -250,3 +250,36 @@ char *enter_repo(char *path, int strict) return NULL; } + +int adjust_shared_perm(const char *path) +{ + struct stat st; + int mode; + + if (!shared_repository) + return 0; + if (lstat(path, &st) < 0) + return -1; + mode = st.st_mode; + if (mode & S_IRUSR) + mode |= (shared_repository == PERM_GROUP + ? S_IRGRP + : (shared_repository == PERM_EVERYBODY + ? (S_IRGRP|S_IROTH) + : 0)); + + if (mode & S_IWUSR) + mode |= S_IWGRP; + + if (mode & S_IXUSR) + mode |= (shared_repository == PERM_GROUP + ? S_IXGRP + : (shared_repository == PERM_EVERYBODY + ? (S_IXGRP|S_IXOTH) + : 0)); + if (S_ISDIR(mode)) + mode |= S_ISGID; + if (chmod(path, mode) < 0) + return -2; + return 0; +} diff --git a/refs.c b/refs.c index f91b7716..713ca467 100644 --- a/refs.c +++ b/refs.c @@ -104,6 +104,11 @@ int create_symref(const char *git_HEAD, const char *refs_heads_master) error("Unable to create %s", git_HEAD); return -3; } + if (adjust_shared_perm(git_HEAD)) { + unlink(lockpath); + error("Unable to fix permissions on %s", lockpath); + return -4; + } return 0; } diff --git a/setup.c b/setup.c index fe7f8846..4612f110 100644 --- a/setup.c +++ b/setup.c @@ -219,12 +219,27 @@ const char *setup_git_directory_gently(int *nongit_ok) return cwd + offset; } +int git_config_perm(const char *var, const char *value) +{ + if (value) { + if (!strcmp(value, "umask")) + return PERM_UMASK; + if (!strcmp(value, "group")) + return PERM_GROUP; + if (!strcmp(value, "all") || + !strcmp(value, "world") || + !strcmp(value, "everybody")) + return PERM_EVERYBODY; + } + return git_config_bool(var, value); +} + int check_repository_format_version(const char *var, const char *value) { if (strcmp(var, "core.repositoryformatversion") == 0) repository_format_version = git_config_int(var, value); else if (strcmp(var, "core.sharedrepository") == 0) - shared_repository = git_config_bool(var, value); + shared_repository = git_config_perm(var, value); return 0; } diff --git a/sha1_file.c b/sha1_file.c index aea0f40d..b4ff233b 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -50,29 +50,6 @@ int get_sha1_hex(const char *hex, unsigned char *sha1) return 0; } -int adjust_shared_perm(const char *path) -{ - struct stat st; - int mode; - - if (!shared_repository) - return 0; - if (lstat(path, &st) < 0) - return -1; - mode = st.st_mode; - if (mode & S_IRUSR) - mode |= S_IRGRP; - if (mode & S_IWUSR) - mode |= S_IWGRP; - if (mode & S_IXUSR) - mode |= S_IXGRP; - if (S_ISDIR(mode)) - mode |= S_ISGID; - if (chmod(path, mode) < 0) - return -2; - return 0; -} - int safe_create_leading_directories(char *path) { char *pos = path;