ad789829c1c33e00cbcc9e1e1564e645755d49ab
[git.git] / http-push.c
1 #include "cache.h"
2 #include "commit.h"
3 #include "pack.h"
4 #include "fetch.h"
5 #include "tag.h"
6 #include "blob.h"
7 #include "http.h"
8
9 #include <expat.h>
10
11 static const char http_push_usage[] =
12 "git-http-push [--complete] [--force] [--verbose] <url> <ref> [<ref>...]\n";
13
14 #ifndef XML_STATUS_OK
15 enum XML_Status {
16   XML_STATUS_OK = 1,
17   XML_STATUS_ERROR = 0
18 };
19 #define XML_STATUS_OK    1
20 #define XML_STATUS_ERROR 0
21 #endif
22
23 #define RANGE_HEADER_SIZE 30
24
25 /* DAV methods */
26 #define DAV_LOCK "LOCK"
27 #define DAV_MKCOL "MKCOL"
28 #define DAV_MOVE "MOVE"
29 #define DAV_PROPFIND "PROPFIND"
30 #define DAV_PUT "PUT"
31 #define DAV_UNLOCK "UNLOCK"
32
33 /* DAV lock flags */
34 #define DAV_PROP_LOCKWR (1u << 0)
35 #define DAV_PROP_LOCKEX (1u << 1)
36 #define DAV_LOCK_OK (1u << 2)
37
38 /* DAV XML properties */
39 #define DAV_CTX_LOCKENTRY ".multistatus.response.propstat.prop.supportedlock.lockentry"
40 #define DAV_CTX_LOCKTYPE_WRITE ".multistatus.response.propstat.prop.supportedlock.lockentry.locktype.write"
41 #define DAV_CTX_LOCKTYPE_EXCLUSIVE ".multistatus.response.propstat.prop.supportedlock.lockentry.lockscope.exclusive"
42 #define DAV_ACTIVELOCK_OWNER ".prop.lockdiscovery.activelock.owner.href"
43 #define DAV_ACTIVELOCK_TIMEOUT ".prop.lockdiscovery.activelock.timeout"
44 #define DAV_ACTIVELOCK_TOKEN ".prop.lockdiscovery.activelock.locktoken.href"
45
46 /* DAV request body templates */
47 #define PROPFIND_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:prop xmlns:R=\"%s\">\n<D:supportedlock/>\n</D:prop>\n</D:propfind>"
48 #define LOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:lockinfo xmlns:D=\"DAV:\">\n<D:lockscope><D:exclusive/></D:lockscope>\n<D:locktype><D:write/></D:locktype>\n<D:owner>\n<D:href>mailto:%s</D:href>\n</D:owner>\n</D:lockinfo>"
49
50 #define LOCK_TIME 600
51 #define LOCK_REFRESH 30
52
53 static int pushing = 0;
54 static int aborted = 0;
55 static char remote_dir_exists[256];
56
57 static struct curl_slist *no_pragma_header;
58 static struct curl_slist *default_headers;
59
60 static int push_verbosely = 0;
61 static int push_all = 0;
62 static int force_all = 0;
63
64 struct repo
65 {
66         char *url;
67         struct packed_git *packs;
68 };
69
70 static struct repo *remote = NULL;
71
72 enum transfer_state {
73         NEED_CHECK,
74         RUN_HEAD,
75         NEED_PUSH,
76         RUN_MKCOL,
77         RUN_PUT,
78         RUN_MOVE,
79         ABORTED,
80         COMPLETE,
81 };
82
83 struct transfer_request
84 {
85         unsigned char sha1[20];
86         char *url;
87         char *dest;
88         struct active_lock *lock;
89         struct curl_slist *headers;
90         struct buffer buffer;
91         char filename[PATH_MAX];
92         char tmpfile[PATH_MAX];
93         enum transfer_state state;
94         CURLcode curl_result;
95         char errorstr[CURL_ERROR_SIZE];
96         long http_code;
97         unsigned char real_sha1[20];
98         SHA_CTX c;
99         z_stream stream;
100         int zret;
101         int rename;
102         struct active_request_slot *slot;
103         struct transfer_request *next;
104 };
105
106 static struct transfer_request *request_queue_head = NULL;
107
108 struct xml_ctx
109 {
110         char *name;
111         int len;
112         char *cdata;
113         void (*userFunc)(struct xml_ctx *ctx, int tag_closed);
114         void *userData;
115 };
116
117 struct active_lock
118 {
119         char *url;
120         char *owner;
121         char *token;
122         time_t start_time;
123         long timeout;
124         int refreshing;
125 };
126
127 static void finish_request(struct transfer_request *request);
128
129 static void process_response(void *callback_data)
130 {
131         struct transfer_request *request =
132                 (struct transfer_request *)callback_data;
133
134         finish_request(request);
135 }
136
137 static void start_check(struct transfer_request *request)
138 {
139         char *hex = sha1_to_hex(request->sha1);
140         struct active_request_slot *slot;
141         char *posn;
142
143         request->url = xmalloc(strlen(remote->url) + 55);
144         strcpy(request->url, remote->url);
145         posn = request->url + strlen(remote->url);
146         strcpy(posn, "objects/");
147         posn += 8;
148         memcpy(posn, hex, 2);
149         posn += 2;
150         *(posn++) = '/';
151         strcpy(posn, hex + 2);
152
153         slot = get_active_slot();
154         slot->callback_func = process_response;
155         slot->callback_data = request;
156         curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
157         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
158         curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
159
160         if (start_active_slot(slot)) {
161                 request->slot = slot;
162                 request->state = RUN_HEAD;
163         } else {
164                 request->state = ABORTED;
165                 free(request->url);
166                 request->url = NULL;
167         }
168 }
169
170 static void start_mkcol(struct transfer_request *request)
171 {
172         char *hex = sha1_to_hex(request->sha1);
173         struct active_request_slot *slot;
174         char *posn;
175
176         request->url = xmalloc(strlen(remote->url) + 13);
177         strcpy(request->url, remote->url);
178         posn = request->url + strlen(remote->url);
179         strcpy(posn, "objects/");
180         posn += 8;
181         memcpy(posn, hex, 2);
182         posn += 2;
183         strcpy(posn, "/");
184
185         slot = get_active_slot();
186         slot->callback_func = process_response;
187         slot->callback_data = request;
188         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); /* undo PUT setup */
189         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
190         curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
191         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
192         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
193
194         if (start_active_slot(slot)) {
195                 request->slot = slot;
196                 request->state = RUN_MKCOL;
197         } else {
198                 request->state = ABORTED;
199                 free(request->url);
200                 request->url = NULL;
201         }
202 }
203
204 static void start_put(struct transfer_request *request)
205 {
206         char *hex = sha1_to_hex(request->sha1);
207         struct active_request_slot *slot;
208         char *posn;
209         char type[20];
210         char hdr[50];
211         void *unpacked;
212         unsigned long len;
213         int hdrlen;
214         ssize_t size;
215         z_stream stream;
216
217         unpacked = read_sha1_file(request->sha1, type, &len);
218         hdrlen = sprintf(hdr, "%s %lu", type, len) + 1;
219
220         /* Set it up */
221         memset(&stream, 0, sizeof(stream));
222         deflateInit(&stream, Z_BEST_COMPRESSION);
223         size = deflateBound(&stream, len + hdrlen);
224         request->buffer.buffer = xmalloc(size);
225
226         /* Compress it */
227         stream.next_out = request->buffer.buffer;
228         stream.avail_out = size;
229
230         /* First header.. */
231         stream.next_in = (void *)hdr;
232         stream.avail_in = hdrlen;
233         while (deflate(&stream, 0) == Z_OK)
234                 /* nothing */;
235
236         /* Then the data itself.. */
237         stream.next_in = unpacked;
238         stream.avail_in = len;
239         while (deflate(&stream, Z_FINISH) == Z_OK)
240                 /* nothing */;
241         deflateEnd(&stream);
242         free(unpacked);
243
244         request->buffer.size = stream.total_out;
245         request->buffer.posn = 0;
246
247         request->url = xmalloc(strlen(remote->url) + 
248                                strlen(request->lock->token) + 51);
249         strcpy(request->url, remote->url);
250         posn = request->url + strlen(remote->url);
251         strcpy(posn, "objects/");
252         posn += 8;
253         memcpy(posn, hex, 2);
254         posn += 2;
255         *(posn++) = '/';
256         strcpy(posn, hex + 2);
257         request->dest = xmalloc(strlen(request->url) + 14);
258         sprintf(request->dest, "Destination: %s", request->url);
259         posn += 38;
260         *(posn++) = '.';
261         strcpy(posn, request->lock->token);
262
263         slot = get_active_slot();
264         slot->callback_func = process_response;
265         slot->callback_data = request;
266         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &request->buffer);
267         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, request->buffer.size);
268         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
269         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
270         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);
271         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
272         curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
273         curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
274         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
275
276         if (start_active_slot(slot)) {
277                 request->slot = slot;
278                 request->state = RUN_PUT;
279         } else {
280                 request->state = ABORTED;
281                 free(request->url);
282                 request->url = NULL;
283         }
284 }
285
286 static void start_move(struct transfer_request *request)
287 {
288         struct active_request_slot *slot;
289         struct curl_slist *dav_headers = NULL;
290
291         slot = get_active_slot();
292         slot->callback_func = process_response;
293         slot->callback_data = request;
294         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); /* undo PUT setup */
295         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MOVE);
296         dav_headers = curl_slist_append(dav_headers, request->dest);
297         dav_headers = curl_slist_append(dav_headers, "Overwrite: T");
298         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
299         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
300         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
301
302         if (start_active_slot(slot)) {
303                 request->slot = slot;
304                 request->state = RUN_MOVE;
305         } else {
306                 request->state = ABORTED;
307                 free(request->url);
308                 request->url = NULL;
309         }
310 }
311
312 static int refresh_lock(struct active_lock *lock)
313 {
314         struct active_request_slot *slot;
315         char *if_header;
316         char timeout_header[25];
317         struct curl_slist *dav_headers = NULL;
318         int rc = 0;
319
320         lock->refreshing = 1;
321
322         if_header = xmalloc(strlen(lock->token) + 25);
323         sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token);
324         sprintf(timeout_header, "Timeout: Second-%ld", lock->timeout);
325         dav_headers = curl_slist_append(dav_headers, if_header);
326         dav_headers = curl_slist_append(dav_headers, timeout_header);
327
328         slot = get_active_slot();
329         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
330         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
331         curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
332         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_LOCK);
333         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
334
335         if (start_active_slot(slot)) {
336                 run_active_slot(slot);
337                 if (slot->curl_result != CURLE_OK) {
338                         fprintf(stderr, "Got HTTP error %ld\n", slot->http_code);
339                 } else {
340                         lock->start_time = time(NULL);
341                         rc = 1;
342                 }
343         }
344
345         lock->refreshing = 0;
346         curl_slist_free_all(dav_headers);
347         free(if_header);
348
349         return rc;
350 }
351
352 static void finish_request(struct transfer_request *request)
353 {
354         time_t current_time = time(NULL);
355         int time_remaining;
356
357         request->curl_result =  request->slot->curl_result;
358         request->http_code = request->slot->http_code;
359         request->slot = NULL;
360
361         /* Refresh the lock if it is close to timing out */
362         time_remaining = request->lock->start_time + request->lock->timeout
363                 - current_time;
364         if (time_remaining < LOCK_REFRESH && !request->lock->refreshing) {
365                 if (!refresh_lock(request->lock)) {
366                         fprintf(stderr, "Unable to refresh remote lock\n");
367                         aborted = 1;
368                 }
369         }
370
371         if (request->headers != NULL)
372                 curl_slist_free_all(request->headers);
373
374         /* URL is reused for MOVE after PUT */
375         if (request->state != RUN_PUT) {
376                 free(request->url);
377                 request->url = NULL;
378         }               
379
380         if (request->state == RUN_HEAD) {
381                 if (request->http_code == 404) {
382                         request->state = NEED_PUSH;
383                 } else if (request->curl_result == CURLE_OK) {
384                         remote_dir_exists[request->sha1[0]] = 1;
385                         request->state = COMPLETE;
386                 } else {
387                         fprintf(stderr, "HEAD %s failed, aborting (%d/%ld)\n",
388                                 sha1_to_hex(request->sha1),
389                                 request->curl_result, request->http_code);
390                         request->state = ABORTED;
391                         aborted = 1;
392                 }
393         } else if (request->state == RUN_MKCOL) {
394                 if (request->curl_result == CURLE_OK ||
395                     request->http_code == 405) {
396                         remote_dir_exists[request->sha1[0]] = 1;
397                         start_put(request);
398                 } else {
399                         fprintf(stderr, "MKCOL %s failed, aborting (%d/%ld)\n",
400                                 sha1_to_hex(request->sha1),
401                                 request->curl_result, request->http_code);
402                         request->state = ABORTED;
403                         aborted = 1;
404                 }
405         } else if (request->state == RUN_PUT) {
406                 if (request->curl_result == CURLE_OK) {
407                         start_move(request);
408                 } else {
409                         fprintf(stderr, "PUT %s failed, aborting (%d/%ld)\n",
410                                 sha1_to_hex(request->sha1),
411                                 request->curl_result, request->http_code);
412                         request->state = ABORTED;
413                         aborted = 1;
414                 }
415         } else if (request->state == RUN_MOVE) {
416                 if (request->curl_result == CURLE_OK) {
417                         if (push_verbosely)
418                                 fprintf(stderr,
419                                         "sent %s\n",
420                                         sha1_to_hex(request->sha1));
421                         request->state = COMPLETE;
422                 } else {
423                         fprintf(stderr, "MOVE %s failed, aborting (%d/%ld)\n",
424                                 sha1_to_hex(request->sha1),
425                                 request->curl_result, request->http_code);
426                         request->state = ABORTED;
427                         aborted = 1;
428                 }
429         }
430 }
431
432 static void release_request(struct transfer_request *request)
433 {
434         struct transfer_request *entry = request_queue_head;
435
436         if (request == request_queue_head) {
437                 request_queue_head = request->next;
438         } else {
439                 while (entry->next != NULL && entry->next != request)
440                         entry = entry->next;
441                 if (entry->next == request)
442                         entry->next = entry->next->next;
443         }
444
445         if (request->url != NULL)
446                 free(request->url);
447         free(request);
448 }
449
450 void fill_active_slots(void)
451 {
452         struct transfer_request *request = request_queue_head;
453         struct active_request_slot *slot = active_queue_head;
454         int num_transfers;
455
456         if (aborted)
457                 return;
458
459         while (active_requests < max_requests && request != NULL) {
460                 if (!pushing && request->state == NEED_CHECK) {
461                         start_check(request);
462                         curl_multi_perform(curlm, &num_transfers);
463                 } else if (pushing && request->state == NEED_PUSH) {
464                         if (remote_dir_exists[request->sha1[0]])
465                                 start_put(request);
466                         else
467                                 start_mkcol(request);
468                         curl_multi_perform(curlm, &num_transfers);
469                 }
470                 request = request->next;
471         }
472
473         while (slot != NULL) {
474                 if (!slot->in_use && slot->curl != NULL) {
475                         curl_easy_cleanup(slot->curl);
476                         slot->curl = NULL;
477                 }
478                 slot = slot->next;
479         }                               
480 }
481
482 static void add_request(unsigned char *sha1, struct active_lock *lock)
483 {
484         struct transfer_request *request = request_queue_head;
485         struct packed_git *target;
486         
487         while (request != NULL && memcmp(request->sha1, sha1, 20))
488                 request = request->next;
489         if (request != NULL)
490                 return;
491
492         target = find_sha1_pack(sha1, remote->packs);
493         if (target)
494                 return;
495
496         request = xmalloc(sizeof(*request));
497         memcpy(request->sha1, sha1, 20);
498         request->url = NULL;
499         request->lock = lock;
500         request->headers = NULL;
501         request->state = NEED_CHECK;
502         request->next = request_queue_head;
503         request_queue_head = request;
504
505         fill_active_slots();
506         step_active_slots();
507 }
508
509 static int fetch_index(unsigned char *sha1)
510 {
511         char *hex = sha1_to_hex(sha1);
512         char *filename;
513         char *url;
514         char tmpfile[PATH_MAX];
515         long prev_posn = 0;
516         char range[RANGE_HEADER_SIZE];
517         struct curl_slist *range_header = NULL;
518
519         FILE *indexfile;
520         struct active_request_slot *slot;
521
522         /* Don't use the index if the pack isn't there */
523         url = xmalloc(strlen(remote->url) + 65);
524         sprintf(url, "%s/objects/pack/pack-%s.pack", remote->url, hex);
525         slot = get_active_slot();
526         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
527         curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
528         if (start_active_slot(slot)) {
529                 run_active_slot(slot);
530                 if (slot->curl_result != CURLE_OK) {
531                         free(url);
532                         return error("Unable to verify pack %s is available",
533                                      hex);
534                 }
535         } else {
536                 return error("Unable to start request");
537         }
538
539         if (has_pack_index(sha1))
540                 return 0;
541
542         if (push_verbosely)
543                 fprintf(stderr, "Getting index for pack %s\n", hex);
544         
545         sprintf(url, "%s/objects/pack/pack-%s.idx", remote->url, hex);
546         
547         filename = sha1_pack_index_name(sha1);
548         snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
549         indexfile = fopen(tmpfile, "a");
550         if (!indexfile)
551                 return error("Unable to open local file %s for pack index",
552                              filename);
553
554         slot = get_active_slot();
555         curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
556         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
557         curl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);
558         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
559         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
560         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
561         slot->local = indexfile;
562
563         /* If there is data present from a previous transfer attempt,
564            resume where it left off */
565         prev_posn = ftell(indexfile);
566         if (prev_posn>0) {
567                 if (push_verbosely)
568                         fprintf(stderr,
569                                 "Resuming fetch of index for pack %s at byte %ld\n",
570                                 hex, prev_posn);
571                 sprintf(range, "Range: bytes=%ld-", prev_posn);
572                 range_header = curl_slist_append(range_header, range);
573                 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);
574         }
575
576         if (start_active_slot(slot)) {
577                 run_active_slot(slot);
578                 if (slot->curl_result != CURLE_OK) {
579                         free(url);
580                         fclose(indexfile);
581                         return error("Unable to get pack index %s\n%s", url,
582                                      curl_errorstr);
583                 }
584         } else {
585                 free(url);
586                 fclose(indexfile);
587                 return error("Unable to start request");
588         }
589
590         free(url);
591         fclose(indexfile);
592
593         return move_temp_to_file(tmpfile, filename);
594 }
595
596 static int setup_index(unsigned char *sha1)
597 {
598         struct packed_git *new_pack;
599
600         if (fetch_index(sha1))
601                 return -1;
602
603         new_pack = parse_pack_index(sha1);
604         new_pack->next = remote->packs;
605         remote->packs = new_pack;
606         return 0;
607 }
608
609 static int fetch_indices(void)
610 {
611         unsigned char sha1[20];
612         char *url;
613         struct buffer buffer;
614         char *data;
615         int i = 0;
616
617         struct active_request_slot *slot;
618
619         data = xmalloc(4096);
620         memset(data, 0, 4096);
621         buffer.size = 4096;
622         buffer.posn = 0;
623         buffer.buffer = data;
624
625         if (push_verbosely)
626                 fprintf(stderr, "Getting pack list\n");
627         
628         url = xmalloc(strlen(remote->url) + 21);
629         sprintf(url, "%s/objects/info/packs", remote->url);
630
631         slot = get_active_slot();
632         curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
633         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
634         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
635         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
636         if (start_active_slot(slot)) {
637                 run_active_slot(slot);
638                 if (slot->curl_result != CURLE_OK) {
639                         free(buffer.buffer);
640                         free(url);
641                         if (slot->http_code == 404)
642                                 return 0;
643                         else
644                                 return error("%s", curl_errorstr);
645                 }
646         } else {
647                 free(buffer.buffer);
648                 free(url);
649                 return error("Unable to start request");
650         }
651         free(url);
652
653         data = buffer.buffer;
654         while (i < buffer.posn) {
655                 switch (data[i]) {
656                 case 'P':
657                         i++;
658                         if (i + 52 < buffer.posn &&
659                             !strncmp(data + i, " pack-", 6) &&
660                             !strncmp(data + i + 46, ".pack\n", 6)) {
661                                 get_sha1_hex(data + i + 6, sha1);
662                                 setup_index(sha1);
663                                 i += 51;
664                                 break;
665                         }
666                 default:
667                         while (data[i] != '\n')
668                                 i++;
669                 }
670                 i++;
671         }
672
673         free(buffer.buffer);
674         return 0;
675 }
676
677 static inline int needs_quote(int ch)
678 {
679         switch (ch) {
680         case '/': case '-': case '.':
681         case 'A'...'Z': case 'a'...'z': case '0'...'9':
682                 return 0;
683         default:
684                 return 1;
685         }
686 }
687
688 static inline int hex(int v)
689 {
690         if (v < 10) return '0' + v;
691         else return 'A' + v - 10;
692 }
693
694 static char *quote_ref_url(const char *base, const char *ref)
695 {
696         const char *cp;
697         char *dp, *qref;
698         int len, baselen, ch;
699
700         baselen = strlen(base);
701         len = baselen + 12; /* "refs/heads/" + NUL */
702         for (cp = ref; (ch = *cp) != 0; cp++, len++)
703                 if (needs_quote(ch))
704                         len += 2; /* extra two hex plus replacement % */
705         qref = xmalloc(len);
706         memcpy(qref, base, baselen);
707         memcpy(qref + baselen, "refs/heads/", 11);
708         for (cp = ref, dp = qref + baselen + 11; (ch = *cp) != 0; cp++) {
709                 if (needs_quote(ch)) {
710                         *dp++ = '%';
711                         *dp++ = hex((ch >> 4) & 0xF);
712                         *dp++ = hex(ch & 0xF);
713                 }
714                 else
715                         *dp++ = ch;
716         }
717         *dp = 0;
718
719         return qref;
720 }
721
722 int fetch_ref(char *ref, unsigned char *sha1)
723 {
724         char *url;
725         char hex[42];
726         struct buffer buffer;
727         char *base = remote->url;
728         struct active_request_slot *slot;
729         buffer.size = 41;
730         buffer.posn = 0;
731         buffer.buffer = hex;
732         hex[41] = '\0';
733         
734         url = quote_ref_url(base, ref);
735         slot = get_active_slot();
736         curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
737         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
738         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
739         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
740         if (start_active_slot(slot)) {
741                 run_active_slot(slot);
742                 if (slot->curl_result != CURLE_OK)
743                         return error("Couldn't get %s for %s\n%s",
744                                      url, ref, curl_errorstr);
745         } else {
746                 return error("Unable to start request");
747         }
748
749         hex[40] = '\0';
750         get_sha1_hex(hex, sha1);
751         return 0;
752 }
753
754 static void handle_lockprop_ctx(struct xml_ctx *ctx, int tag_closed)
755 {
756         int *lock_flags = (int *)ctx->userData;
757
758         if (tag_closed) {
759                 if (!strcmp(ctx->name, DAV_CTX_LOCKENTRY)) {
760                         if ((*lock_flags & DAV_PROP_LOCKEX) &&
761                             (*lock_flags & DAV_PROP_LOCKWR)) {
762                                 *lock_flags |= DAV_LOCK_OK;
763                         }
764                         *lock_flags &= DAV_LOCK_OK;
765                 } else if (!strcmp(ctx->name, DAV_CTX_LOCKTYPE_WRITE)) {
766                         *lock_flags |= DAV_PROP_LOCKWR;
767                 } else if (!strcmp(ctx->name, DAV_CTX_LOCKTYPE_EXCLUSIVE)) {
768                         *lock_flags |= DAV_PROP_LOCKEX;
769                 }
770         }
771 }
772
773 static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed)
774 {
775         struct active_lock *lock = (struct active_lock *)ctx->userData;
776
777         if (tag_closed && ctx->cdata) {
778                 if (!strcmp(ctx->name, DAV_ACTIVELOCK_OWNER)) {
779                         lock->owner = xmalloc(strlen(ctx->cdata) + 1);
780                         strcpy(lock->owner, ctx->cdata);
781                 } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
782                         if (!strncmp(ctx->cdata, "Second-", 7))
783                                 lock->timeout =
784                                         strtol(ctx->cdata + 7, NULL, 10);
785                 } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
786                         if (!strncmp(ctx->cdata, "opaquelocktoken:", 16)) {
787                                 lock->token = xmalloc(strlen(ctx->cdata) - 15);
788                                 strcpy(lock->token, ctx->cdata + 16);
789                         }
790                 }
791         }
792 }
793
794 static void
795 xml_start_tag(void *userData, const char *name, const char **atts)
796 {
797         struct xml_ctx *ctx = (struct xml_ctx *)userData;
798         const char *c = index(name, ':');
799         int new_len;
800
801         if (c == NULL)
802                 c = name;
803         else
804                 c++;
805
806         new_len = strlen(ctx->name) + strlen(c) + 2;
807
808         if (new_len > ctx->len) {
809                 ctx->name = xrealloc(ctx->name, new_len);
810                 ctx->len = new_len;
811         }
812         strcat(ctx->name, ".");
813         strcat(ctx->name, c);
814
815         if (ctx->cdata) {
816                 free(ctx->cdata);
817                 ctx->cdata = NULL;
818         }
819
820         ctx->userFunc(ctx, 0);
821 }
822
823 static void
824 xml_end_tag(void *userData, const char *name)
825 {
826         struct xml_ctx *ctx = (struct xml_ctx *)userData;
827         const char *c = index(name, ':');
828         char *ep;
829
830         ctx->userFunc(ctx, 1);
831
832         if (c == NULL)
833                 c = name;
834         else
835                 c++;
836
837         ep = ctx->name + strlen(ctx->name) - strlen(c) - 1;
838         *ep = 0;
839 }
840
841 static void
842 xml_cdata(void *userData, const XML_Char *s, int len)
843 {
844         struct xml_ctx *ctx = (struct xml_ctx *)userData;
845         if (ctx->cdata)
846                 free(ctx->cdata);
847         ctx->cdata = xcalloc(len+1, 1);
848         strncpy(ctx->cdata, s, len);
849 }
850
851 static struct active_lock *lock_remote(char *file, long timeout)
852 {
853         struct active_request_slot *slot;
854         struct buffer out_buffer;
855         struct buffer in_buffer;
856         char *out_data;
857         char *in_data;
858         char *url;
859         char *ep;
860         char timeout_header[25];
861         struct active_lock *new_lock = NULL;
862         XML_Parser parser = XML_ParserCreate(NULL);
863         enum XML_Status result;
864         struct curl_slist *dav_headers = NULL;
865         struct xml_ctx ctx;
866
867         url = xmalloc(strlen(remote->url) + strlen(file) + 1);
868         sprintf(url, "%s%s", remote->url, file);
869
870         /* Make sure leading directories exist for the remote ref */
871         ep = strchr(url + strlen(remote->url) + 11, '/');
872         while (ep) {
873                 *ep = 0;
874                 slot = get_active_slot();
875                 curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
876                 curl_easy_setopt(slot->curl, CURLOPT_URL, url);
877                 curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
878                 curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
879                 if (start_active_slot(slot)) {
880                         run_active_slot(slot);
881                         if (slot->curl_result != CURLE_OK &&
882                             slot->http_code != 405) {
883                                 fprintf(stderr,
884                                         "Unable to create branch path %s\n",
885                                         url);
886                                 free(url);
887                                 return NULL;
888                         }
889                 } else {
890                         fprintf(stderr, "Unable to start request\n");
891                         free(url);
892                         return NULL;
893                 }
894                 *ep = '/';
895                 ep = strchr(ep + 1, '/');
896         }
897
898         out_buffer.size = strlen(LOCK_REQUEST) + strlen(git_default_email) - 2;
899         out_data = xmalloc(out_buffer.size + 1);
900         snprintf(out_data, out_buffer.size + 1, LOCK_REQUEST, git_default_email);
901         out_buffer.posn = 0;
902         out_buffer.buffer = out_data;
903
904         in_buffer.size = 4096;
905         in_data = xmalloc(in_buffer.size);
906         in_buffer.posn = 0;
907         in_buffer.buffer = in_data;
908
909         sprintf(timeout_header, "Timeout: Second-%ld", timeout);
910         dav_headers = curl_slist_append(dav_headers, timeout_header);
911         dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
912
913         slot = get_active_slot();
914         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
915         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
916         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
917         curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
918         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
919         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
920         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
921         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_LOCK);
922         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
923
924         new_lock = xcalloc(1, sizeof(*new_lock));
925         new_lock->owner = NULL;
926         new_lock->token = NULL;
927         new_lock->timeout = -1;
928         new_lock->refreshing = 0;
929
930         if (start_active_slot(slot)) {
931                 run_active_slot(slot);
932                 if (slot->curl_result == CURLE_OK) {
933                         ctx.name = xcalloc(10, 1);
934                         ctx.len = 0;
935                         ctx.cdata = NULL;
936                         ctx.userFunc = handle_new_lock_ctx;
937                         ctx.userData = new_lock;
938                         XML_SetUserData(parser, &ctx);
939                         XML_SetElementHandler(parser, xml_start_tag,
940                                               xml_end_tag);
941                         XML_SetCharacterDataHandler(parser, xml_cdata);
942                         result = XML_Parse(parser, in_buffer.buffer,
943                                            in_buffer.posn, 1);
944                         free(ctx.name);
945                         if (result != XML_STATUS_OK) {
946                                 fprintf(stderr, "XML error: %s\n",
947                                         XML_ErrorString(
948                                                 XML_GetErrorCode(parser)));
949                                 new_lock->timeout = -1;
950                         }
951                 }
952         } else {
953                 fprintf(stderr, "Unable to start request\n");
954         }
955
956         curl_slist_free_all(dav_headers);
957         free(out_data);
958         free(in_data);
959
960         if (new_lock->token == NULL || new_lock->timeout <= 0) {
961                 if (new_lock->token != NULL)
962                         free(new_lock->token);
963                 if (new_lock->owner != NULL)
964                         free(new_lock->owner);
965                 free(url);
966                 free(new_lock);
967                 new_lock = NULL;
968         } else {
969                 new_lock->url = url;
970                 new_lock->start_time = time(NULL);
971         }
972
973         return new_lock;
974 }
975
976 static int unlock_remote(struct active_lock *lock)
977 {
978         struct active_request_slot *slot;
979         char *lock_token_header;
980         struct curl_slist *dav_headers = NULL;
981         int rc = 0;
982
983         lock_token_header = xmalloc(strlen(lock->token) + 31);
984         sprintf(lock_token_header, "Lock-Token: <opaquelocktoken:%s>",
985                 lock->token);
986         dav_headers = curl_slist_append(dav_headers, lock_token_header);
987
988         slot = get_active_slot();
989         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
990         curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
991         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_UNLOCK);
992         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
993
994         if (start_active_slot(slot)) {
995                 run_active_slot(slot);
996                 if (slot->curl_result == CURLE_OK)
997                         rc = 1;
998                 else
999                         fprintf(stderr, "Got HTTP error %ld\n",
1000                                 slot->http_code);
1001         } else {
1002                 fprintf(stderr, "Unable to start request\n");
1003         }
1004
1005         curl_slist_free_all(dav_headers);
1006         free(lock_token_header);
1007
1008         if (lock->owner != NULL)
1009                 free(lock->owner);
1010         free(lock->url);
1011 /* Freeing the token causes a segfault...
1012         free(lock->token);
1013 */
1014         free(lock);
1015
1016         return rc;
1017 }
1018
1019 static int locking_available(void)
1020 {
1021         struct active_request_slot *slot;
1022         struct buffer in_buffer;
1023         struct buffer out_buffer;
1024         char *in_data;
1025         char *out_data;
1026         XML_Parser parser = XML_ParserCreate(NULL);
1027         enum XML_Status result;
1028         struct curl_slist *dav_headers = NULL;
1029         struct xml_ctx ctx;
1030         int lock_flags = 0;
1031
1032         out_buffer.size = strlen(PROPFIND_REQUEST) + strlen(remote->url) - 2;
1033         out_data = xmalloc(out_buffer.size + 1);
1034         snprintf(out_data, out_buffer.size + 1, PROPFIND_REQUEST, remote->url);
1035         out_buffer.posn = 0;
1036         out_buffer.buffer = out_data;
1037
1038         in_buffer.size = 4096;
1039         in_data = xmalloc(in_buffer.size);
1040         in_buffer.posn = 0;
1041         in_buffer.buffer = in_data;
1042
1043         dav_headers = curl_slist_append(dav_headers, "Depth: 0");
1044         dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
1045         
1046         slot = get_active_slot();
1047         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
1048         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
1049         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1050         curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
1051         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
1052         curl_easy_setopt(slot->curl, CURLOPT_URL, remote->url);
1053         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1054         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PROPFIND);
1055         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1056
1057         if (start_active_slot(slot)) {
1058                 run_active_slot(slot);
1059                 if (slot->curl_result == CURLE_OK) {
1060                         ctx.name = xcalloc(10, 1);
1061                         ctx.len = 0;
1062                         ctx.cdata = NULL;
1063                         ctx.userFunc = handle_lockprop_ctx;
1064                         ctx.userData = &lock_flags;
1065                         XML_SetUserData(parser, &ctx);
1066                         XML_SetElementHandler(parser, xml_start_tag,
1067                                               xml_end_tag);
1068                         result = XML_Parse(parser, in_buffer.buffer,
1069                                            in_buffer.posn, 1);
1070                         free(ctx.name);
1071
1072                         if (result != XML_STATUS_OK) {
1073                                 fprintf(stderr, "XML error: %s\n",
1074                                         XML_ErrorString(
1075                                                 XML_GetErrorCode(parser)));
1076                                 lock_flags = 0;
1077                         }
1078                 }
1079         } else {
1080                 fprintf(stderr, "Unable to start request\n");
1081         }
1082
1083         free(out_data);
1084         free(in_buffer.buffer);
1085         curl_slist_free_all(dav_headers);
1086
1087         return lock_flags;
1088 }
1089
1090 static int is_ancestor(unsigned char *sha1, struct commit *commit)
1091 {
1092         struct commit_list *parents;
1093
1094         if (parse_commit(commit))
1095                 return 0;
1096         parents = commit->parents;
1097         for (; parents; parents = parents->next) {
1098                 if (!memcmp(sha1, parents->item->object.sha1, 20)) {
1099                         return 1;
1100                 } else if (parents->item->object.type == commit_type) {
1101                         if (is_ancestor(
1102                                     sha1,
1103                                     (struct commit *)&parents->item->object
1104                                     ))
1105                                 return 1;
1106                 }
1107         }
1108         return 0;
1109 }
1110
1111 static void get_delta(unsigned char *sha1, struct object *obj,
1112                       struct active_lock *lock)
1113 {
1114         struct commit *commit;
1115         struct commit_list *parents;
1116         struct tree *tree;
1117         struct tree_entry_list *entry;
1118
1119         if (sha1 && !memcmp(sha1, obj->sha1, 20))
1120                 return;
1121
1122         if (aborted)
1123                 return;
1124
1125         if (obj->type == commit_type) {
1126                 if (push_verbosely)
1127                         fprintf(stderr, "walk %s\n", sha1_to_hex(obj->sha1));
1128                 add_request(obj->sha1, lock);
1129                 commit = (struct commit *)obj;
1130                 if (parse_commit(commit)) {
1131                         fprintf(stderr, "Error parsing commit %s\n",
1132                                 sha1_to_hex(obj->sha1));
1133                         aborted = 1;
1134                         return;
1135                 }
1136                 parents = commit->parents;
1137                 for (; parents; parents = parents->next)
1138                         if (sha1 == NULL ||
1139                             memcmp(sha1, parents->item->object.sha1, 20))
1140                                 get_delta(sha1, &parents->item->object,
1141                                           lock);
1142                 get_delta(sha1, &commit->tree->object, lock);
1143         } else if (obj->type == tree_type) {
1144                 if (push_verbosely)
1145                         fprintf(stderr, "walk %s\n", sha1_to_hex(obj->sha1));
1146                 add_request(obj->sha1, lock);
1147                 tree = (struct tree *)obj;
1148                 if (parse_tree(tree)) {
1149                         fprintf(stderr, "Error parsing tree %s\n",
1150                                 sha1_to_hex(obj->sha1));
1151                         aborted = 1;
1152                         return;
1153                 }
1154                 entry = tree->entries;
1155                 tree->entries = NULL;
1156                 while (entry) {
1157                         struct tree_entry_list *next = entry->next;
1158                         get_delta(sha1, entry->item.any, lock);
1159                         free(entry->name);
1160                         free(entry);
1161                         entry = next;
1162                 }
1163         } else if (obj->type == blob_type || obj->type == tag_type) {
1164                 add_request(obj->sha1, lock);
1165         }
1166 }
1167
1168 static int update_remote(unsigned char *sha1, struct active_lock *lock)
1169 {
1170         struct active_request_slot *slot;
1171         char *out_data;
1172         char *if_header;
1173         struct buffer out_buffer;
1174         struct curl_slist *dav_headers = NULL;
1175         int i;
1176
1177         if_header = xmalloc(strlen(lock->token) + 25);
1178         sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token);
1179         dav_headers = curl_slist_append(dav_headers, if_header);
1180
1181         out_buffer.size = 41;
1182         out_data = xmalloc(out_buffer.size + 1);
1183         i = snprintf(out_data, out_buffer.size + 1, "%s\n", sha1_to_hex(sha1));
1184         if (i != out_buffer.size) {
1185                 fprintf(stderr, "Unable to initialize PUT request body\n");
1186                 return 0;
1187         }
1188         out_buffer.posn = 0;
1189         out_buffer.buffer = out_data;
1190
1191         slot = get_active_slot();
1192         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
1193         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
1194         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1195         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
1196         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);
1197         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1198         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1199         curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
1200         curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
1201
1202         if (start_active_slot(slot)) {
1203                 run_active_slot(slot);
1204                 free(out_data);
1205                 free(if_header);
1206                 if (slot->curl_result != CURLE_OK) {
1207                         fprintf(stderr,
1208                                 "PUT error: curl result=%d, HTTP code=%ld\n",
1209                                 slot->curl_result, slot->http_code);
1210                         /* We should attempt recovery? */
1211                         return 0;
1212                 }
1213         } else {
1214                 free(out_data);
1215                 free(if_header);
1216                 fprintf(stderr, "Unable to start PUT request\n");
1217                 return 0;
1218         }
1219
1220         return 1;
1221 }
1222
1223 int main(int argc, char **argv)
1224 {
1225         struct transfer_request *request;
1226         struct transfer_request *next_request;
1227         int nr_refspec = 0;
1228         char **refspec = NULL;
1229         int do_remote_update;
1230         int new_branch;
1231         int force_this;
1232         char *local_ref;
1233         unsigned char local_sha1[20];
1234         struct object *local_object = NULL;
1235         char *remote_ref = NULL;
1236         unsigned char remote_sha1[20];
1237         struct active_lock *remote_lock;
1238         char *remote_path = NULL;
1239         int rc = 0;
1240         int i;
1241
1242         setup_ident();
1243
1244         remote = xmalloc(sizeof(*remote));
1245         remote->url = NULL;
1246         remote->packs = NULL;
1247
1248         argv++;
1249         for (i = 1; i < argc; i++, argv++) {
1250                 char *arg = *argv;
1251
1252                 if (*arg == '-') {
1253                         if (!strcmp(arg, "--complete")) {
1254                                 push_all = 1;
1255                                 continue;
1256                         }
1257                         if (!strcmp(arg, "--force")) {
1258                                 force_all = 1;
1259                                 continue;
1260                         }
1261                         if (!strcmp(arg, "--verbose")) {
1262                                 push_verbosely = 1;
1263                                 continue;
1264                         }
1265                         usage(http_push_usage);
1266                 }
1267                 if (!remote->url) {
1268                         remote->url = arg;
1269                         continue;
1270                 }
1271                 refspec = argv;
1272                 nr_refspec = argc - i;
1273                 break;
1274         }
1275
1276         memset(remote_dir_exists, 0, 256);
1277
1278         http_init();
1279
1280         no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
1281         default_headers = curl_slist_append(default_headers, "Range:");
1282         default_headers = curl_slist_append(default_headers, "Destination:");
1283         default_headers = curl_slist_append(default_headers, "If:");
1284         default_headers = curl_slist_append(default_headers,
1285                                             "Pragma: no-cache");
1286
1287         /* Verify DAV compliance/lock support */
1288         if (!locking_available()) {
1289                 fprintf(stderr, "Error: no DAV locking support on remote repo %s\n", remote->url);
1290                 rc = 1;
1291                 goto cleanup;
1292         }
1293
1294         /* Process each refspec */
1295         for (i = 0; i < nr_refspec; i++) {
1296                 char *ep;
1297                 force_this = 0;
1298                 do_remote_update = 0;
1299                 new_branch = 0;
1300                 local_ref = refspec[i];
1301                 if (*local_ref == '+') {
1302                         force_this = 1;
1303                         local_ref++;
1304                 }
1305                 ep = strchr(local_ref, ':');
1306                 if (ep) {
1307                         remote_ref = ep + 1;
1308                         *ep = 0;
1309                 }
1310                 else
1311                         remote_ref = local_ref;
1312
1313                 /* Lock remote branch ref */
1314                 if (remote_path)
1315                         free(remote_path);
1316                 remote_path = xmalloc(strlen(remote_ref) + 12);
1317                 sprintf(remote_path, "refs/heads/%s", remote_ref);
1318                 remote_lock = lock_remote(remote_path, LOCK_TIME);
1319                 if (remote_lock == NULL) {
1320                         fprintf(stderr, "Unable to lock remote branch %s\n",
1321                                 remote_ref);
1322                         rc = 1;
1323                         continue;
1324                 }
1325
1326                 /* Resolve local and remote refs */
1327                 if (fetch_ref(remote_ref, remote_sha1) != 0) {
1328                         fprintf(stderr,
1329                                 "Remote branch %s does not exist on %s\n",
1330                                 remote_ref, remote->url);
1331                         new_branch = 1;
1332                 }
1333                 if (get_sha1(local_ref, local_sha1) != 0) {
1334                         fprintf(stderr, "Error resolving local branch %s\n",
1335                                 local_ref);
1336                         rc = 1;
1337                         goto unlock;
1338                 }
1339         
1340                 /* Find relationship between local and remote */
1341                 local_object = parse_object(local_sha1);
1342                 if (!local_object) {
1343                         fprintf(stderr, "Unable to parse local object %s\n",
1344                                 sha1_to_hex(local_sha1));
1345                         rc = 1;
1346                         goto unlock;
1347                 } else if (new_branch) {
1348                         do_remote_update = 1;
1349                 } else {
1350                         if (!memcmp(local_sha1, remote_sha1, 20)) {
1351                                 fprintf(stderr,
1352                                         "* %s: same as branch '%s' of %s\n",
1353                                         local_ref, remote_ref, remote->url);
1354                         } else if (is_ancestor(remote_sha1,
1355                                                (struct commit *)local_object)) {
1356                                 fprintf(stderr,
1357                                         "Remote %s will fast-forward to local %s\n",
1358                                         remote_ref, local_ref);
1359                                 do_remote_update = 1;
1360                         } else if (force_all || force_this) {
1361                                 fprintf(stderr,
1362                                         "* %s on %s does not fast forward to local branch '%s', overwriting\n",
1363                                         remote_ref, remote->url, local_ref);
1364                                 do_remote_update = 1;
1365                         } else {
1366                                 fprintf(stderr,
1367                                         "* %s on %s does not fast forward to local branch '%s'\n",
1368                                         remote_ref, remote->url, local_ref);
1369                                 rc = 1;
1370                                 goto unlock;
1371                         }
1372                 }
1373
1374                 /* Generate and check list of required objects */
1375                 pushing = 0;
1376                 if (do_remote_update || push_all)
1377                         fetch_indices();
1378                 get_delta(push_all ? NULL : remote_sha1,
1379                           local_object, remote_lock);
1380                 finish_all_active_slots();
1381
1382                 /* Push missing objects to remote, this would be a
1383                    convenient time to pack them first if appropriate. */
1384                 pushing = 1;
1385                 fill_active_slots();
1386                 finish_all_active_slots();
1387
1388                 /* Update the remote branch if all went well */
1389                 if (do_remote_update) {
1390                         if (!aborted && update_remote(local_sha1,
1391                                                       remote_lock)) {
1392                                 fprintf(stderr, "%s remote branch %s\n",
1393                                         new_branch ? "Created" : "Updated",
1394                                         remote_ref);
1395                         } else {
1396                                 fprintf(stderr,
1397                                         "Unable to %s remote branch %s\n",
1398                                         new_branch ? "create" : "update",
1399                                         remote_ref);
1400                                 rc = 1;
1401                                 goto unlock;
1402                         }
1403                 }
1404
1405         unlock:
1406                 unlock_remote(remote_lock);
1407                 free(remote_path);
1408         }
1409
1410  cleanup:
1411         free(remote);
1412
1413         curl_slist_free_all(no_pragma_header);
1414         curl_slist_free_all(default_headers);
1415
1416         http_cleanup();
1417
1418         request = request_queue_head;
1419         while (request != NULL) {
1420                 next_request = request->next;
1421                 release_request(request);
1422                 request = next_request;
1423         }
1424
1425         return rc;
1426 }