зеркало из 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
|
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
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
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
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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче