diff options
author | Ori Bernstein <ori@eigenstate.org> | 2021-05-31 18:02:23 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2021-05-31 18:02:23 -0700 |
commit | 1160919f8197c8b1ad45f0c5bcf5cef7051202d9 (patch) | |
tree | ecd6f75b3122dd2dbf7f07ab7933a393847e6e48 | |
parent | c29748226982e52d19dfd206a680b97ed35c44f6 (diff) | |
download | plan9front-1160919f8197c8b1ad45f0c5bcf5cef7051202d9.tar.xz |
git/send: pick minimal delta set correctly (thanks igor)
We weren't giving all objects to the twixt() function, and
it was making bad life choices -- gambling, smoking, drinking,
and packing in too much data.
With more information, it doesn't do the last.
-rw-r--r-- | sys/src/cmd/git/pack.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/git/ref.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/git/send.c | 64 |
3 files changed, 51 insertions, 19 deletions
diff --git a/sys/src/cmd/git/pack.c b/sys/src/cmd/git/pack.c index 847d931fe..893e4cd85 100644 --- a/sys/src/cmd/git/pack.c +++ b/sys/src/cmd/git/pack.c @@ -1326,7 +1326,7 @@ loadtree(Metavec *v, Objset *has, Hash tree, char *dpath, vlong mtime) if(t->type != GTree){ fprint(2, "load: %H: not tree\n", t->hash); unref(t); - return -1; + return 0; } addmeta(v, has, t, dpath, mtime); for(i = 0; i < t->tree->nent; i++){ @@ -1363,7 +1363,7 @@ loadcommit(Metavec *v, Objset *has, Hash h) if(c->type != GCommit){ fprint(2, "load: %H: not commit\n", c->hash); unref(c); - return -1; + return 0; } addmeta(v, has, c, "", c->commit->ctime); r = loadtree(v, has, c->commit->tree, "", c->commit->ctime); diff --git a/sys/src/cmd/git/ref.c b/sys/src/cmd/git/ref.c index 80d79bdfc..5f67dacb0 100644 --- a/sys/src/cmd/git/ref.c +++ b/sys/src/cmd/git/ref.c @@ -294,11 +294,11 @@ findtwixt(Hash *head, int nhead, Hash *tail, int ntail, Object ***res, int *nres if(hasheq(&tail[i], &Zhash)) continue; if((o = readobject(tail[i])) == nil){ - fprint(2, "warning: %H does not point at commit\n", o->hash); werrstr("read tail %H: %r", tail[i]); return -1; } if(o->type != GCommit){ + fprint(2, "warning: %H does not point at commit\n", o->hash); unref(o); continue; } diff --git a/sys/src/cmd/git/send.c b/sys/src/cmd/git/send.c index aa4332ae5..1e44caa81 100644 --- a/sys/src/cmd/git/send.c +++ b/sys/src/cmd/git/send.c @@ -4,6 +4,7 @@ #include "git.h" typedef struct Capset Capset; +typedef struct Map Map; struct Capset { int sideband; @@ -11,6 +12,12 @@ struct Capset { int report; }; +struct Map { + char *ref; + Hash ours; + Hash theirs; +}; + int sendall; int force; int nbranch; @@ -24,7 +31,6 @@ int findref(char **r, int nr, char *ref) { int i; - for(i = 0; i < nr; i++) if(strcmp(r[i], ref) == 0) return i; @@ -32,6 +38,16 @@ findref(char **r, int nr, char *ref) } int +findkey(Map *m, int nm, char *ref) +{ + int i; + for(i = 0; i < nm; i++) + if(strcmp(m[i].ref, ref) == 0) + return i; + return -1; +} + +int readours(Hash **tailp, char ***refp) { int nu, i, idx; @@ -101,17 +117,27 @@ parsecaps(char *caps, Capset *cs) int sendpack(Conn *c) { - int i, n, idx, nupd, nsp, send, first; + int i, n, idx, nsp, send, first; + int nours, ntheirs, nmap; char buf[Pktmax], *sp[3]; Hash h, *theirs, *ours; Object *a, *b, *p; char **refs; Capset cs; + Map *map, *m; first = 1; memset(&cs, 0, sizeof(Capset)); - nupd = readours(&ours, &refs); - theirs = eamalloc(nupd, sizeof(Hash)); + nours = readours(&ours, &refs); + theirs = nil; + ntheirs = 0; + nmap = nours; + map = eamalloc(nmap, sizeof(Map)); + for(i = 0; i < nmap; i++){ + map[i].ours = ours[i]; + map[i].theirs = Zhash; + map[i].ref = refs[i]; + } while(1){ n = readpkt(c, buf, sizeof(buf)); if(n == -1) @@ -126,10 +152,12 @@ sendpack(Conn *c) if(getfields(buf, sp, nelem(sp), 1, " \t\r\n") != 2) sysfatal("invalid ref line %.*s", utfnlen(buf, n), buf); - if((idx = findref(refs, nupd, sp[1])) == -1) - continue; - if(hparse(&theirs[idx], sp[0]) == -1) + theirs = earealloc(theirs, ntheirs+1, sizeof(Hash)); + if(hparse(&theirs[ntheirs], sp[0]) == -1) sysfatal("invalid hash %s", sp[0]); + if((idx = findkey(map, nmap, sp[1])) != -1) + map[idx].theirs = theirs[ntheirs]; + ntheirs++; } if(writephase(c) == -1) @@ -137,13 +165,17 @@ sendpack(Conn *c) send = 0; if(force) send=1; - for(i = 0; i < nupd; i++){ - a = readobject(theirs[i]); - b = hasheq(&ours[i], &Zhash) ? nil : readobject(ours[i]); + for(i = 0; i < nmap; i++){ + m = &map[i]; + a = readobject(m->theirs); + if(hasheq(&m->ours, &Zhash)) + b = nil; + else + b = readobject(m->ours); p = nil; if(a != nil && b != nil) p = ancestor(a, b); - if(!force && !hasheq(&theirs[i], &Zhash) && (a == nil || p != a)){ + if(!force && !hasheq(&m->theirs, &Zhash) && (a == nil || p != a)){ fprint(2, "remote has diverged\n"); werrstr("force needed"); flushpkt(c); @@ -152,12 +184,12 @@ sendpack(Conn *c) unref(a); unref(b); unref(p); - if(hasheq(&theirs[i], &ours[i])){ - print("uptodate %s\n", refs[i]); + if(hasheq(&m->theirs, &m->ours)){ + print("uptodate %s\n", m->ref); continue; } - print("update %s %H %H\n", refs[i], theirs[i], ours[i]); - n = snprint(buf, sizeof(buf), "%H %H %s", theirs[i], ours[i], refs[i]); + print("update %s %H %H\n", m->ref, m->theirs, m->ours); + n = snprint(buf, sizeof(buf), "%H %H %s", m->theirs, m->ours, m->ref); /* * Workaround for github. @@ -183,7 +215,7 @@ sendpack(Conn *c) return 0; } - if(writepack(c->wfd, ours, nupd, theirs, nupd, &h) == -1) + if(writepack(c->wfd, ours, nours, theirs, ntheirs, &h) == -1) return -1; if(!cs.report) return 0; |