git: 9front

Download patch

ref: caa816c0f91765a955d1549554f8f220c25e62b1
parent: 36e20f1b135152a82a3cd52adb0aef10258b52ad
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun Oct 28 19:18:38 EDT 2012

hgfs: more work in progress stuff

--- a/sys/src/cmd/hgfs/dat.h
+++ b/sys/src/cmd/hgfs/dat.h
@@ -94,3 +94,5 @@
 	char	*buf;
 	int	fd;
 };
+
+uchar nullid[HASHSZ];
--- a/sys/src/cmd/hgfs/fns.h
+++ b/sys/src/cmd/hgfs/fns.h
@@ -32,4 +32,5 @@
 void closerevtree(Revtree *t);
 
 /* util */
-int getdothg(char *dothg, char *path);
+ulong hashstr(char *s);
+int getworkdir(char *work, char *path);
--- a/sys/src/cmd/hgfs/fs.c
+++ b/sys/src/cmd/hgfs/fs.c
@@ -44,7 +44,7 @@
 static Revlog manifest;
 static Revlog *revlogs;
 
-static char dothg[MAXPATH];
+static char workdir[MAXPATH];
 static int mangle = 0;
 
 static Revlog*
@@ -56,7 +56,7 @@
 
 	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 @@
 		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 @@
 
 	exits(0);
 }
-
--- 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;
+}
 
-	if(seek(fd, 0x28LL, 0) != 0x28LL)
-		sysfatal("can't seek dirstate: %r");
+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));
+}
+
+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");
+		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;
+}
 
-		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);
+void
+changes(char *ppath, char *rpath)
+{
+	print("diff -r %s %s\n", ppath, rpath);
+}
 
-		if(len >= sizeof(buf))
-			sysfatal("invalid name length %d", len);
+void
+usage(void)
+{
+	fprint(2, "usage: %s [-m mtpt] [-r rev] [root]\n", argv0);
+	exits("usage");
+}
 
-		n = read(fd, buf, len);
-		if(n < 0)
-			sysfatal("read error: %r");
-		if(n < len)
-			sysfatal("dirstate name truncated");
-		buf[n] = 0;
+void
+main(int argc, char *argv[])
+{
+	char ppath[MAXPATH], rpath[MAXPATH];
+	char *mtpt, *rev;
+	Workdir wd;
 
+	fmtinstall('H', Hfmt);
 
-		print("%c\t%o\t%lld\t%s\n", state, mode, size, buf);
-	}
+	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);
 }
--- a/sys/src/cmd/hgfs/mkfile
+++ b/sys/src/cmd/hgfs/mkfile
@@ -11,5 +11,5 @@
 </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
--- a/sys/src/cmd/hgfs/revlog.c
+++ b/sys/src/cmd/hgfs/revlog.c
@@ -104,7 +104,6 @@
 uchar*
 revhash(Revlog *r, int rev)
 {
-	static uchar nullid[HASHSZ];
 	if(rev < 0 || rev >= r->nmap)
 		return nullid;
 	return r->map[rev].hash;
--- a/sys/src/cmd/hgfs/tree.c
+++ b/sys/src/cmd/hgfs/tree.c
@@ -111,22 +111,6 @@
 	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)
 {
--- 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;
 	}
--