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
|
||||
Trees are presented as directory listings, and blobs
|
||||
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
|
||||
.TP
|
||||
|
@ -100,11 +109,14 @@ The global configuration for git tools.
|
|||
|
||||
.SH BUGS
|
||||
Symlinks are only partially supported.
|
||||
Symlinks are treated as regular files when reading.
|
||||
Modifying symlinks is unsupported.
|
||||
They will be followed when reading, but a commit that
|
||||
modifies a symlink is an error.
|
||||
|
||||
.PP
|
||||
There is no way to inspect the raw objects. This is
|
||||
a feature that would be useful for debugging.
|
||||
For efficiency, git/fs only loads repo permissions at startup
|
||||
|
||||
.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 *username;
|
||||
char *groupname;
|
||||
char *mntpt = ".git/fs";
|
||||
char **branches = nil;
|
||||
Cache uqidcache[512];
|
||||
|
@ -164,7 +165,7 @@ obj2dir(Dir *d, Crumb *c, Object *o, char *name)
|
|||
d->mode = c->mode;
|
||||
d->name = estrdup9p(name);
|
||||
d->uid = estrdup9p(username);
|
||||
d->gid = estrdup9p(username);
|
||||
d->gid = estrdup9p(groupname);
|
||||
d->muid = estrdup9p(username);
|
||||
if(o->type == GBlob || o->type == GTag){
|
||||
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.path = qpath(nil, i, i, Qroot);
|
||||
d->uid = estrdup9p(username);
|
||||
d->gid = estrdup9p(username);
|
||||
d->gid = estrdup9p(groupname);
|
||||
d->muid = estrdup9p(username);
|
||||
d->mtime = c->mtime;
|
||||
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->mode = 0555 | DMDIR;
|
||||
d->uid = estrdup9p(username);
|
||||
d->gid = estrdup9p(username);
|
||||
d->gid = estrdup9p(groupname);
|
||||
d->muid = estrdup9p(username);
|
||||
d->mtime = 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.path = qpath(c, i, o->id, aux->qdir);
|
||||
d->mode = m;
|
||||
d->mode |= (o->type == GTree) ? 0755 : 0644;
|
||||
d->atime = c->mtime;
|
||||
d->mtime = c->mtime;
|
||||
d->uid = estrdup9p(username);
|
||||
d->gid = estrdup9p(username);
|
||||
d->gid = estrdup9p(groupname);
|
||||
d->muid = estrdup9p(username);
|
||||
d->name = estrdup9p(e->tree->ent[i].name);
|
||||
d->length = o->size;
|
||||
|
@ -271,7 +271,7 @@ gcommitgen(int i, Dir *d, void *p)
|
|||
c = crumb(p, 0);
|
||||
o = c->obj;
|
||||
d->uid = estrdup9p(username);
|
||||
d->gid = estrdup9p(username);
|
||||
d->gid = estrdup9p(groupname);
|
||||
d->muid = estrdup9p(username);
|
||||
d->mode = 0444;
|
||||
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){
|
||||
q->type = 0;
|
||||
c->mtime = o->commit->mtime;
|
||||
c->mode = 0444;
|
||||
c->mode = 0644;
|
||||
assert(qdir == Qcommit || qdir == Qobject || qdir == Qcommittree || qdir == Qhead);
|
||||
if(strcmp(name, "msg") == 0)
|
||||
q->path = qpath(p, 0, o->id, Qcommitmsg);
|
||||
|
@ -804,7 +804,7 @@ gitstat(Req *r)
|
|||
aux = r->fid->aux;
|
||||
c = crumb(aux, 0);
|
||||
r->d.uid = estrdup9p(username);
|
||||
r->d.gid = estrdup9p(username);
|
||||
r->d.gid = estrdup9p(groupname);
|
||||
r->d.muid = estrdup9p(username);
|
||||
r->d.qid = r->fid->qid;
|
||||
r->d.mtime = c->mtime;
|
||||
|
@ -837,6 +837,8 @@ usage(void)
|
|||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Dir *d;
|
||||
|
||||
gitinit();
|
||||
ARGBEGIN{
|
||||
case 'd':
|
||||
|
@ -852,7 +854,12 @@ main(int argc, char **argv)
|
|||
if(argc != 0)
|
||||
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[0] = nil;
|
||||
postmountsrv(&gitsrv, nil, mntpt, MCREATE);
|
||||
|
|
|
@ -70,6 +70,7 @@ int cachemax = 4096;
|
|||
Packf *packf;
|
||||
int npackf;
|
||||
int openpacks;
|
||||
int gitdirmode = -1;
|
||||
|
||||
static void
|
||||
clear(Object *o)
|
||||
|
@ -887,7 +888,7 @@ parsecommit(Object *o)
|
|||
static void
|
||||
parsetree(Object *o)
|
||||
{
|
||||
int m, entsz, nent;
|
||||
int m, a, entsz, nent;
|
||||
Dirent *t, *ent;
|
||||
char *p, *ep;
|
||||
|
||||
|
@ -908,7 +909,15 @@ parsetree(Object *o)
|
|||
if(*p != ' ')
|
||||
sysfatal("malformed tree %H: *p=(%d) %c\n", o->hash, *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->islink = 0;
|
||||
if(m == 0160000){
|
||||
|
@ -1048,7 +1057,14 @@ Object*
|
|||
readobject(Hash h)
|
||||
{
|
||||
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)
|
||||
return nil;
|
||||
parseobject(o);
|
||||
|
|
Loading…
Reference in a new issue