hgfs: work in progress stuff...
This commit is contained in:
parent
6812f4679b
commit
559d2fc835
6 changed files with 172 additions and 10 deletions
108
sys/src/cmd/hgfs/ancestor.c
Normal file
108
sys/src/cmd/hgfs/ancestor.c
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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[]);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue