summaryrefslogtreecommitdiff
path: root/sys/src/cmd/hgfs
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-10-28 23:18:38 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2012-10-28 23:18:38 +0200
commit6812f4679be6b8fcd96bc2cad9c38a8344bae78e (patch)
tree79bb90accdea5f1b34a855bd5ecd413c81dbe8a4 /sys/src/cmd/hgfs
parent90cbdce8abd1edd8c56975c2f00500ba65434ab2 (diff)
hgfs: more work in progress stuff
Diffstat (limited to 'sys/src/cmd/hgfs')
-rw-r--r--sys/src/cmd/hgfs/dat.h2
-rw-r--r--sys/src/cmd/hgfs/fns.h3
-rw-r--r--sys/src/cmd/hgfs/fs.c13
-rw-r--r--sys/src/cmd/hgfs/hgdb.c192
-rw-r--r--sys/src/cmd/hgfs/mkfile2
-rw-r--r--sys/src/cmd/hgfs/revlog.c1
-rw-r--r--sys/src/cmd/hgfs/tree.c16
-rw-r--r--sys/src/cmd/hgfs/util.c30
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;
}