hgfs: work in progress stuff...

This commit is contained in:
cinap_lenrek 2012-10-29 22:00:38 +01:00
parent 6812f4679b
commit 559d2fc835
6 changed files with 172 additions and 10 deletions

108
sys/src/cmd/hgfs/ancestor.c Normal file
View file

@ -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);
}
}

View file

@ -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[]);

View file

@ -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;
}

View file

@ -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);
changes(ppath, rpath);
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);
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);
}

View file

@ -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

View file

@ -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;
}