summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-10-29 22:00:38 +0100
committercinap_lenrek <cinap_lenrek@gmx.de>2012-10-29 22:00:38 +0100
commit559d2fc8359bb9f2c6517861f084b70fe51fc573 (patch)
tree47f8224167e74c1b62e6177b10e887b2a0f9ef59 /sys/src
parent6812f4679be6b8fcd96bc2cad9c38a8344bae78e (diff)
hgfs: work in progress stuff...
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/cmd/hgfs/ancestor.c108
-rw-r--r--sys/src/cmd/hgfs/fns.h5
-rw-r--r--sys/src/cmd/hgfs/hash.c18
-rw-r--r--sys/src/cmd/hgfs/hgdb.c34
-rw-r--r--sys/src/cmd/hgfs/mkfile2
-rw-r--r--sys/src/cmd/hgfs/util.c15
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;
+}