diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-10-28 23:18:38 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-10-28 23:18:38 +0200 |
commit | 6812f4679be6b8fcd96bc2cad9c38a8344bae78e (patch) | |
tree | 79bb90accdea5f1b34a855bd5ecd413c81dbe8a4 /sys/src/cmd/hgfs | |
parent | 90cbdce8abd1edd8c56975c2f00500ba65434ab2 (diff) |
hgfs: more work in progress stuff
Diffstat (limited to 'sys/src/cmd/hgfs')
-rw-r--r-- | sys/src/cmd/hgfs/dat.h | 2 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/fns.h | 3 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/fs.c | 13 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/hgdb.c | 192 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/mkfile | 2 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/revlog.c | 1 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/tree.c | 16 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/util.c | 30 |
8 files changed, 182 insertions, 77 deletions
diff --git a/sys/src/cmd/hgfs/dat.h b/sys/src/cmd/hgfs/dat.h index 2a0ee580e..acab7db5e 100644 --- a/sys/src/cmd/hgfs/dat.h +++ b/sys/src/cmd/hgfs/dat.h @@ -94,3 +94,5 @@ struct Revfile char *buf; int fd; }; + +uchar nullid[HASHSZ]; diff --git a/sys/src/cmd/hgfs/fns.h b/sys/src/cmd/hgfs/fns.h index 3aba47ccb..4802f3931 100644 --- a/sys/src/cmd/hgfs/fns.h +++ b/sys/src/cmd/hgfs/fns.h @@ -32,4 +32,5 @@ Revtree *loadchangestree(Revlog *changelog, Revlog *manifest, Revinfo *ri); void closerevtree(Revtree *t); /* util */ -int getdothg(char *dothg, char *path); +ulong hashstr(char *s); +int getworkdir(char *work, char *path); diff --git a/sys/src/cmd/hgfs/fs.c b/sys/src/cmd/hgfs/fs.c index 3cac4144b..4b58a515c 100644 --- a/sys/src/cmd/hgfs/fs.c +++ b/sys/src/cmd/hgfs/fs.c @@ -44,7 +44,7 @@ static Revlog changelog; static Revlog manifest; static Revlog *revlogs; -static char dothg[MAXPATH]; +static char workdir[MAXPATH]; static int mangle = 0; static Revlog* @@ -56,7 +56,7 @@ getrevlog(Revnode *nd) mang = mangle; Again: - nodepath(seprint(buf, buf+sizeof(buf), "%s/store/data", dothg), + nodepath(seprint(buf, buf+sizeof(buf), "%s/.hg/store/data", workdir), buf+sizeof(buf), nd, mang); for(rl = revlogs; rl; rl = rl->next) if(strcmp(buf, rl->path) == 0) @@ -762,13 +762,13 @@ main(int argc, char *argv[]) usage(); } ARGEND; - if(getdothg(dothg, *argv) < 0) - sysfatal("can't find .hg: %r"); + if(getworkdir(workdir, *argv) < 0) + sysfatal("can't find workdir: %r"); - snprint(buf, sizeof(buf), "%s/store/00changelog", dothg); + snprint(buf, sizeof(buf), "%s/.hg/store/00changelog", workdir); if(revlogopen(&changelog, buf, OREAD) < 0) sysfatal("can't open changelog: %r\n"); - snprint(buf, sizeof(buf), "%s/store/00manifest", dothg); + snprint(buf, sizeof(buf), "%s/.hg/store/00manifest", workdir); if(revlogopen(&manifest, buf, OREAD) < 0) sysfatal("can't open menifest: %r\n"); @@ -776,4 +776,3 @@ main(int argc, char *argv[]) exits(0); } - diff --git a/sys/src/cmd/hgfs/hgdb.c b/sys/src/cmd/hgfs/hgdb.c index 30a189627..c835b006b 100644 --- a/sys/src/cmd/hgfs/hgdb.c +++ b/sys/src/cmd/hgfs/hgdb.c @@ -6,61 +6,165 @@ #include "dat.h" #include "fns.h" -char dothg[MAXPATH]; +typedef struct Workdir Workdir; +typedef struct Dstate Dstate; -void -main(int argc, char *argv[]) +struct Dstate { - char buf[MAXPATH]; - uchar hdr[1+4+4+4+4]; - int n, fd; + Dstate *next; + int mode; + ulong size; + long mtime; + char status; + char path[]; +}; - ARGBEGIN { - } ARGEND; +struct Workdir +{ + char path[MAXPATH]; + uchar p1hash[HASHSZ]; + uchar p2hash[HASHSZ]; + Dstate *ht[256]; +}; - if(getdothg(dothg, *argv) < 0) - sysfatal("can't find .hg: %r"); +static Dstate** +dslookup(Workdir *wd, char *path) +{ + Dstate **hp, *h; - snprint(buf, sizeof(buf), "%s/dirstate", dothg); - if((fd = open(buf, OREAD)) < 0) - sysfatal("can't open dirstate: %r"); + hp = &wd->ht[hashstr(path) % nelem(wd->ht)]; + for(h = *hp; h != nil; h = *hp){ + if(strcmp(path, h->path) == 0) + break; + hp = &h->next; + } + return hp; +} + +static void +clearworkdir(Workdir *wd) +{ + Dstate *h; + int i; + + for(i=0; i<nelem(wd->ht); i++) + while(h = wd->ht[i]){ + wd->ht[i] = h->next; + free(h); + } + memset(wd, 0, sizeof(*wd)); +} - if(seek(fd, 0x28LL, 0) != 0x28LL) - sysfatal("can't seek dirstate: %r"); +static int +loadworkdir(Workdir *wd, char *path) +{ + uchar hdr[1+4+4+4+4]; + char buf[MAXPATH], *err; + Dstate **hp, *h; + int fd, n; + memset(wd, 0, sizeof(*wd)); + if(getworkdir(wd->path, path) < 0) + return -1; + snprint(buf, sizeof(buf), "%s/.hg/dirstate", wd->path); + if((fd = open(buf, OREAD)) < 0) + return -1; + err = "dirstate truncated"; + if(read(fd, wd->p1hash, HASHSZ) != HASHSZ) + goto Error; + if(read(fd, wd->p2hash, HASHSZ) != HASHSZ) + goto Error; for(;;){ - char state; - int mode, len; - vlong size; - long mtime; - if((n = read(fd, hdr, sizeof(hdr))) == 0) break; - if(n < 0) - sysfatal("read error: %r"); - if(n < sizeof(hdr)) - sysfatal("dirstate truncated"); - - state = hdr[0]; - mode = hdr[4] | hdr[3]<<8 | hdr[2]<<16 | hdr[1]<<24; - size = hdr[8] | hdr[7]<<8 | hdr[6]<<16 | hdr[5]<<24; - mtime = hdr[12] | hdr[11]<<8 | hdr[10]<<16 | hdr[9]<<24; - len = hdr[16] | hdr[15]<<8 | hdr[14]<<16 | hdr[13]<<24; - USED(mtime); - - if(len >= sizeof(buf)) - sysfatal("invalid name length %d", len); - - n = read(fd, buf, len); - if(n < 0) - sysfatal("read error: %r"); - if(n < len) - sysfatal("dirstate name truncated"); - buf[n] = 0; - - - print("%c\t%o\t%lld\t%s\n", state, mode, size, buf); + if(n < 0){ + err = "reading dirstate: %r"; + goto Error; + } + if(n != sizeof(hdr)) + goto Error; + n = hdr[16] | hdr[15]<<8 | hdr[14]<<16 | hdr[13]<<24; + if(n < 0 || n >= sizeof(buf)){ + err = "bad path length in dirstate"; + goto Error; + } + if(read(fd, buf, n) != n) + goto Error; + buf[n++] = 0; + hp = dslookup(wd, buf); + if(*hp != nil){ + err = "duplicate entry in dirstate"; + goto Error; + } + h = malloc(sizeof(*h) + n); + if(h == nil){ + err = "out of memory"; + goto Error; + } + memmove(h->path, buf, n); + h->status = hdr[0]; + h->mode = hdr[4] | hdr[3]<<8 | hdr[2]<<16 | hdr[1]<<24; + h->size = hdr[8] | hdr[7]<<8 | hdr[6]<<16 | hdr[5]<<24; + h->mtime = hdr[12] | hdr[11]<<8 | hdr[10]<<16 | hdr[9]<<24; + h->next = *hp; + *hp = h; } + close(fd); + return 0; +Error: + clearworkdir(wd); + close(fd); + werrstr(err); + return -1; +} + +void +changes(char *ppath, char *rpath) +{ + print("diff -r %s %s\n", ppath, rpath); +} + +void +usage(void) +{ + fprint(2, "usage: %s [-m mtpt] [-r rev] [root]\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + char ppath[MAXPATH], rpath[MAXPATH]; + char *mtpt, *rev; + Workdir wd; + + fmtinstall('H', Hfmt); + + rev = "tip"; + mtpt = "/mnt/hg"; + + ARGBEGIN { + case 'm': + mtpt = EARGF(usage()); + break; + case 'r': + rev = EARGF(usage()); + break; + } ARGEND; + + memset(&wd, 0, sizeof(wd)); + if(loadworkdir(&wd, *argv) < 0) + sysfatal("loadworkdir: %r"); + + print("%s\n%H\n%H\n", wd.path, wd.p1hash, wd.p2hash); + + if(memcmp(wd.p2hash, nullid, HASHSZ)) + sysfatal("outstanding merge"); + + snprint(ppath, sizeof(ppath), "%s/%H/files", mtpt, wd.p1hash); + snprint(rpath, sizeof(rpath), "%s/%s/files", mtpt, rev); + changes(ppath, rpath); + exits(0); } diff --git a/sys/src/cmd/hgfs/mkfile b/sys/src/cmd/hgfs/mkfile index f63319185..70607b2a7 100644 --- a/sys/src/cmd/hgfs/mkfile +++ b/sys/src/cmd/hgfs/mkfile @@ -11,5 +11,5 @@ OFILES=fs.$O zip.$O patch.$O hash.$O revlog.$O tree.$O info.$O util.$O </sys/src/cmd/mkone # debug stuff -$O.hgdb: hgdb.$O util.$O +$O.hgdb: hgdb.$O hash.$O util.$O $LD $LDFLAGS -o $target $prereq diff --git a/sys/src/cmd/hgfs/revlog.c b/sys/src/cmd/hgfs/revlog.c index 0d3c44136..420a13307 100644 --- a/sys/src/cmd/hgfs/revlog.c +++ b/sys/src/cmd/hgfs/revlog.c @@ -104,7 +104,6 @@ revlogclose(Revlog *r) uchar* revhash(Revlog *r, int rev) { - static uchar nullid[HASHSZ]; if(rev < 0 || rev >= r->nmap) return nullid; return r->map[rev].hash; diff --git a/sys/src/cmd/hgfs/tree.c b/sys/src/cmd/hgfs/tree.c index 0a45f3d64..a6cb1f171 100644 --- a/sys/src/cmd/hgfs/tree.c +++ b/sys/src/cmd/hgfs/tree.c @@ -111,22 +111,6 @@ struct Hashstr char str[]; }; -static ulong -hashstr(char *s) -{ - ulong h, t; - char c; - - h = 0; - while(c = *s++){ - t = h & 0xf8000000; - h <<= 5; - h ^= t>>27; - h ^= (ulong)c; - } - return h; -} - static int loadmanifest(Revnode *root, int fd, Hashstr **ht, int nh) { diff --git a/sys/src/cmd/hgfs/util.c b/sys/src/cmd/hgfs/util.c index 179713124..984302b8a 100644 --- a/sys/src/cmd/hgfs/util.c +++ b/sys/src/cmd/hgfs/util.c @@ -4,23 +4,39 @@ #include "dat.h" #include "fns.h" +ulong +hashstr(char *s) +{ + ulong h, t; + char c; + + h = 0; + while(c = *s++){ + t = h & 0xf8000000; + h <<= 5; + h ^= t>>27; + h ^= (ulong)c; + } + return h; +} + int -getdothg(char *dothg, char *path) +getworkdir(char *work, char *path) { char buf[MAXPATH], *s; if(path != nil){ - snprint(buf, sizeof(buf), "%s", path); - cleanname(buf); - } else if(getwd(buf, sizeof(buf)) == nil) + snprint(work, MAXPATH, "%s", path); + cleanname(work); + } else if(getwd(work, MAXPATH) == nil) return -1; for(;;){ - snprint(dothg, MAXPATH, "%s/.hg", buf); - if(access(dothg, AEXIST) == 0) + snprint(buf, sizeof(buf), "%s/.hg", work); + if(access(buf, AEXIST) == 0) return 0; if(path != nil) break; - if((s = strrchr(buf, '/')) == nil) + if((s = strrchr(work, '/')) == nil) break; *s = 0; } |