зеркало из https://github.com/microsoft/git.git
Merge branch 'ho/shared'
* ho/shared: Make core.sharedRepository more generic
This commit is contained in:
Коммит
36c79d2bf8
|
@ -261,7 +261,12 @@ core.sharedRepository::
|
|||
group-writable). When 'all' (or 'world' or 'everybody'), the
|
||||
repository will be readable by all users, additionally to being
|
||||
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::
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
in shared repositories, so that you cannot force a non fast-forwarding push
|
||||
into it.
|
||||
|
|
|
@ -400,9 +400,16 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
|
|||
char buf[10];
|
||||
/* We do not spell "group" and such, so that
|
||||
* 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("receive.denyNonFastforwards", "true");
|
||||
}
|
||||
|
|
16
cache.h
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);
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
PERM_UMASK = 0,
|
||||
PERM_GROUP,
|
||||
PERM_EVERYBODY
|
||||
PERM_UMASK = 0,
|
||||
OLD_PERM_GROUP = 1,
|
||||
OLD_PERM_EVERYBODY = 2,
|
||||
PERM_GROUP = 0660,
|
||||
PERM_EVERYBODY = 0664,
|
||||
};
|
||||
int git_config_perm(const char *var, const char *value);
|
||||
int adjust_shared_perm(const char *path);
|
||||
|
|
31
path.c
31
path.c
|
@ -266,24 +266,25 @@ int adjust_shared_perm(const char *path)
|
|||
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 (shared_repository) {
|
||||
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)
|
||||
mode |= (shared_repository == PERM_GROUP
|
||||
? S_IXGRP
|
||||
: (shared_repository == PERM_EVERYBODY
|
||||
? (S_IXGRP|S_IXOTH)
|
||||
: 0));
|
||||
if (S_ISDIR(mode))
|
||||
if (S_ISDIR(mode)) {
|
||||
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)
|
||||
return -2;
|
||||
return 0;
|
||||
|
|
60
setup.c
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)
|
||||
{
|
||||
if (value) {
|
||||
int i;
|
||||
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;
|
||||
i = atoi(value);
|
||||
if (i > 1)
|
||||
return i;
|
||||
int i;
|
||||
char *endptr;
|
||||
|
||||
if (value == NULL)
|
||||
return PERM_GROUP;
|
||||
|
||||
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;
|
||||
|
||||
/* 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)
|
||||
|
|
|
@ -7,6 +7,16 @@ test_description='Test shared repository initialization'
|
|||
|
||||
. ./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' '
|
||||
mkdir sub &&
|
||||
cd sub &&
|
||||
|
@ -33,4 +43,44 @@ test_expect_success 'update-server-info honors core.sharedRepository' '
|
|||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче