* ho/shared:
  Make core.sharedRepository more generic
This commit is contained in:
Junio C Hamano 2008-04-25 12:17:45 -07:00
Родитель 049a226fa1 06cbe85503
Коммит 36c79d2bf8
7 изменённых файлов: 147 добавлений и 36 удалений

Просмотреть файл

@ -261,7 +261,12 @@ core.sharedRepository::
group-writable). When 'all' (or 'world' or 'everybody'), the group-writable). When 'all' (or 'world' or 'everybody'), the
repository will be readable by all users, additionally to being repository will be readable by all users, additionally to being
group-shareable. When 'umask' (or 'false'), git will use permissions group-shareable. When 'umask' (or 'false'), git will use permissions
reported by umask(2). See linkgit:git-init[1]. False by default. reported by umask(2). When '0xxx', where '0xxx' is an octal number,
files in the repository will have this mode value. '0xxx' will override
user's umask value, and thus, users with a safe umask (0077) can use
this option. Examples: '0660' is equivalent to 'group'. '0640' is a
repository that is group-readable but not group-writable.
See linkgit:git-init[1]. False by default.
core.warnAmbiguousRefs:: core.warnAmbiguousRefs::
If true, git will warn you if the ref name you passed it is ambiguous If true, git will warn you if the ref name you passed it is ambiguous

Просмотреть файл

@ -31,7 +31,7 @@ structure, some suggested "exclude patterns", and copies of non-executing
"hook" files. The suggested patterns and hook files are all modifiable and "hook" files. The suggested patterns and hook files are all modifiable and
extensible. extensible.
--shared[={false|true|umask|group|all|world|everybody}]:: --shared[={false|true|umask|group|all|world|everybody|0xxx}]::
Specify that the git repository is to be shared amongst several users. This Specify that the git repository is to be shared amongst several users. This
allows users belonging to the same group to push into that allows users belonging to the same group to push into that
@ -52,6 +52,12 @@ is given:
- 'all' (or 'world' or 'everybody'): Same as 'group', but make the repository - 'all' (or 'world' or 'everybody'): Same as 'group', but make the repository
readable by all users. readable by all users.
- '0xxx': '0xxx' is an octal number and each file will have mode '0xxx'
Any option except 'umask' can be set using this option. '0xxx' will
override users umask(2) value, and thus, users with a safe umask (0077)
can use this option. '0640' will create a repository which is group-readable
but not writable. '0660' is equivalent to 'group'.
By default, the configuration flag receive.denyNonFastForwards is enabled By default, the configuration flag receive.denyNonFastForwards is enabled
in shared repositories, so that you cannot force a non fast-forwarding push in shared repositories, so that you cannot force a non fast-forwarding push
into it. into it.

Просмотреть файл

@ -400,9 +400,16 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
char buf[10]; char buf[10];
/* We do not spell "group" and such, so that /* We do not spell "group" and such, so that
* the configuration can be read by older version * the configuration can be read by older version
* of git. * of git. Note, we use octal numbers for new share modes,
* and compatibility values for PERM_GROUP and
* PERM_EVERYBODY.
*/ */
sprintf(buf, "%d", shared_repository); if (shared_repository == PERM_GROUP)
sprintf(buf, "%d", OLD_PERM_GROUP);
else if (shared_repository == PERM_EVERYBODY)
sprintf(buf, "%d", OLD_PERM_EVERYBODY);
else
sprintf(buf, "0%o", shared_repository);
git_config_set("core.sharedrepository", buf); git_config_set("core.sharedrepository", buf);
git_config_set("receive.denyNonFastforwards", "true"); git_config_set("receive.denyNonFastforwards", "true");
} }

16
cache.h
Просмотреть файл

@ -474,10 +474,20 @@ static inline void hashclr(unsigned char *hash)
int git_mkstemp(char *path, size_t n, const char *template); int git_mkstemp(char *path, size_t n, const char *template);
/*
* NOTE NOTE NOTE!!
*
* PERM_UMASK, OLD_PERM_GROUP and OLD_PERM_EVERYBODY enumerations must
* not be changed. Old repositories have core.sharedrepository written in
* numeric format, and therefore these values are preserved for compatibility
* reasons.
*/
enum sharedrepo { enum sharedrepo {
PERM_UMASK = 0, PERM_UMASK = 0,
PERM_GROUP, OLD_PERM_GROUP = 1,
PERM_EVERYBODY OLD_PERM_EVERYBODY = 2,
PERM_GROUP = 0660,
PERM_EVERYBODY = 0664,
}; };
int git_config_perm(const char *var, const char *value); int git_config_perm(const char *var, const char *value);
int adjust_shared_perm(const char *path); int adjust_shared_perm(const char *path);

31
path.c
Просмотреть файл

@ -266,24 +266,25 @@ int adjust_shared_perm(const char *path)
if (lstat(path, &st) < 0) if (lstat(path, &st) < 0)
return -1; return -1;
mode = st.st_mode; 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) if (shared_repository) {
mode |= S_IWGRP; int tweak = shared_repository;
if (!(mode & S_IWUSR))
tweak &= ~0222;
mode = (mode & ~0777) | tweak;
} else {
/* Preserve old PERM_UMASK behaviour */
if (mode & S_IWUSR)
mode |= S_IWGRP;
}
if (mode & S_IXUSR) if (S_ISDIR(mode)) {
mode |= (shared_repository == PERM_GROUP
? S_IXGRP
: (shared_repository == PERM_EVERYBODY
? (S_IXGRP|S_IXOTH)
: 0));
if (S_ISDIR(mode))
mode |= FORCE_DIR_SET_GID; mode |= FORCE_DIR_SET_GID;
/* Copy read bits to execute bits */
mode |= (shared_repository & 0444) >> 2;
}
if ((mode & st.st_mode) != mode && chmod(path, mode) < 0) if ((mode & st.st_mode) != mode && chmod(path, mode) < 0)
return -2; return -2;
return 0; return 0;

60
setup.c
Просмотреть файл

@ -428,21 +428,53 @@ const char *setup_git_directory_gently(int *nongit_ok)
int git_config_perm(const char *var, const char *value) int git_config_perm(const char *var, const char *value)
{ {
if (value) { int i;
int i; char *endptr;
if (!strcmp(value, "umask"))
return PERM_UMASK; if (value == NULL)
if (!strcmp(value, "group")) return PERM_GROUP;
return PERM_GROUP;
if (!strcmp(value, "all") || if (!strcmp(value, "umask"))
!strcmp(value, "world") || return PERM_UMASK;
!strcmp(value, "everybody")) if (!strcmp(value, "group"))
return PERM_EVERYBODY; return PERM_GROUP;
i = atoi(value); if (!strcmp(value, "all") ||
if (i > 1) !strcmp(value, "world") ||
return i; !strcmp(value, "everybody"))
return PERM_EVERYBODY;
/* Parse octal numbers */
i = strtol(value, &endptr, 8);
/* If not an octal number, maybe true/false? */
if (*endptr != 0)
return git_config_bool(var, value) ? PERM_GROUP : PERM_UMASK;
/*
* Treat values 0, 1 and 2 as compatibility cases, otherwise it is
* a chmod value.
*/
switch (i) {
case PERM_UMASK: /* 0 */
return PERM_UMASK;
case OLD_PERM_GROUP: /* 1 */
return PERM_GROUP;
case OLD_PERM_EVERYBODY: /* 2 */
return PERM_EVERYBODY;
} }
return git_config_bool(var, value);
/* A filemode value was given: 0xxx */
if ((i & 0600) != 0600)
die("Problem with core.sharedRepository filemode value "
"(0%.3o).\nThe owner of files must always have "
"read and write permissions.", i);
/*
* Mask filemode value. Others can not get write permission.
* x flags for directories are handled separately.
*/
return i & 0666;
} }
int check_repository_format_version(const char *var, const char *value) int check_repository_format_version(const char *var, const char *value)

Просмотреть файл

@ -7,6 +7,16 @@ test_description='Test shared repository initialization'
. ./test-lib.sh . ./test-lib.sh
# User must have read permissions to the repo -> failure on --shared=0400
test_expect_success 'shared = 0400 (faulty permission u-w)' '
mkdir sub && (
cd sub && git init --shared=0400
)
ret="$?"
rm -rf sub
test $ret != "0"
'
test_expect_success 'shared=all' ' test_expect_success 'shared=all' '
mkdir sub && mkdir sub &&
cd sub && cd sub &&
@ -33,4 +43,44 @@ test_expect_success 'update-server-info honors core.sharedRepository' '
esac esac
' '
for u in 0660:rw-rw---- \
0640:rw-r----- \
0600:rw------- \
0666:rw-rw-rw- \
0664:rw-rw-r--
do
x=$(expr "$u" : ".*:\([rw-]*\)") &&
y=$(echo "$x" | sed -e "s/w/-/g") &&
u=$(expr "$u" : "\([0-7]*\)") &&
git config core.sharedrepository "$u" &&
umask 0277 &&
test_expect_success "shared = $u ($y) ro" '
rm -f .git/info/refs &&
git update-server-info &&
actual="$(ls -l .git/info/refs)" &&
actual=${actual%% *} &&
test "x$actual" = "x-$y" || {
ls -lt .git/info
false
}
'
umask 077 &&
test_expect_success "shared = $u ($x) rw" '
rm -f .git/info/refs &&
git update-server-info &&
actual="$(ls -l .git/info/refs)" &&
actual=${actual%% *} &&
test "x$actual" = "x-$x" || {
ls -lt .git/info
false
}
'
done
test_done test_done