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.
This commit is contained in:
parent
c297482269
commit
1160919f81
3 changed files with 51 additions and 19 deletions
|
@ -1326,7 +1326,7 @@ loadtree(Metavec *v, Objset *has, Hash tree, char *dpath, vlong mtime)
|
||||||
if(t->type != GTree){
|
if(t->type != GTree){
|
||||||
fprint(2, "load: %H: not tree\n", t->hash);
|
fprint(2, "load: %H: not tree\n", t->hash);
|
||||||
unref(t);
|
unref(t);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
addmeta(v, has, t, dpath, mtime);
|
addmeta(v, has, t, dpath, mtime);
|
||||||
for(i = 0; i < t->tree->nent; i++){
|
for(i = 0; i < t->tree->nent; i++){
|
||||||
|
@ -1363,7 +1363,7 @@ loadcommit(Metavec *v, Objset *has, Hash h)
|
||||||
if(c->type != GCommit){
|
if(c->type != GCommit){
|
||||||
fprint(2, "load: %H: not commit\n", c->hash);
|
fprint(2, "load: %H: not commit\n", c->hash);
|
||||||
unref(c);
|
unref(c);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
addmeta(v, has, c, "", c->commit->ctime);
|
addmeta(v, has, c, "", c->commit->ctime);
|
||||||
r = loadtree(v, has, c->commit->tree, "", c->commit->ctime);
|
r = loadtree(v, has, c->commit->tree, "", c->commit->ctime);
|
||||||
|
|
|
@ -294,11 +294,11 @@ findtwixt(Hash *head, int nhead, Hash *tail, int ntail, Object ***res, int *nres
|
||||||
if(hasheq(&tail[i], &Zhash))
|
if(hasheq(&tail[i], &Zhash))
|
||||||
continue;
|
continue;
|
||||||
if((o = readobject(tail[i])) == nil){
|
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]);
|
werrstr("read tail %H: %r", tail[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(o->type != GCommit){
|
if(o->type != GCommit){
|
||||||
|
fprint(2, "warning: %H does not point at commit\n", o->hash);
|
||||||
unref(o);
|
unref(o);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "git.h"
|
#include "git.h"
|
||||||
|
|
||||||
typedef struct Capset Capset;
|
typedef struct Capset Capset;
|
||||||
|
typedef struct Map Map;
|
||||||
|
|
||||||
struct Capset {
|
struct Capset {
|
||||||
int sideband;
|
int sideband;
|
||||||
|
@ -11,6 +12,12 @@ struct Capset {
|
||||||
int report;
|
int report;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Map {
|
||||||
|
char *ref;
|
||||||
|
Hash ours;
|
||||||
|
Hash theirs;
|
||||||
|
};
|
||||||
|
|
||||||
int sendall;
|
int sendall;
|
||||||
int force;
|
int force;
|
||||||
int nbranch;
|
int nbranch;
|
||||||
|
@ -24,13 +31,22 @@ int
|
||||||
findref(char **r, int nr, char *ref)
|
findref(char **r, int nr, char *ref)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < nr; i++)
|
for(i = 0; i < nr; i++)
|
||||||
if(strcmp(r[i], ref) == 0)
|
if(strcmp(r[i], ref) == 0)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
int
|
||||||
readours(Hash **tailp, char ***refp)
|
readours(Hash **tailp, char ***refp)
|
||||||
{
|
{
|
||||||
|
@ -101,17 +117,27 @@ parsecaps(char *caps, Capset *cs)
|
||||||
int
|
int
|
||||||
sendpack(Conn *c)
|
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];
|
char buf[Pktmax], *sp[3];
|
||||||
Hash h, *theirs, *ours;
|
Hash h, *theirs, *ours;
|
||||||
Object *a, *b, *p;
|
Object *a, *b, *p;
|
||||||
char **refs;
|
char **refs;
|
||||||
Capset cs;
|
Capset cs;
|
||||||
|
Map *map, *m;
|
||||||
|
|
||||||
first = 1;
|
first = 1;
|
||||||
memset(&cs, 0, sizeof(Capset));
|
memset(&cs, 0, sizeof(Capset));
|
||||||
nupd = readours(&ours, &refs);
|
nours = readours(&ours, &refs);
|
||||||
theirs = eamalloc(nupd, sizeof(Hash));
|
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){
|
while(1){
|
||||||
n = readpkt(c, buf, sizeof(buf));
|
n = readpkt(c, buf, sizeof(buf));
|
||||||
if(n == -1)
|
if(n == -1)
|
||||||
|
@ -126,10 +152,12 @@ sendpack(Conn *c)
|
||||||
|
|
||||||
if(getfields(buf, sp, nelem(sp), 1, " \t\r\n") != 2)
|
if(getfields(buf, sp, nelem(sp), 1, " \t\r\n") != 2)
|
||||||
sysfatal("invalid ref line %.*s", utfnlen(buf, n), buf);
|
sysfatal("invalid ref line %.*s", utfnlen(buf, n), buf);
|
||||||
if((idx = findref(refs, nupd, sp[1])) == -1)
|
theirs = earealloc(theirs, ntheirs+1, sizeof(Hash));
|
||||||
continue;
|
if(hparse(&theirs[ntheirs], sp[0]) == -1)
|
||||||
if(hparse(&theirs[idx], sp[0]) == -1)
|
|
||||||
sysfatal("invalid hash %s", sp[0]);
|
sysfatal("invalid hash %s", sp[0]);
|
||||||
|
if((idx = findkey(map, nmap, sp[1])) != -1)
|
||||||
|
map[idx].theirs = theirs[ntheirs];
|
||||||
|
ntheirs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(writephase(c) == -1)
|
if(writephase(c) == -1)
|
||||||
|
@ -137,13 +165,17 @@ sendpack(Conn *c)
|
||||||
send = 0;
|
send = 0;
|
||||||
if(force)
|
if(force)
|
||||||
send=1;
|
send=1;
|
||||||
for(i = 0; i < nupd; i++){
|
for(i = 0; i < nmap; i++){
|
||||||
a = readobject(theirs[i]);
|
m = &map[i];
|
||||||
b = hasheq(&ours[i], &Zhash) ? nil : readobject(ours[i]);
|
a = readobject(m->theirs);
|
||||||
|
if(hasheq(&m->ours, &Zhash))
|
||||||
|
b = nil;
|
||||||
|
else
|
||||||
|
b = readobject(m->ours);
|
||||||
p = nil;
|
p = nil;
|
||||||
if(a != nil && b != nil)
|
if(a != nil && b != nil)
|
||||||
p = ancestor(a, b);
|
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");
|
fprint(2, "remote has diverged\n");
|
||||||
werrstr("force needed");
|
werrstr("force needed");
|
||||||
flushpkt(c);
|
flushpkt(c);
|
||||||
|
@ -152,12 +184,12 @@ sendpack(Conn *c)
|
||||||
unref(a);
|
unref(a);
|
||||||
unref(b);
|
unref(b);
|
||||||
unref(p);
|
unref(p);
|
||||||
if(hasheq(&theirs[i], &ours[i])){
|
if(hasheq(&m->theirs, &m->ours)){
|
||||||
print("uptodate %s\n", refs[i]);
|
print("uptodate %s\n", m->ref);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
print("update %s %H %H\n", refs[i], theirs[i], ours[i]);
|
print("update %s %H %H\n", m->ref, m->theirs, m->ours);
|
||||||
n = snprint(buf, sizeof(buf), "%H %H %s", theirs[i], ours[i], refs[i]);
|
n = snprint(buf, sizeof(buf), "%H %H %s", m->theirs, m->ours, m->ref);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Workaround for github.
|
* Workaround for github.
|
||||||
|
@ -183,7 +215,7 @@ sendpack(Conn *c)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(writepack(c->wfd, ours, nupd, theirs, nupd, &h) == -1)
|
if(writepack(c->wfd, ours, nours, theirs, ntheirs, &h) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if(!cs.report)
|
if(!cs.report)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue