hgfs: more work in progress stuff
This commit is contained in:
parent
90cbdce8ab
commit
6812f4679b
8 changed files with 182 additions and 77 deletions
|
@ -94,3 +94,5 @@ struct Revfile
|
||||||
char *buf;
|
char *buf;
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uchar nullid[HASHSZ];
|
||||||
|
|
|
@ -32,4 +32,5 @@ Revtree *loadchangestree(Revlog *changelog, Revlog *manifest, Revinfo *ri);
|
||||||
void closerevtree(Revtree *t);
|
void closerevtree(Revtree *t);
|
||||||
|
|
||||||
/* util */
|
/* util */
|
||||||
int getdothg(char *dothg, char *path);
|
ulong hashstr(char *s);
|
||||||
|
int getworkdir(char *work, char *path);
|
||||||
|
|
|
@ -44,7 +44,7 @@ static Revlog changelog;
|
||||||
static Revlog manifest;
|
static Revlog manifest;
|
||||||
static Revlog *revlogs;
|
static Revlog *revlogs;
|
||||||
|
|
||||||
static char dothg[MAXPATH];
|
static char workdir[MAXPATH];
|
||||||
static int mangle = 0;
|
static int mangle = 0;
|
||||||
|
|
||||||
static Revlog*
|
static Revlog*
|
||||||
|
@ -56,7 +56,7 @@ getrevlog(Revnode *nd)
|
||||||
|
|
||||||
mang = mangle;
|
mang = mangle;
|
||||||
Again:
|
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);
|
buf+sizeof(buf), nd, mang);
|
||||||
for(rl = revlogs; rl; rl = rl->next)
|
for(rl = revlogs; rl; rl = rl->next)
|
||||||
if(strcmp(buf, rl->path) == 0)
|
if(strcmp(buf, rl->path) == 0)
|
||||||
|
@ -762,13 +762,13 @@ main(int argc, char *argv[])
|
||||||
usage();
|
usage();
|
||||||
} ARGEND;
|
} ARGEND;
|
||||||
|
|
||||||
if(getdothg(dothg, *argv) < 0)
|
if(getworkdir(workdir, *argv) < 0)
|
||||||
sysfatal("can't find .hg: %r");
|
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)
|
if(revlogopen(&changelog, buf, OREAD) < 0)
|
||||||
sysfatal("can't open changelog: %r\n");
|
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)
|
if(revlogopen(&manifest, buf, OREAD) < 0)
|
||||||
sysfatal("can't open menifest: %r\n");
|
sysfatal("can't open menifest: %r\n");
|
||||||
|
|
||||||
|
@ -776,4 +776,3 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
exits(0);
|
exits(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,61 +6,165 @@
|
||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
|
|
||||||
char dothg[MAXPATH];
|
typedef struct Workdir Workdir;
|
||||||
|
typedef struct Dstate Dstate;
|
||||||
|
|
||||||
|
struct Dstate
|
||||||
|
{
|
||||||
|
Dstate *next;
|
||||||
|
int mode;
|
||||||
|
ulong size;
|
||||||
|
long mtime;
|
||||||
|
char status;
|
||||||
|
char path[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Workdir
|
||||||
|
{
|
||||||
|
char path[MAXPATH];
|
||||||
|
uchar p1hash[HASHSZ];
|
||||||
|
uchar p2hash[HASHSZ];
|
||||||
|
Dstate *ht[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
static Dstate**
|
||||||
|
dslookup(Workdir *wd, char *path)
|
||||||
|
{
|
||||||
|
Dstate **hp, *h;
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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(;;){
|
||||||
|
if((n = read(fd, hdr, sizeof(hdr))) == 0)
|
||||||
|
break;
|
||||||
|
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
|
void
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char buf[MAXPATH];
|
char ppath[MAXPATH], rpath[MAXPATH];
|
||||||
uchar hdr[1+4+4+4+4];
|
char *mtpt, *rev;
|
||||||
int n, fd;
|
Workdir wd;
|
||||||
|
|
||||||
|
fmtinstall('H', Hfmt);
|
||||||
|
|
||||||
|
rev = "tip";
|
||||||
|
mtpt = "/mnt/hg";
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
|
case 'm':
|
||||||
|
mtpt = EARGF(usage());
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
rev = EARGF(usage());
|
||||||
|
break;
|
||||||
} ARGEND;
|
} ARGEND;
|
||||||
|
|
||||||
if(getdothg(dothg, *argv) < 0)
|
memset(&wd, 0, sizeof(wd));
|
||||||
sysfatal("can't find .hg: %r");
|
if(loadworkdir(&wd, *argv) < 0)
|
||||||
|
sysfatal("loadworkdir: %r");
|
||||||
|
|
||||||
snprint(buf, sizeof(buf), "%s/dirstate", dothg);
|
print("%s\n%H\n%H\n", wd.path, wd.p1hash, wd.p2hash);
|
||||||
if((fd = open(buf, OREAD)) < 0)
|
|
||||||
sysfatal("can't open dirstate: %r");
|
|
||||||
|
|
||||||
if(seek(fd, 0x28LL, 0) != 0x28LL)
|
if(memcmp(wd.p2hash, nullid, HASHSZ))
|
||||||
sysfatal("can't seek dirstate: %r");
|
sysfatal("outstanding merge");
|
||||||
|
|
||||||
for(;;){
|
snprint(ppath, sizeof(ppath), "%s/%H/files", mtpt, wd.p1hash);
|
||||||
char state;
|
snprint(rpath, sizeof(rpath), "%s/%s/files", mtpt, rev);
|
||||||
int mode, len;
|
|
||||||
vlong size;
|
|
||||||
long mtime;
|
|
||||||
|
|
||||||
if((n = read(fd, hdr, sizeof(hdr))) == 0)
|
changes(ppath, rpath);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
exits(0);
|
exits(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
</sys/src/cmd/mkone
|
||||||
|
|
||||||
# debug stuff
|
# debug stuff
|
||||||
$O.hgdb: hgdb.$O util.$O
|
$O.hgdb: hgdb.$O hash.$O util.$O
|
||||||
$LD $LDFLAGS -o $target $prereq
|
$LD $LDFLAGS -o $target $prereq
|
||||||
|
|
|
@ -104,7 +104,6 @@ revlogclose(Revlog *r)
|
||||||
uchar*
|
uchar*
|
||||||
revhash(Revlog *r, int rev)
|
revhash(Revlog *r, int rev)
|
||||||
{
|
{
|
||||||
static uchar nullid[HASHSZ];
|
|
||||||
if(rev < 0 || rev >= r->nmap)
|
if(rev < 0 || rev >= r->nmap)
|
||||||
return nullid;
|
return nullid;
|
||||||
return r->map[rev].hash;
|
return r->map[rev].hash;
|
||||||
|
|
|
@ -111,22 +111,6 @@ struct Hashstr
|
||||||
char str[];
|
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
|
static int
|
||||||
loadmanifest(Revnode *root, int fd, Hashstr **ht, int nh)
|
loadmanifest(Revnode *root, int fd, Hashstr **ht, int nh)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,23 +4,39 @@
|
||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fns.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
|
int
|
||||||
getdothg(char *dothg, char *path)
|
getworkdir(char *work, char *path)
|
||||||
{
|
{
|
||||||
char buf[MAXPATH], *s;
|
char buf[MAXPATH], *s;
|
||||||
|
|
||||||
if(path != nil){
|
if(path != nil){
|
||||||
snprint(buf, sizeof(buf), "%s", path);
|
snprint(work, MAXPATH, "%s", path);
|
||||||
cleanname(buf);
|
cleanname(work);
|
||||||
} else if(getwd(buf, sizeof(buf)) == nil)
|
} else if(getwd(work, MAXPATH) == nil)
|
||||||
return -1;
|
return -1;
|
||||||
for(;;){
|
for(;;){
|
||||||
snprint(dothg, MAXPATH, "%s/.hg", buf);
|
snprint(buf, sizeof(buf), "%s/.hg", work);
|
||||||
if(access(dothg, AEXIST) == 0)
|
if(access(buf, AEXIST) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if(path != nil)
|
if(path != nil)
|
||||||
break;
|
break;
|
||||||
if((s = strrchr(buf, '/')) == nil)
|
if((s = strrchr(work, '/')) == nil)
|
||||||
break;
|
break;
|
||||||
*s = 0;
|
*s = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue