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);
|
int hex2hash(char *s, uchar *h);
|
||||||
uvlong hash2qid(uchar *h);
|
uvlong hash2qid(uchar *h);
|
||||||
int fhash(int fd, uchar p1[], uchar p2[], uchar h[]);
|
int fhash(int fd, uchar p1[], uchar p2[], uchar h[]);
|
||||||
|
int readhash(char *path, char *name, uchar hash[]);
|
||||||
|
|
||||||
/* patch */
|
/* patch */
|
||||||
int fpatchmark(int pfd, char *mark);
|
int fpatchmark(int pfd, char *mark);
|
||||||
|
@ -34,3 +35,7 @@ void closerevtree(Revtree *t);
|
||||||
/* util */
|
/* util */
|
||||||
ulong hashstr(char *s);
|
ulong hashstr(char *s);
|
||||||
int getworkdir(char *work, char *path);
|
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);
|
v |= (uvlong)h[i]<<(56-8*i);
|
||||||
return v;
|
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 <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
|
@ -119,9 +119,9 @@ Error:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
void
|
||||||
|
@ -134,7 +134,8 @@ usage(void)
|
||||||
void
|
void
|
||||||
main(int argc, char *argv[])
|
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;
|
char *mtpt, *rev;
|
||||||
Workdir wd;
|
Workdir wd;
|
||||||
|
|
||||||
|
@ -156,15 +157,30 @@ main(int argc, char *argv[])
|
||||||
if(loadworkdir(&wd, *argv) < 0)
|
if(loadworkdir(&wd, *argv) < 0)
|
||||||
sysfatal("loadworkdir: %r");
|
sysfatal("loadworkdir: %r");
|
||||||
|
|
||||||
print("%s\n%H\n%H\n", wd.path, wd.p1hash, wd.p2hash);
|
|
||||||
|
|
||||||
if(memcmp(wd.p2hash, nullid, HASHSZ))
|
if(memcmp(wd.p2hash, nullid, HASHSZ))
|
||||||
sysfatal("outstanding merge");
|
sysfatal("outstanding merge");
|
||||||
|
|
||||||
snprint(ppath, sizeof(ppath), "%s/%H/files", mtpt, wd.p1hash);
|
snprint(rpath, sizeof(rpath), "%s/%s", mtpt, rev);
|
||||||
snprint(rpath, sizeof(rpath), "%s/%s/files", 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);
|
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 hash.$O util.$O
|
$O.hgdb: hgdb.$O hash.$O util.$O ancestor.$O
|
||||||
$LD $LDFLAGS -o $target $prereq
|
$LD $LDFLAGS -o $target $prereq
|
||||||
|
|
|
@ -42,3 +42,18 @@ getworkdir(char *work, char *path)
|
||||||
}
|
}
|
||||||
return -1;
|
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…
Add table
Add a link
Reference in a new issue