12 fmtpkt(Conn *c, char *fmt, ...)
19 n = vsnprint(pkt, sizeof(pkt), fmt, ap);
20 n = writepkt(c, pkt, n);
36 if(resolveref(&head, "HEAD") != -1)
37 if(fmtpkt(c, "%H HEAD", head) == -1)
40 if((nrefs = listrefs(&refs, &names)) == -1)
41 sysfatal("listrefs: %r");
42 for(i = 0; i < nrefs; i++){
43 if(strncmp(names[i], "heads/", strlen("heads/")) != 0)
45 if(fmtpkt(c, "%H refs/%s\n", refs[i], names[i]) == -1)
52 for(i = 0; i < nrefs; i++)
60 servnegotiate(Conn *c, Hash **head, int *nhead, Hash **tail, int *ntail)
75 if((n = readpkt(c, pkt, sizeof(pkt))) == -1)
79 if(strncmp(pkt, "want ", 5) != 0){
80 werrstr(" protocol garble %s", pkt);
83 if(hparse(&h, &pkt[5]) == -1){
84 werrstr(" garbled want");
87 if((o = readobject(h)) == nil){
88 werrstr("requested nonexistent object");
92 *head = erealloc(*head, (*nhead + 1)*sizeof(Hash));
99 if((n = readpkt(c, pkt, sizeof(pkt))) == -1)
101 if(strncmp(pkt, "done", 4) == 0)
104 if(!acked && fmtpkt(c, "NAK") == -1)
107 if(strncmp(pkt, "have ", 5) != 0){
108 werrstr(" protocol garble %s", pkt);
111 if(hparse(&h, &pkt[5]) == -1){
112 werrstr(" garbled have");
115 if((o = readobject(h)) == nil)
118 if(fmtpkt(c, "ACK %H", h) == -1)
123 *tail = erealloc(*tail, (*ntail + 1)*sizeof(Hash));
127 if(!acked && fmtpkt(c, "NAK\n") == -1)
131 fmtpkt(c, "ERR %r\n");
140 Hash *head, *tail, h;
143 dprint(1, "negotiating pack\n");
144 if(servnegotiate(c, &head, &nhead, &tail, &ntail) == -1)
145 sysfatal("negotiate: %r");
146 dprint(1, "writing pack\n");
147 if(writepack(c->wfd, head, nhead, tail, ntail, &h) == -1)
148 sysfatal("send: %r");
155 if(strncmp(s, "refs/", 5) != 0)
157 for(; *s != '\0'; s++)
158 if(!isalnum(*s) && strchr("/-_.", *s) == nil)
164 recvnegotiate(Conn *c, Hash **cur, Hash **upd, char ***ref, int *nupd)
166 char pkt[Pktmax], *sp[4];
170 if(showrefs(c) == -1)
177 if((n = readpkt(c, pkt, sizeof(pkt))) == -1)
181 if(getfields(pkt, sp, nelem(sp), 1, " \t\n\r") != 3){
182 fmtpkt(c, "ERR protocol garble %s\n", pkt);
185 if(hparse(&old, sp[0]) == -1){
186 fmtpkt(c, "ERR bad old hash %s\n", sp[0]);
189 if(hparse(&new, sp[1]) == -1){
190 fmtpkt(c, "ERR bad new hash %s\n", sp[1]);
193 if(!validref(sp[2])){
194 fmtpkt(c, "ERR invalid ref %s\n", sp[2]);
197 *cur = erealloc(*cur, (*nupd + 1)*sizeof(Hash));
198 *upd = erealloc(*upd, (*nupd + 1)*sizeof(Hash));
199 *ref = erealloc(*ref, (*nupd + 1)*sizeof(Hash));
202 (*ref)[*nupd] = estrdup(sp[2]);
209 for(i = 0; i < *nupd; i++)
216 rename(char *pack, char *idx, Hash h)
218 char name[128], path[196];
223 snprint(name, sizeof(name), "%H.pack", h);
224 snprint(path, sizeof(path), ".git/objects/pack/%s", name);
225 if(access(path, AEXIST) == 0)
226 fprint(2, "warning, pack %s already pushed\n", name);
227 else if(dirwstat(pack, &st) == -1)
229 snprint(name, sizeof(name), "%H.idx", h);
230 snprint(path, sizeof(path), ".git/objects/pack/%s", name);
231 if(access(path, AEXIST) == 0)
232 fprint(2, "warning, pack %s already indexed\n", name);
233 else if(dirwstat(idx, &st) == -1)
239 checkhash(int fd, vlong sz, Hash *hcomp)
248 werrstr("undersize packfile");
254 if(seek(fd, 0, 0) == -1)
255 sysfatal("packfile seek: %r");
258 if(sz - n - 20 < sizeof(buf))
260 r = readn(fd, buf, nr);
262 werrstr("short read");
265 st = sha1((uchar*)buf, nr, nil, st);
268 sha1(nil, 0, hcomp->h, st);
269 if(readn(fd, hexpect.h, sizeof(hexpect.h)) != sizeof(hexpect.h))
270 sysfatal("truncated packfile");
271 if(!hasheq(hcomp, &hexpect)){
272 werrstr("bad hash: %H != %H", *hcomp, hexpect);
284 if(access(dir, AEXIST) == 0)
286 if((f = create(dir, OREAD, DMDIR | 0755)) == -1){
287 rerrstr(buf, sizeof(buf));
288 if(strstr(buf, "exist") == nil)
298 char buf[Pktmax], packtmp[128], idxtmp[128], ebuf[ERRMAX];
302 /* make sure the needed dirs exist */
303 if(mkdir(".git/objects") == -1)
305 if(mkdir(".git/objects/pack") == -1)
307 if(mkdir(".git/refs") == -1)
309 if(mkdir(".git/refs/heads") == -1)
311 snprint(packtmp, sizeof(packtmp), ".git/objects/pack/recv-%d.pack.tmp", getpid());
312 snprint(idxtmp, sizeof(idxtmp), ".git/objects/pack/recv-%d.idx.tmp", getpid());
313 if((pfd = create(packtmp, ORDWR, 0644)) == -1)
317 n = read(c->rfd, buf, sizeof(buf));
321 rerrstr(ebuf, sizeof(ebuf));
322 if(strstr(ebuf, "hungup") == nil)
326 if(write(pfd, buf, n) != n)
330 if(checkhash(pfd, packsz, &h) == -1){
331 dprint(1, "hash mismatch\n");
334 if(indexpack(packtmp, idxtmp, h) == -1){
335 dprint(1, "indexing failed: %r\n");
338 if(rename(packtmp, idxtmp, h) == -1){
339 dprint(1, "rename failed: %r\n");
344 error2: remove(idxtmp);
345 error1: remove(packtmp);
354 for(i = 0; i < 10; i++) {
355 if((fd = create(".git/_lock", ORCLOSE|ORDWR|OTRUNC|OEXCL, 0644))!= -1)
363 updaterefs(Conn *c, Hash *cur, Hash *upd, char **ref, int nupd)
366 int i, newidx, hadref, fd, ret, lockfd;
375 * Date of Magna Carta.
376 * Wrong because it was computed using
377 * the proleptic gregorian calendar.
379 newtm = -23811206400;
380 if((lockfd = lockrepo()) == -1){
381 werrstr("repo locked\n");
384 for(i = 0; i < nupd; i++){
385 if(resolveref(&h, ref[i]) == 0){
387 if(!hasheq(&h, &cur[i])){
388 werrstr("old ref changed: %s", ref[i]);
392 if(snprint(refpath, sizeof(refpath), ".git/%s", ref[i]) == sizeof(refpath)){
393 werrstr("ref path too long: %s", ref[i]);
396 if(hasheq(&upd[i], &Zhash)){
400 if((o = readobject(upd[i])) == nil){
401 werrstr("update to nonexistent hash %H", upd[i]);
404 if(o->type != GCommit){
405 werrstr("not commit: %H", upd[i]);
408 if(o->commit->mtime > newtm){
409 newtm = o->commit->mtime;
413 if((fd = create(refpath, OWRITE|OTRUNC, 0644)) == -1){
414 werrstr("open ref: %r");
417 if(fprint(fd, "%H", upd[i]) == -1){
418 werrstr("upate ref: %r");
426 * If there are no valid refs, and HEAD is invalid, then
427 * pick the ref with the newest commits as the default
430 * Several people have been caught out by pushing to
431 * a repo where HEAD named differently from what got
432 * pushed, and this is going to be more of a footgun
433 * when 'master', 'main', and 'front' are all in active
434 * use. This should make us pick a useful default in
435 * those cases, instead of silently failing.
437 if(resolveref(&h, "HEAD") == -1 && hadref == 0 && newidx != -1){
438 if((fd = create(".git/HEAD", OWRITE|OTRUNC, 0644)) == -1){
439 werrstr("open HEAD: %r");
442 if(fprint(fd, "ref: %s", ref[0]) == -1){
443 werrstr("write HEAD ref: %r");
462 if(recvnegotiate(c, &cur, &upd, &ref, &nupd) == -1)
463 sysfatal("negotiate refs: %r");
464 if(nupd != 0 && updatepack(c) == -1)
465 sysfatal("update pack: %r");
466 if(nupd != 0 && updaterefs(c, cur, upd, ref, nupd) == -1)
467 sysfatal("update refs: %r");
472 parsecmd(char *buf, char *cmd, int ncmd)
477 for(p = buf, i = 0; *p && i < ncmd - 1; i++, p++){
478 if(*p == ' ' || *p == '\t'){
484 while(*p == ' ' || *p == '\t')
492 fprint(2, "usage: %s [-dw] [-r rel]\n", argv0);
497 main(int argc, char **argv)
499 char *repo, cmd[32], buf[512];
507 pathpfx = EARGF(usage());
509 sysfatal("path prefix must begin with '/'");
521 if(rfork(RFNAMEG) == -1)
522 sysfatal("rfork: %r");
524 if(bind(pathpfx, "/", MREPL) == -1)
525 sysfatal("bind: %r");
527 if(rfork(RFNOMNT) == -1)
528 sysfatal("rfork: %r");
531 if(readpkt(&c, buf, sizeof(buf)) == -1)
532 sysfatal("readpkt: %r");
533 repo = parsecmd(buf, cmd, sizeof(cmd));
535 if(strncmp(repo, "../", 3) == 0)
536 sysfatal("invalid path %s\n", repo);
537 if(bind(repo, "/", MREPL) == -1){
538 fmtpkt(&c, "ERR no repo %r\n");
539 sysfatal("enter %s: %r", repo);
542 sysfatal("chdir: %r");
543 if(access(".git", AREAD) == -1)
544 sysfatal("no git repository");
545 if(strcmp(cmd, "git-receive-pack") == 0 && allowwrite)
547 else if(strcmp(cmd, "git-upload-pack") == 0)
550 sysfatal("unsupported command '%s'", cmd);