7 char *upstream = "origin";
11 resolveremote(Hash *h, char *ref)
17 if((r = hparse(h, ref)) != -1)
19 /* Slightly special handling: translate remote refs to local ones. */
20 if(strcmp(ref, "HEAD") == 0){
21 snprint(buf, sizeof(buf), ".git/HEAD");
22 }else if(strstr(ref, "refs/heads") == ref){
23 ref += strlen("refs/heads");
24 snprint(buf, sizeof(buf), ".git/refs/remotes/%s/%s", upstream, ref);
25 }else if(strstr(ref, "refs/tags") == ref){
26 ref += strlen("refs/tags");
27 snprint(buf, sizeof(buf), ".git/refs/tags/%s/%s", upstream, ref);
34 if((f = open(s, OREAD)) == -1)
36 if(readn(f, buf, sizeof(buf)) >= 40)
40 if(r == -1 && strstr(buf, "ref:") == buf)
41 return resolveremote(h, buf + strlen("ref:"));
46 rename(char *pack, char *idx, Hash h)
53 snprint(name, sizeof(name), "%H.pack", h);
54 if(access(name, AEXIST) == 0)
55 fprint(2, "warning, pack %s already fetched\n", name);
56 else if(dirwstat(pack, &st) == -1)
58 snprint(name, sizeof(name), "%H.idx", h);
59 if(access(name, AEXIST) == 0)
60 fprint(2, "warning, pack %s already indexed\n", name);
61 else if(dirwstat(idx, &st) == -1)
67 checkhash(int fd, vlong sz, Hash *hcomp)
76 werrstr("undersize packfile");
84 if(sz - n - 20 < sizeof(buf))
86 r = readn(fd, buf, nr);
89 st = sha1((uchar*)buf, nr, nil, st);
92 sha1(nil, 0, hcomp->h, st);
93 if(readn(fd, hexpect.h, sizeof(hexpect.h)) != sizeof(hexpect.h))
94 sysfatal("truncated packfile");
95 if(!hasheq(hcomp, &hexpect)){
96 werrstr("bad hash: %H != %H", *hcomp, hexpect);
103 mkoutpath(char *path)
109 snprint(s, sizeof(s), "%s", path);
110 for(p=strchr(s+1, '/'); p; p=strchr(p+1, '/')){
112 if(access(s, AEXIST) != 0){
113 fd = create(s, OREAD, DMDIR | 0775);
124 branchmatch(char *br, char *pat)
128 if(strstr(pat, "refs/heads") == pat)
129 snprint(name, sizeof(name), "%s", pat);
130 else if(strstr(pat, "heads"))
131 snprint(name, sizeof(name), "refs/%s", pat);
133 snprint(name, sizeof(name), "refs/heads/%s", pat);
134 return strcmp(br, name) == 0;
138 matchcap(char *s, char *cap, int full)
140 if(strncmp(s, cap, strlen(cap)) == 0)
141 if(!full || strlen(s) == strlen(cap))
142 return s + strlen(cap);
147 handlecaps(char *caps)
151 for(p = caps; p != nil; p = n){
155 if((c = matchcap(p, "symref=", 0)) != nil){
156 if((r = strchr(c, ':')) != nil){
158 print("symref %s %s\n", c, r);
165 fail(char *pack, char *idx, char *msg, ...)
171 snprint(buf, sizeof(buf), msg, ap);
176 fprint(2, "%s", buf);
183 char buf[Pktmax], *sp[3];
184 char *packtmp, *idxtmp;
185 Hash h, *have, *want;
186 int nref, refsz, first;
194 have = eamalloc(refsz, sizeof(have[0]));
195 want = eamalloc(refsz, sizeof(want[0]));
197 n = readpkt(c, buf, sizeof(buf));
202 if(strncmp(buf, "ERR ", 4) == 0)
203 sysfatal("%s", buf + 4);
205 if(first && n > strlen(buf))
206 handlecaps(buf + strlen(buf) + 1);
209 getfields(buf, sp, nelem(sp), 1, " \t\n\r");
210 if(strstr(sp[1], "^{}"))
212 if(fetchbranch && !branchmatch(sp[1], fetchbranch))
214 if(refsz == nref + 1){
216 have = erealloc(have, refsz * sizeof(have[0]));
217 want = erealloc(want, refsz * sizeof(want[0]));
219 if(hparse(&want[nref], sp[0]) == -1)
220 sysfatal("invalid hash %s", sp[0]);
221 if (resolveremote(&have[nref], sp[1]) == -1)
222 memset(&have[nref], 0, sizeof(have[nref]));
223 print("remote %s %H local %H\n", sp[1], want[nref], have[nref]);
231 if(writephase(c) == -1)
232 sysfatal("write: %r");
234 for(i = 0; i < nref; i++){
235 if(hasheq(&have[i], &want[i]))
237 if((o = readobject(want[i])) != nil){
241 n = snprint(buf, sizeof(buf), "want %H\n", want[i]);
242 if(writepkt(c, buf, n) == -1)
243 sysfatal("could not send want for %H", want[i]);
247 for(i = 0; i < nref; i++){
248 if(hasheq(&have[i], &Zhash))
250 n = snprint(buf, sizeof(buf), "have %H\n", have[i]);
251 if(writepkt(c, buf, n + 1) == -1)
252 sysfatal("could not send have for %H", have[i]);
257 n = snprint(buf, sizeof(buf), "done\n");
258 if(writepkt(c, buf, n) == -1)
259 sysfatal("write: %r");
262 if(readphase(c) == -1)
263 sysfatal("read: %r");
264 if((n = readpkt(c, buf, sizeof(buf))) == -1)
265 sysfatal("read: %r");
268 if((packtmp = smprint(".git/objects/pack/fetch.%d.pack", getpid())) == nil)
269 sysfatal("smprint: %r");
270 if((idxtmp = smprint(".git/objects/idx/fetch.%d.idx", getpid())) == nil)
271 sysfatal("smprint: %r");
272 if(mkoutpath(packtmp) == -1)
273 sysfatal("could not create %s: %r", packtmp);
274 if((pfd = create(packtmp, ORDWR, 0664)) == -1)
275 sysfatal("could not create %s: %r", packtmp);
277 fprint(2, "fetching...\n");
280 n = readn(c->rfd, buf, sizeof buf);
283 if(n == -1 || write(pfd, buf, n) != n)
284 sysfatal("fetch packfile: %r");
289 if(seek(pfd, 0, 0) == -1)
290 fail(packtmp, idxtmp, "packfile seek: %r");
291 if(checkhash(pfd, packsz, &h) == -1)
292 fail(packtmp, idxtmp, "corrupt packfile: %r");
294 if(indexpack(packtmp, idxtmp, h) == -1)
295 fail(packtmp, idxtmp, "could not index fetched pack: %r");
296 if(rename(packtmp, idxtmp, h) == -1)
297 fail(packtmp, idxtmp, "could not rename indexed pack: %r");
304 fprint(2, "usage: %s [-dl] [-b br] [-u upstream] remote\n", argv0);
305 fprint(2, "\t-b br: only fetch matching branch 'br'\n");
306 fprint(2, "remote: fetch from this repository\n");
311 main(int argc, char **argv)
316 case 'b': fetchbranch=EARGF(usage()); break;
317 case 'u': upstream=EARGF(usage()); break;
318 case 'd': chattygit++; break;
319 case 'l': listonly++; break;
320 default: usage(); break;
327 if(gitconnect(&c, argv[0], "upload") == -1)
328 sysfatal("could not dial %s: %r", argv[0]);
329 if(fetchpack(&c) == -1)
330 sysfatal("fetch failed: %r");