diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-10-29 22:00:38 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-10-29 22:00:38 +0100 |
commit | 559d2fc8359bb9f2c6517861f084b70fe51fc573 (patch) | |
tree | 47f8224167e74c1b62e6177b10e887b2a0f9ef59 | |
parent | 6812f4679be6b8fcd96bc2cad9c38a8344bae78e (diff) |
hgfs: work in progress stuff...
-rw-r--r-- | sys/src/cmd/hgfs/ancestor.c | 108 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/fns.h | 5 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/hash.c | 18 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/hgdb.c | 34 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/mkfile | 2 | ||||
-rw-r--r-- | sys/src/cmd/hgfs/util.c | 15 |
6 files changed, 172 insertions, 10 deletions
diff --git a/sys/src/cmd/hgfs/ancestor.c b/sys/src/cmd/hgfs/ancestor.c new file mode 100644 index 000000000..2aa764897 --- /dev/null +++ b/sys/src/cmd/hgfs/ancestor.c @@ -0,0 +1,108 @@ +#include <u.h> +#include <libc.h> +#include <thread.h> +#include "dat.h" +#include "fns.h" + +typedef struct XNode XNode; +struct XNode +{ + XNode *next; + XNode *queue; + char mark; + uchar hash[HASHSZ]; +}; + +static XNode* +hnode(XNode *ht[], uchar hash[]) +{ + XNode *h; + + for(h = ht[hash[0]]; h; h = h->next) + if(memcmp(h->hash, hash, HASHSZ) == 0) + return h; + + h = malloc(sizeof(*h)); + memmove(h->hash, hash, HASHSZ); + h->mark = 0; + h->queue = nil; + h->next = ht[hash[0]]; + ht[hash[0]] = h; + return h; +} + +/* + * find common ancestor revision ahash for xhash and yhash + * in the give hgfs mount point. sets ahash to nullid if + * no common ancestor. + */ +void +ancestor(char *mtpt, uchar xhash[], uchar yhash[], uchar ahash[]) +{ + XNode *ht[256], *h, *q, *q1, *q2; + char buf[MAXPATH], rev[6]; + int i; + + if(memcmp(xhash, yhash, HASHSZ) == 0){ + memmove(ahash, xhash, HASHSZ); + return; + } + if(memcmp(xhash, nullid, HASHSZ) == 0){ + memmove(ahash, nullid, HASHSZ); + return; + } + if(memcmp(yhash, nullid, HASHSZ) == 0){ + memmove(ahash, nullid, HASHSZ); + return; + } + + memset(ht, 0, sizeof(ht)); + q1 = nil; + + h = hnode(ht, xhash); + h->mark = 'x'; + h->queue = q1; + q1 = h; + + h = hnode(ht, yhash); + h->mark = 'y'; + h->queue = q1; + q1 = h; + + for(;;){ + q2 = nil; + while(q = q1){ + q1 = q->queue; + q->queue = nil; + snprint(buf, sizeof(buf), "%s/%H", mtpt, q->hash); + for(i=1; i<=2; i++){ + sprint(rev, "rev%d", i); + if(readhash(buf, rev, ahash) != 0) + continue; + if(memcmp(ahash, nullid, HASHSZ) == 0) + continue; + h = hnode(ht, ahash); + if(h->mark){ + if(h->mark != q->mark) + goto Done; + } else { + h->mark = q->mark; + h->queue = q2; + q2 = h; + } + } + } + if(q2 == nil){ + memmove(ahash, nullid, HASHSZ); + break; + } + q1 = q2; + } + +Done: + for(i=0; i<nelem(ht); i++) + while(h = ht[i]){ + ht[i] = h->next; + free(h); + } +} diff --git a/sys/src/cmd/hgfs/fns.h b/sys/src/cmd/hgfs/fns.h index 4802f3931..7e875a6ab 100644 --- a/sys/src/cmd/hgfs/fns.h +++ b/sys/src/cmd/hgfs/fns.h @@ -3,6 +3,7 @@ int Hfmt(Fmt *f); int hex2hash(char *s, uchar *h); uvlong hash2qid(uchar *h); int fhash(int fd, uchar p1[], uchar p2[], uchar h[]); +int readhash(char *path, char *name, uchar hash[]); /* patch */ int fpatchmark(int pfd, char *mark); @@ -34,3 +35,7 @@ void closerevtree(Revtree *t); /* util */ ulong hashstr(char *s); int getworkdir(char *work, char *path); +int readfile(char *path, char *buf, int nbuf); + +/* ancestor */ +void ancestor(char *mtpt, uchar xhash[], uchar yhash[], uchar ahash[]); diff --git a/sys/src/cmd/hgfs/hash.c b/sys/src/cmd/hgfs/hash.c index e477c5734..342977ef4 100644 --- a/sys/src/cmd/hgfs/hash.c +++ b/sys/src/cmd/hgfs/hash.c @@ -78,3 +78,21 @@ hash2qid(uchar *h) v |= (uvlong)h[i]<<(56-8*i); return v; } + +int +readhash(char *path, char *name, uchar hash[]) +{ + char buf[MAXPATH], *p; + int n; + + snprint(buf, sizeof(buf), "%s/%s", path, name); + readfile(buf, buf, sizeof(buf)); + if(p = strchr(buf, '.')) + p++; + else + p = buf; + n = hex2hash(p, hash); + if(n != HASHSZ) + return -1; + return 0; +} diff --git a/sys/src/cmd/hgfs/hgdb.c b/sys/src/cmd/hgfs/hgdb.c index c835b006b..46a724f32 100644 --- a/sys/src/cmd/hgfs/hgdb.c +++ b/sys/src/cmd/hgfs/hgdb.c @@ -1,4 +1,4 @@ -/* hg debug stuff, just dumps dirstate database right now */ +/* hg debug stuff, will become update/merge program */ #include <u.h> #include <libc.h> @@ -119,9 +119,9 @@ Error: } void -changes(char *ppath, char *rpath) +changes(char *lpath, char *rpath, char *apath) { - print("diff -r %s %s\n", ppath, rpath); + print("local=%s\nremote=%s\nancestor=%s\n", lpath, rpath, apath); } void @@ -134,7 +134,8 @@ usage(void) void main(int argc, char *argv[]) { - char ppath[MAXPATH], rpath[MAXPATH]; + char lpath[MAXPATH], rpath[MAXPATH], apath[MAXPATH]; + uchar rhash[HASHSZ], ahash[HASHSZ]; char *mtpt, *rev; Workdir wd; @@ -156,15 +157,30 @@ main(int argc, char *argv[]) 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); + snprint(rpath, sizeof(rpath), "%s/%s", mtpt, rev); + if(readhash(rpath, "rev", rhash) != 0) + sysfatal("unable to get hash for %s", rev); + + if(memcmp(rhash, wd.p1hash, HASHSZ) == 0){ + fprint(2, "up to date\n"); + exits(0); + } + + ancestor(mtpt, wd.p1hash, rhash, ahash); + if(memcmp(ahash, nullid, HASHSZ) == 0) + sysfatal("no common ancestor between %H and %H", wd.p1hash, rhash); + + if(memcmp(ahash, rhash, HASHSZ) == 0) + memmove(ahash, wd.p1hash, HASHSZ); - changes(ppath, rpath); + snprint(lpath, sizeof(lpath), "%s/%H/files", mtpt, wd.p1hash); + snprint(rpath, sizeof(rpath), "%s/%H/files", mtpt, rhash); + snprint(apath, sizeof(apath), "%s/%H/files", mtpt, ahash); + + changes(lpath, rpath, apath); exits(0); } diff --git a/sys/src/cmd/hgfs/mkfile b/sys/src/cmd/hgfs/mkfile index 70607b2a7..702df525f 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 hash.$O util.$O +$O.hgdb: hgdb.$O hash.$O util.$O ancestor.$O $LD $LDFLAGS -o $target $prereq diff --git a/sys/src/cmd/hgfs/util.c b/sys/src/cmd/hgfs/util.c index 984302b8a..5af0937d0 100644 --- a/sys/src/cmd/hgfs/util.c +++ b/sys/src/cmd/hgfs/util.c @@ -42,3 +42,18 @@ getworkdir(char *work, char *path) } return -1; } + +int +readfile(char *path, char *buf, int nbuf) +{ + int fd, n; + + n = 0; + if((fd = open(path, OREAD)) >= 0){ + if((n = read(fd, buf, nbuf-1)) < 0) + n = 0; + close(fd); + } + buf[n] = '\0'; + return n; +} |