M pack.c => pack.c +32 -17
@@ 253,38 253,51 @@ openpack(Packf *pf)
vlong t;
int i, best;
- if(pf->pack == nil){
- if((pf->pack = Bopen(pf->path, OREAD)) == nil)
- return nil;
- openpacks++;
+ if(pf->pack != nil){
+ pf->refs++;
+ return pf->pack;
}
- if(openpacks == Npackcache){
- t = pf->opentm;
+ /*
+ * If we've got more packs open
+ * than we want cached, try to
+ * free up the oldest ones.
+ *
+ * If we can't find a slot, this
+ * isn't fatal; we can just use
+ * another fd.
+ */
+ while(openpacks >= Npackcache){
+ t = (1ull<<62)-1;
best = -1;
for(i = 0; i < npackf; i++){
- if(packf[i].opentm < t && packf[i].refs > 0){
+ if(&packf[i] != pf
+ && packf[i].pack != nil
+ && packf[i].opentm < t
+ && packf[i].refs == 0){
t = packf[i].opentm;
best = i;
}
}
- if(best != -1){
- Bterm(packf[best].pack);
- packf[best].pack = nil;
- openpacks--;
+ if(best == -1){
+ fprint(2, "no available pack slots\n");
+ break;
}
+ Bterm(packf[best].pack);
+ packf[best].pack = nil;
+ openpacks--;
}
+ openpacks++;
pf->opentm = nsec();
pf->refs++;
+ if((pf->pack = Bopen(pf->path, OREAD)) == nil)
+ return nil;
return pf->pack;
}
static void
closepack(Packf *pf)
{
- if(--pf->refs == 0){
- Bterm(pf->pack);
- pf->pack = nil;
- }
+ pf->refs--;
}
static u32int
@@ 1448,7 1461,8 @@ pickdeltas(Meta **meta, int nmeta)
pct = 0;
dprint(1, "picking deltas\n");
- fprint(2, "deltifying %d objects: 0%%", nmeta);
+ if(interactive)
+ fprint(2, "deltifying %d objects: 0%%", nmeta);
qsort(meta, nmeta, sizeof(Meta*), deltaordercmp);
for(i = 0; i < nmeta; i++){
m = meta[i];
@@ 1491,7 1505,8 @@ pickdeltas(Meta **meta, int nmeta)
}
for(i = max(0, nmeta - 10); i < nmeta; i++)
dtclear(&meta[i]->dtab);
- fprint(2, "\b\b\b\b100%%\n");
+ if(interactive)
+ fprint(2, "\b\b\b\b100%%\n");
}
static int
M ref.c => ref.c +3 -2
@@ 217,6 217,7 @@ paint(Hash *head, int nhead, Hash *tail, int ntail, Object ***res, int *nres, in
osinit(&keep);
osinit(&drop);
+ memset(&objq, 0, sizeof(objq));
qinit(&objq);
objq.head = head;
objq.nhead = nhead;
@@ 335,9 336,9 @@ ancestor(Object *a, Object *b)
if(paint(&a->hash, 1, &b->hash, 1, &o, &n, 1) == -1 || n == 0)
return nil;
- r = o[0];
+ r = ref(o[0]);
free(o);
- return ref(r);
+ return r;
}
int
M serve.c => serve.c +5 -1
@@ 98,8 98,12 @@ servnegotiate(Conn *c, Hash **head, int *nhead, Hash **tail, int *ntail)
while(1){
if((n = readpkt(c, pkt, sizeof(pkt))) == -1)
goto error;
- if(n == 0 || strncmp(pkt, "done", 4) == 0)
+ if(strncmp(pkt, "done", 4) == 0)
break;
+ if(n == 0){
+ if(!acked && fmtpkt(c, "NAK") == -1)
+ goto error;
+ }
if(strncmp(pkt, "have ", 5) != 0){
werrstr(" protocol garble %s", pkt);
goto error;
M walk.c => walk.c +15 -3
@@ 30,6 30,7 @@ enum {
Cache seencache[NCACHE];
int quiet;
int printflg;
+char *base;
char *rstr = "R ";
char *tstr = "T ";
char *mstr = "M ";
@@ 209,19 210,21 @@ mismatch:
void
usage(void)
{
- fprint(2, "usage: %s [-qbc] [-f filt] [paths...]\n", argv0);
+ fprint(2, "usage: %s [-qbc] [-f filt] [-b base] [paths...]\n", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
- char *rpath, *tpath, *bpath, buf[8], repo[512];
+ char *rpath, *tpath, *bpath, *cpath, buf[8], repo[512];
char *p, *e;
int i, dirty;
+ Hash h;
Wres r;
Dir *d;
+;
ARGBEGIN{
case 'q':
quiet++;
@@ 242,6 245,9 @@ main(int argc, char **argv)
default: usage(); break;
}
break;
+ case 'b':
+ base = EARGF(usage());
+ break;
default:
usage();
}ARGEND
@@ 252,6 258,12 @@ main(int argc, char **argv)
sysfatal("chdir: %r");
if(access(".git/fs/ctl", AEXIST) != 0)
sysfatal("no running git/fs");
+ cpath = HDIR;
+ if(base != nil){
+ if(resolveref(&h, base) == -1)
+ sysfatal("invalid base commit %s", base);
+ cpath = smprint(".git/fs/object/%H/tree", h);
+ }
dirty = 0;
memset(&r, 0, sizeof(r));
if(printflg == 0)
@@ 289,7 301,7 @@ nextarg:
goto next;
rpath = smprint(RDIR"/%s", p);
tpath = smprint(TDIR"/%s", p);
- bpath = smprint(HDIR"/%s", p);
+ bpath = smprint("%s/%s", cpath, p);
/* Fast path: we don't want to force access to the rpath. */
if(d && sameqid(d, tpath)) {
if(!quiet && (printflg & Tflg))