mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
git/save: pffff. revert last change...
This commit is contained in:
parent
de7d3753a5
commit
0e7690a4f8
1 changed files with 48 additions and 52 deletions
|
@ -191,6 +191,21 @@ tracked(char *path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pathelt(char *buf, int nbuf, char *p, int *isdir)
|
||||
{
|
||||
char *b;
|
||||
|
||||
b = buf;
|
||||
if(*p == '/')
|
||||
p++;
|
||||
while(*p && *p != '/' && b != buf + nbuf)
|
||||
*b++ = *p++;
|
||||
*b = '\0';
|
||||
*isdir = (*p == '/');
|
||||
return b - buf;
|
||||
}
|
||||
|
||||
Dirent*
|
||||
dirent(Dirent **ent, int *nent, char *name)
|
||||
{
|
||||
|
@ -210,64 +225,37 @@ dirent(Dirent **ent, int *nent, char *name)
|
|||
int
|
||||
treeify(Object *t, char **path, char **epath, int off, Hash *h)
|
||||
{
|
||||
int nent, ne, slash;
|
||||
char *s, **p, **ep;
|
||||
int r, n, ne, nsub, nent, isdir;
|
||||
char **p, **ep;
|
||||
char elt[256];
|
||||
Object **sub;
|
||||
Dirent *e, *ent;
|
||||
Object *o;
|
||||
Dir *d;
|
||||
|
||||
r = -1;
|
||||
nsub = 0;
|
||||
nent = t->tree->nent;
|
||||
ent = eamalloc(nent, sizeof(*ent));
|
||||
sub = eamalloc((epath - path), sizeof(Object*));
|
||||
memcpy(ent, t->tree->ent, nent*sizeof(*ent));
|
||||
for(p = path; p != epath; p = ep){
|
||||
s = *p;
|
||||
|
||||
/*
|
||||
* paths have been normalized already,
|
||||
* no leading or double-slashes allowed.
|
||||
*/
|
||||
assert(s[off] != '\0' && s[off] != '/');
|
||||
|
||||
/* get next path element length (from off until '/' or nul) */
|
||||
for(ne = 1; s[off+ne] != '\0' && s[off+ne] != '/'; ne++)
|
||||
ne++;
|
||||
|
||||
/* truncate at '/' or nul */
|
||||
slash = s[off + ne];
|
||||
s[off + ne] = '\0';
|
||||
|
||||
/* skip over children (having s as prefix) */
|
||||
for(ep = p + 1; ep != epath; ep++){
|
||||
if(strncmp(s, *ep, off + ne) != 0)
|
||||
ne = pathelt(elt, sizeof(elt), *p + off, &isdir);
|
||||
for(ep = p; ep != epath; ep++){
|
||||
if(strncmp(elt, *ep + off, ne) != 0)
|
||||
break;
|
||||
if((*ep)[off+ne] != '\0' && (*ep)[off+ne] != '/')
|
||||
break;
|
||||
}
|
||||
|
||||
e = dirent(&ent, &nent, s + off);
|
||||
|
||||
d = dirstat(s);
|
||||
if(d == nil){
|
||||
/* delete */
|
||||
e->name = nil;
|
||||
|
||||
s[off + ne] = slash;
|
||||
continue;
|
||||
}
|
||||
|
||||
e = dirent(&ent, &nent, elt);
|
||||
if(e->islink)
|
||||
sysfatal("symlinks may not be modified: %s", s);
|
||||
sysfatal("symlinks may not be modified: %s", *path);
|
||||
if(e->ismod)
|
||||
sysfatal("submodules may not be modified: %s", s);
|
||||
|
||||
s[off + ne] = slash;
|
||||
|
||||
if(slash && (d->mode & DMDIR) != 0){
|
||||
free(d);
|
||||
sysfatal("submodules may not be modified: %s", *path);
|
||||
if(isdir){
|
||||
e->mode = DMDIR | 0755;
|
||||
o = readobject(e->h);
|
||||
if(o == nil || o->type != GTree)
|
||||
o = emptydir();
|
||||
sub[nsub] = readobject(e->h);
|
||||
if(sub[nsub] == nil || sub[nsub]->type != GTree)
|
||||
sub[nsub] = emptydir();
|
||||
/*
|
||||
* if after processing deletions, a tree is empty,
|
||||
* mark it for removal from the parent.
|
||||
|
@ -276,21 +264,29 @@ treeify(Object *t, char **path, char **epath, int off, Hash *h)
|
|||
* but this is fine -- and ensures that an empty
|
||||
* repository will continue to work.
|
||||
*/
|
||||
if(treeify(o, p, ep, off + ne + 1, &e->h) == 0)
|
||||
n = treeify(sub[nsub], p, ep, off + ne + 1, &e->h);
|
||||
if(n == 0)
|
||||
e->name = nil;
|
||||
else if(n == -1)
|
||||
goto err;
|
||||
}else{
|
||||
if((d->mode & DMDIR) == 0 && tracked(s))
|
||||
blobify(d, s, &e->mode, &e->h);
|
||||
d = dirstat(*p);
|
||||
if(d != nil && tracked(*p))
|
||||
blobify(d, *p, &e->mode, &e->h);
|
||||
else
|
||||
e->name = nil;
|
||||
free(d);
|
||||
}
|
||||
}
|
||||
if(nent == 0)
|
||||
sysfatal("%.*s: refusing to update empty directory", off, *path);
|
||||
nent = writetree(ent, nent, h);
|
||||
free(ent);
|
||||
return nent;
|
||||
if(nent == 0){
|
||||
werrstr("%.*s: empty directory", off, *path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = writetree(ent, nent, h);
|
||||
err:
|
||||
free(sub);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue