ref: d6fa07c6a0190bc922f11a117263264518d155f5
parent: 72000ca276cc993a2f6924da9e321bfea91ac92e
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Mar 29 13:35:35 EDT 2020
unref objects from git/send When pushing a large repo, git/send will run out of memory fairly quickly. This makes git/send run out of memory fairly slowly, and only on large repos.
--- a/pack.c
+++ b/pack.c
@@ -880,6 +880,7 @@
goto error;
Bterm(f);
parseobject(obj);
+ free(d);
cache(obj);
return obj;
error:
--- a/send.c
+++ b/send.c
@@ -37,6 +37,8 @@
char **branch;
char *removed[128];
int nremoved;
+int npacked;
+int nsent;
static int
hwrite(int fd, void *buf, int nbuf, DigestState **st)
@@ -62,6 +64,7 @@
if((s = readobject(o->commit->tree)) == nil)
sysfatal("could not read tree %H: %r", o->hash);
pack(send, skip, s);
+ unref(s);
break;
case GTree:
for(i = 0; i < o->tree->nent; i++){
@@ -69,6 +72,7 @@
if ((s = readobject(e->h)) == nil)
sysfatal("could not read entry %H: %r", e->h);
pack(send, skip, s);
+ unref(s);
}
break;
default:
@@ -172,6 +176,7 @@
if((o = readobject(u->theirs)) == nil)
sysfatal("could not read %H", u->theirs);
pack(&skip, &skip, o);
+ unref(o);
}
q = nil;
@@ -179,14 +184,13 @@
for(i = 0; i < nupd; i++){
u = &upd[i];
if((o = readobject(u->ours)) == nil){
- if(force)
- continue;
- else
+ if(!force)
sysfatal("could not read object %H", u->ours);
+ continue;
}
-
n = emalloc(sizeof(Objq));
n->obj = o;
+ unref(o);
if(!q){
q = n;
e = n;
@@ -213,6 +217,7 @@
n = q->next;
free(q);
}
+ fprint(2, "\n");
st = nil;
PUTBE32(buf, send.nobj);
@@ -223,8 +228,10 @@
for(i = 0; i < send.sz; i++){
if(!send.obj[i])
continue;
- if(writeobject(c->wfd, send.obj[i], &st) == -1)
+ o = readobject(send.obj[i]->hash);
+ if(writeobject(c->wfd, o, &st) == -1)
return -1;
+ unref(o);
}
sha1(nil, 0, h.h, st);
if(write(c->wfd, h.h, sizeof(h.h)) == -1)
@@ -284,7 +291,7 @@
int i, n, r, nupd, nsp, send;
char buf[Pktmax], *sp[3];
Update *upd, *u;
- Object *a, *b;
+ Object *a, *b, *p;
nupd = readours(&upd);
while(1){
@@ -313,7 +320,10 @@
u = &upd[i];
a = readobject(u->theirs);
b = readobject(u->ours);
- if(!force && !hasheq(&u->theirs, &Zhash) && (a == nil || ancestor(a, b) != a)){
+ p = nil;
+ if(a && b)
+ p = ancestor(a, b);
+ if(!force && !hasheq(&u->theirs, &Zhash) && (a == nil || p != a)){
fprint(2, "remote has diverged\n");
werrstr("force needed");
send=0;
@@ -320,6 +330,9 @@
r = -1;
break;
}
+ unref(a);
+ unref(b);
+ unref(p);
if(hasheq(&u->ours, &Zhash)){
print("removed %s\n", u->ref);
continue;