ref: 8a00270e0aafafe5d5d5fbdb5b513609cf560778
parent: 09cdf057aa0db2d8d63eedc7718f3dea0c6075ac
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Dec 27 21:22:57 EST 2020
git/send: fix force pushes When sending a force push, the remote expects a pack file, even if it's empty. Generate and send an empty pack when we do a force push, instead of flushing and bailing out early.
--- a/pack.c
+++ b/pack.c
@@ -1636,8 +1636,6 @@
if((nmeta = readmeta(theirs, ntheirs, ours, nours, &meta)) == -1)
return -1;
- if(nmeta == 0)
- return 0;
pickdeltas(meta, nmeta);
r = genpack(fd, meta, nmeta, h, 0);
for(i = 0; i < nmeta; i++)
--- a/send.c
+++ b/send.c
@@ -99,7 +99,7 @@
int
sendpack(Conn *c)
{
- int i, n, r, idx, nupd, nsp, send, first;
+ int i, n, idx, nupd, nsp, send, first;
char buf[Pktmax], *sp[3];
Hash h, *theirs, *ours;
Object *a, *b, *p;
@@ -131,8 +131,9 @@
if(writephase(c) == -1)
return -1;
- r = 0;
send = 0;
+ if(force)
+ send=1;
for(i = 0; i < nupd; i++){
a = readobject(theirs[i]);
b = readobject(ours[i]);
@@ -142,9 +143,8 @@
if(!force && !hasheq(&theirs[i], &Zhash) && (a == nil || p != a)){
fprint(2, "remote has diverged\n");
werrstr("force needed");
- send=0;
- r = -1;
- break;
+ flushpkt(c);
+ return -1;
}
unref(a);
unref(b);
@@ -184,37 +184,41 @@
send = 1;
}
flushpkt(c);
- if(!send)
- print("nothing to send\n");
- if(send){
- if(writepack(c->wfd, ours, nupd, theirs, nupd, &h) == -1)
- return -1;
- if(cs.report && readphase(c) == -1)
- return -1;
- /* We asked for a status report, may as well use it. */
- while(cs.report && (n = readpkt(c, buf, sizeof(buf))) > 0){
- buf[n] = 0;
- if(chattygit)
- fprint(2, "done sending pack, status %s\n", buf);
- nsp = getfields(buf, sp, nelem(sp), 1, " \t\n\r");
- if(nsp < 2)
- continue;
- if(nsp < 3)
- sp[2] = "";
- /*
- * Only report errors; successes will be reported by
- * surrounding scripts.
- */
- if(strcmp(sp[0], "unpack") == 0 && strcmp(sp[1], "ok") != 0)
- fprint(2, "unpack %s\n", sp[1]);
- else if(strcmp(sp[0], "ng") == 0)
- fprint(2, "failed update: %s\n", sp[1]);
- else
- continue;
- r = -1;
- }
+ if(!send){
+ fprint(2, "nothing to send\n");
+ return 0;
}
- return r;
+
+ if(writepack(c->wfd, ours, nupd, theirs, nupd, &h) == -1)
+ return -1;
+ if(!cs.report)
+ return 0;
+
+ if(readphase(c) == -1)
+ return -1;
+ /* We asked for a status report, may as well use it. */
+ while((n = readpkt(c, buf, sizeof(buf))) > 0){
+ buf[n] = 0;
+ if(chattygit)
+ fprint(2, "done sending pack, status %s\n", buf);
+ nsp = getfields(buf, sp, nelem(sp), 1, " \t\n\r");
+ if(nsp < 2)
+ continue;
+ if(nsp < 3)
+ sp[2] = "";
+ /*
+ * Only report errors; successes will be reported by
+ * surrounding scripts.
+ */
+ if(strcmp(sp[0], "unpack") == 0 && strcmp(sp[1], "ok") != 0)
+ fprint(2, "unpack %s\n", sp[1]);
+ else if(strcmp(sp[0], "ng") == 0)
+ fprint(2, "failed update: %s\n", sp[1]);
+ else
+ continue;
+ return -1;
+ }
+ return 0;
}
void