git/fs: use a better heuristic for permissions.
Since we now store /dist/plan9front in git, the initial assumption that the owner of the repo is the person touching it is not always true. This change gives us a better heuristic for the file permissions we should have in the files we copy around, basing it off of the permissions of the .git directory.
This commit is contained in:
parent
5770332282
commit
b904edadd8
3 changed files with 50 additions and 15 deletions
|
@ -74,6 +74,15 @@ hierarchy are the same as the date of the commit.
|
||||||
.PP
|
.PP
|
||||||
Trees are presented as directory listings, and blobs
|
Trees are presented as directory listings, and blobs
|
||||||
as files.
|
as files.
|
||||||
|
The repository controls the user permissions.
|
||||||
|
The group and world permissions are derived by masking
|
||||||
|
the user permissions with the permissions of the
|
||||||
|
.I .git
|
||||||
|
directory.
|
||||||
|
The user and group presented is the same as the user and
|
||||||
|
group of the
|
||||||
|
.I .git
|
||||||
|
directory.
|
||||||
|
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
|
@ -100,11 +109,14 @@ The global configuration for git tools.
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
Symlinks are only partially supported.
|
Symlinks are only partially supported.
|
||||||
Symlinks are treated as regular files when reading.
|
They will be followed when reading, but a commit that
|
||||||
Modifying symlinks is unsupported.
|
modifies a symlink is an error.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
There is no way to inspect the raw objects. This is
|
For efficiency, git/fs only loads repo permissions at startup
|
||||||
a feature that would be useful for debugging.
|
|
||||||
|
.PP
|
||||||
|
There is no way to inspect the raw objects.
|
||||||
|
Inspecting raw objects would be useful for debugging.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ char *qroot[] = {
|
||||||
|
|
||||||
char gitdir[512];
|
char gitdir[512];
|
||||||
char *username;
|
char *username;
|
||||||
|
char *groupname;
|
||||||
char *mntpt = ".git/fs";
|
char *mntpt = ".git/fs";
|
||||||
char **branches = nil;
|
char **branches = nil;
|
||||||
Cache uqidcache[512];
|
Cache uqidcache[512];
|
||||||
|
@ -164,7 +165,7 @@ obj2dir(Dir *d, Crumb *c, Object *o, char *name)
|
||||||
d->mode = c->mode;
|
d->mode = c->mode;
|
||||||
d->name = estrdup9p(name);
|
d->name = estrdup9p(name);
|
||||||
d->uid = estrdup9p(username);
|
d->uid = estrdup9p(username);
|
||||||
d->gid = estrdup9p(username);
|
d->gid = estrdup9p(groupname);
|
||||||
d->muid = estrdup9p(username);
|
d->muid = estrdup9p(username);
|
||||||
if(o->type == GBlob || o->type == GTag){
|
if(o->type == GBlob || o->type == GTag){
|
||||||
d->qid.type = 0;
|
d->qid.type = 0;
|
||||||
|
@ -188,7 +189,7 @@ rootgen(int i, Dir *d, void *p)
|
||||||
d->qid.type = strcmp(qroot[i], "ctl") == 0 ? 0 : QTDIR;
|
d->qid.type = strcmp(qroot[i], "ctl") == 0 ? 0 : QTDIR;
|
||||||
d->qid.path = qpath(nil, i, i, Qroot);
|
d->qid.path = qpath(nil, i, i, Qroot);
|
||||||
d->uid = estrdup9p(username);
|
d->uid = estrdup9p(username);
|
||||||
d->gid = estrdup9p(username);
|
d->gid = estrdup9p(groupname);
|
||||||
d->muid = estrdup9p(username);
|
d->muid = estrdup9p(username);
|
||||||
d->mtime = c->mtime;
|
d->mtime = c->mtime;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -210,7 +211,7 @@ branchgen(int i, Dir *d, void *p)
|
||||||
d->qid.path = qpath(c, i, branchid(aux, aux->refpath), Qbranch | Internal);
|
d->qid.path = qpath(c, i, branchid(aux, aux->refpath), Qbranch | Internal);
|
||||||
d->mode = 0555 | DMDIR;
|
d->mode = 0555 | DMDIR;
|
||||||
d->uid = estrdup9p(username);
|
d->uid = estrdup9p(username);
|
||||||
d->gid = estrdup9p(username);
|
d->gid = estrdup9p(groupname);
|
||||||
d->muid = estrdup9p(username);
|
d->muid = estrdup9p(username);
|
||||||
d->mtime = c->mtime;
|
d->mtime = c->mtime;
|
||||||
d->atime = c->mtime;
|
d->atime = c->mtime;
|
||||||
|
@ -251,11 +252,10 @@ gtreegen(int i, Dir *d, void *p)
|
||||||
d->qid.type = o->type == GTree ? QTDIR : 0;
|
d->qid.type = o->type == GTree ? QTDIR : 0;
|
||||||
d->qid.path = qpath(c, i, o->id, aux->qdir);
|
d->qid.path = qpath(c, i, o->id, aux->qdir);
|
||||||
d->mode = m;
|
d->mode = m;
|
||||||
d->mode |= (o->type == GTree) ? 0755 : 0644;
|
|
||||||
d->atime = c->mtime;
|
d->atime = c->mtime;
|
||||||
d->mtime = c->mtime;
|
d->mtime = c->mtime;
|
||||||
d->uid = estrdup9p(username);
|
d->uid = estrdup9p(username);
|
||||||
d->gid = estrdup9p(username);
|
d->gid = estrdup9p(groupname);
|
||||||
d->muid = estrdup9p(username);
|
d->muid = estrdup9p(username);
|
||||||
d->name = estrdup9p(e->tree->ent[i].name);
|
d->name = estrdup9p(e->tree->ent[i].name);
|
||||||
d->length = o->size;
|
d->length = o->size;
|
||||||
|
@ -271,7 +271,7 @@ gcommitgen(int i, Dir *d, void *p)
|
||||||
c = crumb(p, 0);
|
c = crumb(p, 0);
|
||||||
o = c->obj;
|
o = c->obj;
|
||||||
d->uid = estrdup9p(username);
|
d->uid = estrdup9p(username);
|
||||||
d->gid = estrdup9p(username);
|
d->gid = estrdup9p(groupname);
|
||||||
d->muid = estrdup9p(username);
|
d->muid = estrdup9p(username);
|
||||||
d->mode = 0444;
|
d->mode = 0444;
|
||||||
d->atime = o->commit->ctime;
|
d->atime = o->commit->ctime;
|
||||||
|
@ -490,7 +490,7 @@ objwalk1(Qid *q, Object *o, Crumb *p, Crumb *c, char *name, vlong qdir, Gitaux *
|
||||||
}else if(o->type == GCommit){
|
}else if(o->type == GCommit){
|
||||||
q->type = 0;
|
q->type = 0;
|
||||||
c->mtime = o->commit->mtime;
|
c->mtime = o->commit->mtime;
|
||||||
c->mode = 0444;
|
c->mode = 0644;
|
||||||
assert(qdir == Qcommit || qdir == Qobject || qdir == Qcommittree || qdir == Qhead);
|
assert(qdir == Qcommit || qdir == Qobject || qdir == Qcommittree || qdir == Qhead);
|
||||||
if(strcmp(name, "msg") == 0)
|
if(strcmp(name, "msg") == 0)
|
||||||
q->path = qpath(p, 0, o->id, Qcommitmsg);
|
q->path = qpath(p, 0, o->id, Qcommitmsg);
|
||||||
|
@ -804,7 +804,7 @@ gitstat(Req *r)
|
||||||
aux = r->fid->aux;
|
aux = r->fid->aux;
|
||||||
c = crumb(aux, 0);
|
c = crumb(aux, 0);
|
||||||
r->d.uid = estrdup9p(username);
|
r->d.uid = estrdup9p(username);
|
||||||
r->d.gid = estrdup9p(username);
|
r->d.gid = estrdup9p(groupname);
|
||||||
r->d.muid = estrdup9p(username);
|
r->d.muid = estrdup9p(username);
|
||||||
r->d.qid = r->fid->qid;
|
r->d.qid = r->fid->qid;
|
||||||
r->d.mtime = c->mtime;
|
r->d.mtime = c->mtime;
|
||||||
|
@ -837,6 +837,8 @@ usage(void)
|
||||||
void
|
void
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
Dir *d;
|
||||||
|
|
||||||
gitinit();
|
gitinit();
|
||||||
ARGBEGIN{
|
ARGBEGIN{
|
||||||
case 'd':
|
case 'd':
|
||||||
|
@ -852,7 +854,12 @@ main(int argc, char **argv)
|
||||||
if(argc != 0)
|
if(argc != 0)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
username = getuser();
|
if((d = dirstat(".git")) == nil)
|
||||||
|
sysfatal("dirstat .git: %r");
|
||||||
|
username = strdup(d->uid);
|
||||||
|
groupname = strdup(d->gid);
|
||||||
|
free(d);
|
||||||
|
|
||||||
branches = emalloc(sizeof(char*));
|
branches = emalloc(sizeof(char*));
|
||||||
branches[0] = nil;
|
branches[0] = nil;
|
||||||
postmountsrv(&gitsrv, nil, mntpt, MCREATE);
|
postmountsrv(&gitsrv, nil, mntpt, MCREATE);
|
||||||
|
|
|
@ -70,6 +70,7 @@ int cachemax = 4096;
|
||||||
Packf *packf;
|
Packf *packf;
|
||||||
int npackf;
|
int npackf;
|
||||||
int openpacks;
|
int openpacks;
|
||||||
|
int gitdirmode = -1;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear(Object *o)
|
clear(Object *o)
|
||||||
|
@ -887,7 +888,7 @@ parsecommit(Object *o)
|
||||||
static void
|
static void
|
||||||
parsetree(Object *o)
|
parsetree(Object *o)
|
||||||
{
|
{
|
||||||
int m, entsz, nent;
|
int m, a, entsz, nent;
|
||||||
Dirent *t, *ent;
|
Dirent *t, *ent;
|
||||||
char *p, *ep;
|
char *p, *ep;
|
||||||
|
|
||||||
|
@ -908,7 +909,15 @@ parsetree(Object *o)
|
||||||
if(*p != ' ')
|
if(*p != ' ')
|
||||||
sysfatal("malformed tree %H: *p=(%d) %c\n", o->hash, *p, *p);
|
sysfatal("malformed tree %H: *p=(%d) %c\n", o->hash, *p, *p);
|
||||||
p++;
|
p++;
|
||||||
t->mode = m & 0777;
|
/*
|
||||||
|
* only the stored permissions for the user
|
||||||
|
* are relevant; git fills group and world
|
||||||
|
* bits with whatever -- so to serve with
|
||||||
|
* useful permissions, replicate the mode
|
||||||
|
* of the git repo dir.
|
||||||
|
*/
|
||||||
|
a = (m & 0777)>>6;
|
||||||
|
t->mode = ((a<<6)|(a<<3)|a) & gitdirmode;
|
||||||
t->ismod = 0;
|
t->ismod = 0;
|
||||||
t->islink = 0;
|
t->islink = 0;
|
||||||
if(m == 0160000){
|
if(m == 0160000){
|
||||||
|
@ -1048,7 +1057,14 @@ Object*
|
||||||
readobject(Hash h)
|
readobject(Hash h)
|
||||||
{
|
{
|
||||||
Object *o;
|
Object *o;
|
||||||
|
Dir *d;
|
||||||
|
|
||||||
|
if(gitdirmode == -1){
|
||||||
|
if((d = dirstat(".git")) == nil)
|
||||||
|
sysfatal("stat .git: %r");
|
||||||
|
gitdirmode = d->mode & 0777;
|
||||||
|
free(d);
|
||||||
|
}
|
||||||
if((o = readidxobject(nil, h, 0)) == nil)
|
if((o = readidxobject(nil, h, 0)) == nil)
|
||||||
return nil;
|
return nil;
|
||||||
parseobject(o);
|
parseobject(o);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue